I began to study "struct" and the methods of execution. I tried to create spells, but it works partially, I mean that only part of the code is executed. The essence is that a caster shoots an arrow, when hit by an enemy, damage is caused depending on the distance between them, after the damage is inflicted, the enemy begins several times. The trigger only works before the damage is inflicted. That is, a text is created with damage caused and everything, even the text is not destroyed but just flies up. I do not ask you to judge too much, since I suspect there are many mistakes in it, but still I ask you to tell me where the error is and why the trigger is not being executed. Thank you in advance.
JASS:
library BashArrow
globals
private constant integer SPELL_ID = 'A02L'
private constant integer DUMMY_SPELL = 'A03S'
private constant integer BUFF_ID = 'B014'
private constant integer DUMMY = 'u001'
endglobals
function BACon takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
struct BashArrow
unit caster
unit target
integer lvl
location loc
location loc1
static method create takes unit u, unit s, integer l, location f1, location f2 returns BashArrow
local BashArrow this = BashArrow.allocate()
set this.caster = u
set this.target = s
set this.lvl = l
set this.loc = f1
set this.loc1 = f2
return this
endmethod
method destroy takes nothing returns nothing
call this.deallocate()
endmethod
method onDestroy takes nothing returns nothing
set caster = null
set target = null
set lvl = 0
call RemoveLocation(loc)
call RemoveLocation(loc1)
set loc = null
set loc1 = null
endmethod
method BaSt takes nothing returns nothing
local unit d
local integer i
local texttag lct
local real distdmg
if GetUnitAbilityLevel(this.target, BUFF_ID) > 0 and GetUnitState(this.target, UNIT_STATE_LIFE)>0 then
call PauseTimer(GetExpiredTimer())
set distdmg = DistanceBetweenPoints(this.loc, this.loc1)*(.10*this.lvl)
set lct = CreateTextTagUnit(I2S(R2I(distdmg)), this.target, 0, 50, 70)
call UnitDamageTarget(this.caster, this.target, distdmg, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_MAGIC, null)
set d = CreateUnit(GetOwningPlayer(this.caster), DUMMY, GetUnitX(this.target), GetUnitY(this.target), 270)
call UnitAddAbility(d, DUMMY_SPELL)
call SetUnitAbilityLevel(d, DUMMY_SPELL, this.lvl)
call UnitApplyTimedLife(d, 'BTLF', 1)
call SetUnitPathing(d, false)
call ShowUnit(d, false)
call IssueTargetOrder(d, "thunderbolt", this.target)
set d = null
call PolledWait(1)
call DestroyTextTag(lct)
call PolledWait(1)
if this.lvl > 1 then
set d = CreateUnit(GetOwningPlayer(this.caster), DUMMY, GetUnitX(this.target), GetUnitY(this.target), 270)
call UnitAddAbility(d, DUMMY_SPELL)
call SetUnitAbilityLevel(d, DUMMY_SPELL, this.lvl)
call UnitApplyTimedLife(d, 'BTLF', 1)
call SetUnitPathing(d, false)
call ShowUnit(d, false)
call IssueTargetOrder(d, "thunderbolt", this.target)
set d = null
call PolledWait(2)
endif
if this.lvl > 3 then
set d = CreateUnit(GetOwningPlayer(this.caster), DUMMY, GetUnitX(this.target), GetUnitY(this.target), 270)
call UnitAddAbility(d, DUMMY_SPELL)
call SetUnitAbilityLevel(d, DUMMY_SPELL, this.lvl)
call UnitApplyTimedLife(d, 'BTLF', 1)
call SetUnitPathing(d, false)
call ShowUnit(d, false)
call IssueTargetOrder(d, "thunderbolt", this.target)
set d = null
call PolledWait(2)
endif
call this.destroy()
call SX(GetHandleId(GetExpiredTimer()))
call DestroyTimer(GetExpiredTimer())
set distdmg = 0
set lct = null
set d = null
elseif GetUnitState(this.target, UNIT_STATE_LIFE)<=0 then
call PauseTimer(GetExpiredTimer())
call this.destroy()
call SX(GetHandleId(GetExpiredTimer()))
call DestroyTimer(GetExpiredTimer())
endif
endmethod
endstruct
function BALoop takes nothing returns nothing
local BashArrow data = GetInt(GetExpiredTimer(), "BaSt")
call data.BaSt()
endfunction
function BAMain takes nothing returns nothing
local timer t = CreateTimer()
local unit u = GetSpellAbilityUnit()
local unit s = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u, SPELL_ID)
local location loc = GetUnitLoc(u)
local location loc1 = GetUnitLoc(s)
local BashArrow data = BashArrow.create(u, s, lvl, loc, loc1)
call SaveInt(t, "BaSt", data)
call TimerStart(t, 0.00001, true, function BALoop)
set loc = null
set loc1 = null
set t = null
set u = null
set lvl = 0
endfunction
function StartTrig_Bash_Arrow takes nothing returns nothing
set gg_trg_Bash_Arrow = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_Bash_Arrow, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_Bash_Arrow, Condition(function BACon))
call TriggerAddAction(gg_trg_Bash_Arrow, function BAMain)
call SpellPreload(DUMMY_SPELL)
endfunction
endlibrary