Дисклеймер!
Я полный нуб/лох/помойка в джассе (называйте как хотите), ничего толком не знаю и короче юзай способность на свой страх и риск. По возможности буду стараться оптимизировать это говно
Предложения по улучшению пишите в комменты
Я полный нуб/лох/помойка в джассе (называйте как хотите), ничего толком не знаю и короче юзай способность на свой страх и риск. По возможности буду стараться оптимизировать это говно
Предложения по улучшению пишите в комменты
Цель: точка или боевая единица
Тип: АОЕ урон
Суть: град стрел, но вы можете, конечно, свой снаряд поставить: метеориты, курицы, овцы, моя мать и т.д.
Подходит как для обычного юнита, так и для героя
Тип: АОЕ урон
Суть: град стрел, но вы можете, конечно, свой снаряд поставить: метеориты, курицы, овцы, моя мать и т.д.
Подходит как для обычного юнита, так и для героя
Текущие настройки:
- ID способности
- ID дамми-снаряда
- Базовый урон
- Доп. урон с уровнем
- Скейл урона от силы
- Скейл урона от ловкости
- Скейл урона от интеллекта
- вкл|выкл бонусы к характеристикам
- Радиус урона
- Доп. радиус с уровнем
- Кол-во волн
- Доп. кол-во волн с уровнем
- Интервал урона
- Отступ от середины точки применения способности
- Доп. радиус с уровнем
- волны стрел | по 1 стреле
- Количество стрел в волне
- Доп. кол-во стрел в волне с уровнем
- Интервал появления стрел
- Интервал спавна стрел
- Высота спавна стрел
- Скорость падения стрел
- Приземление стрелы
- Тип атаки
- Тип урона
- Тип оружия (звук)
- вкл|выкл эффекты при попадании
- Эффект при попадании
- Точка крепления эффекта
- Время удаления эффекта
Код
scope MySc
globals
private constant integer AbilityID = 'A000' // ID способности
private constant integer DummyID = 'u000' // ID дамми-снаряда
private constant real Damage = 5 // Базовый урон
private constant real DamageLvl = 5 // Доп. урон с уровнем
private constant real DamageScaleStr = 0.10 // Скейл урона от силы
private constant real DamageScaleAgi = 0.20 // Скейл урона от ловкости
private constant real DamageScaleInt = 0.00 // Скейл урона от интеллекта
private constant boolean IncludeBonuses = true // true|false - вкл|выкл бонусы к характеристикам
private constant real DamageRadius = 175 // Радиус урона
private constant real DamageRadiusLvl = 50 // Доп. радиус с уровнем
private constant integer DamageWaves = 3 // Кол-во волн
private constant integer DamageWavesLvl = 1 // Доп. кол-во волн с уровнем
private constant real DamageInterval = 1.00 // Интервал урона
private constant real RadiusThreshold = 25 // Отступ от середины точки применения способности
private constant real RadiusThresholdLvl = 25 // Доп. радиус с уровнем
//===
private constant boolean ArrowIntervalTF = true // true|false - волны стрел | по 1 стреле
//true
private constant integer ArrowsCount = 5 // Количество стрел в волне
private constant integer ArrowsCountLvl = 5 // Доп. кол-во стрел в волне с уровнем
private constant real ArrowsInterval = 0.50 // Интервал появления стрел
//false
private constant real ArrowInterval = 0.10 // Интервал спавна стрел
//===
private constant real ArrowHeight = 700 // Высота спавна стрел
private constant real ArrowSpeed = 1500 // Скорость падения стрел
private constant real ArrowGround = 0 // Приземление стрелы
private constant attacktype AttackType = ATTACK_TYPE_NORMAL // Тип атаки
private constant damagetype DamageType = DAMAGE_TYPE_NORMAL // Тип урона
private constant weapontype WeaponType = WEAPON_TYPE_WHOKNOWS // Тип оружия (звук)
private constant boolean ArrowEffectTF = true // true|false - вкл|выкл эффекты при попадании
private constant string ArrowEffect = "Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl" // Эффект при попадании
private constant string ArrowAttachPoint = "chest" // Точка крепления эффекта
private constant real ArrowEffectRemoveTime = 1.00 // Время удаления эффекта
private real TempReal = 0.
endglobals
//==========================================================================
private function IsUnitDead takes unit u returns boolean
return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction
private function filt takes nothing returns boolean // Тут ставим свои условия кому наносить урон, на данный момент: Юнит жив, Юнит враг применяющему юниту, Юнит не здание
set bj_lastReplacedUnit = GetFilterUnit()
return not IsUnitDead(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,bj_groupEnumOwningPlayer) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_STRUCTURE)
endfunction
private function remeff takes nothing returns nothing
local timer t = GetExpiredTimer()
call DestroyEffect(LoadEffectHandle(udg_Hash,GetHandleId(t),0))
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call DestroyTimer(t)
set t = null
endfunction
private function dmgf takes nothing returns nothing
local timer t = null
call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),TempReal,false,true,AttackType,DamageType,WeaponType)
if ArrowEffectTF == true then
set t = CreateTimer()
set bj_lastCreatedEffect = AddSpecialEffectTarget(ArrowEffect,GetEnumUnit(),ArrowAttachPoint)
call SaveEffectHandle(udg_Hash,GetHandleId(t),0,bj_lastCreatedEffect)
call TimerStart(t,ArrowEffectRemoveTime,false,function remeff)
set t = null
set bj_lastCreatedEffect = null
endif
endfunction
private function createunit takes real x, real y returns nothing
set bj_lastCreatedUnit = CreateUnit(bj_groupEnumOwningPlayer,DummyID,x,y,GetRandomReal(0,360))
call SetUnitFlyHeight(bj_lastCreatedUnit,ArrowHeight,0)
call SetUnitFlyHeight(bj_lastCreatedUnit,ArrowGround,ArrowSpeed)
call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',(ArrowHeight-ArrowGround)/ArrowSpeed)
set bj_lastCreatedUnit = null
endfunction
private function Arrow takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer i = GetHandleId(t)
local integer dmgw = LoadInteger(udg_Hash,i,7)
local integer dmgw1 = LoadInteger(udg_Hash,i,8)
local integer k = LoadInteger(udg_Hash,i,11)
local real x = LoadReal(udg_Hash,i,1)
local real y = LoadReal(udg_Hash,i,2)
local real DI = LoadReal(udg_Hash,i,3)+.01
local real AI = LoadReal(udg_Hash,i,4)+.01
local real r = LoadReal(udg_Hash,i,5)
local real a = GetRandomReal(0,360)
local real aa
local group g = null
if dmgw1 == dmgw then
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash,i)
else
set bj_groupEnumOwningPlayer = LoadPlayerHandle(udg_Hash,i,6)
if ArrowIntervalTF == false then
if AI >= ArrowInterval then
set TempReal = GetRandomReal(LoadReal(udg_Hash,i,9),r)
call createunit(x+TempReal*Cos(a*bj_DEGTORAD),y+TempReal*Sin(a*bj_DEGTORAD))
set AI = 0.
endif
elseif DI >= DamageInterval-ArrowsInterval and k == 0 then
set aa = LoadReal(udg_Hash,i,9)
set bj_forLoopAIndex = 0
set bj_forLoopAIndexEnd = LoadInteger(udg_Hash,i,10)
set k = 1
loop
exitwhen bj_forLoopAIndex == bj_forLoopAIndexEnd
set bj_forLoopAIndex = bj_forLoopAIndex+1
set TempReal = GetRandomReal(aa,r)
call createunit(x+TempReal*Cos(a*bj_DEGTORAD),y+TempReal*Sin(a*bj_DEGTORAD))
set a = GetRandomReal(0,360)
endloop
endif
if DI >= DamageInterval then
set g = CreateGroup()
set TempReal = LoadReal(udg_Hash,i,0)
set bj_lastCreatedUnit = CreateUnit(bj_groupEnumOwningPlayer,DummyID,x,y,0)
call GroupEnumUnitsInRange(g,x,y,r,Condition(function filt))
call ForGroup(g,function dmgf)
call GroupClear(g)
call DestroyGroup(g)
call RemoveUnit(bj_lastCreatedUnit)
set g = null
set bj_lastCreatedUnit = null
set DI = 0.
set k = 0
call SaveInteger(udg_Hash,i,8,dmgw1+1)
endif
call SaveReal(udg_Hash,i,3,DI)
call SaveReal(udg_Hash,i,4,AI)
call SaveInteger(udg_Hash,i,11,k)
set bj_groupEnumOwningPlayer = null
endif
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit u = GetSpellAbilityUnit()
local timer t = CreateTimer()
local integer i = GetHandleId(t)
local integer lvl = GetUnitAbilityLevel(u,AbilityID)
call SaveReal(udg_Hash,i,0,Damage+(lvl*DamageLvl)+(GetHeroStr(u,IncludeBonuses)*DamageScaleStr)+(GetHeroAgi(u,IncludeBonuses)*DamageScaleAgi)+(GetHeroInt(u,IncludeBonuses)*DamageScaleInt))
call SaveReal(udg_Hash,i,1,GetSpellTargetX())
call SaveReal(udg_Hash,i,2,GetSpellTargetY())
call SaveReal(udg_Hash,i,3,0.)
call SaveReal(udg_Hash,i,4,0.)
call SaveReal(udg_Hash,i,5,DamageRadius+(lvl*DamageRadiusLvl))
call SaveReal(udg_Hash,i,9,RadiusThreshold+(lvl*RadiusThresholdLvl))
call SavePlayerHandle(udg_Hash,i,6,GetOwningPlayer(u))
call SaveInteger(udg_Hash,i,7,DamageWaves+(lvl*DamageWavesLvl))
call SaveInteger(udg_Hash,i,8,0)
call SaveInteger(udg_Hash,i,10,ArrowsCount+(ArrowsCountLvl*lvl))
call TimerStart(t,.01,true,function Arrow)
set u = null
set t = null
endfunction
//===========================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == AbilityID
endfunction
function InitTrig_Phoenix takes nothing returns nothing // Phoenix переименовать на название твоего триггера
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set t = null
endfunction
endscope
В планах доработать, чтобы стрелы не могли спавнится за границей карты (если какой-то дурачок решит юзануть туда спелл и крашнуть всем игру)
Upd: Я в курсе что у некоторых могла возникнуть ошибка отсутствия функции в базе данных из-за кастом гуи, я конвертировал текст в код и теперь всё должно быть нормально, прошу прощения
Если при запуске карты через редактор тебя выбивает в главное меню, то просто нажми Ctrl+S в редакторе, если возникнет ошибка, пожалуйста, сделай скрин и пришли мне, если ошибки не будет, то после этого карта должна запустится