- Joined
- Apr 2, 2006
- Messages
- 32
Having a slight problem with a spell I've created with NewGen here.
It's meant to send the target unit flying backwards.
When it comes to a stop, a bunch of units are grouped within a small radius of that unit,
and are then knocked back in the 'Knockback_Aftershock' function.
All of that works, apart from the last part - the grouped-units aren't knocked back.
All I am able to tell from what is happening here, is that the grouped-units
are moved just once, and then the spell comes to a halt.
I've tried debugging in that non-working function, and it reads 0 for both groups.
Strange though, because when I try debugging in the previous function,
it reads above 0 (if there are units in the group).
So you should've been able to pick up what I'm trying to do here.
I'm using the simple "Loop & exitwhen unit of group = null" method,
with the extra duplicate group adding all removed units back into the one
thats had units removed from it inside the loop.
I've got no idea how to fix this.
Is there any other sort of method I can use that enables me to have access
to a struct's members when looping through a unit group?
It's meant to send the target unit flying backwards.
When it comes to a stop, a bunch of units are grouped within a small radius of that unit,
and are then knocked back in the 'Knockback_Aftershock' function.
All of that works, apart from the last part - the grouped-units aren't knocked back.
All I am able to tell from what is happening here, is that the grouped-units
are moved just once, and then the spell comes to a halt.
I've tried debugging in that non-working function, and it reads 0 for both groups.
Strange though, because when I try debugging in the previous function,
it reads above 0 (if there are units in the group).
So you should've been able to pick up what I'm trying to do here.
I'm using the simple "Loop & exitwhen unit of group = null" method,
with the extra duplicate group adding all removed units back into the one
thats had units removed from it inside the loop.
I've got no idea how to fix this.
Is there any other sort of method I can use that enables me to have access
to a struct's members when looping through a unit group?
JASS:
scope Knockback
globals
//Knockback effects config
private constant integer ID = 'AOcl'
private constant real damage = 4
private constant real tdelay = 0.03
private constant real brake = 0.975
private constant real maxdist = 700
private constant real power = 25
private constant string SFX = "Abilities\\Spells\\Undead\\Impale\\ImpaleHitTarget.mdl"
private constant string SFX2 = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
//Knockback after-shock config
private constant real damage2 = 325
private constant real brake2 = 0.9
private constant real maxdist2 = 445
private constant real AoE = 300
private constant real power2 = 10
private constant string SFX3 = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
endglobals
struct Knockback_Data
unit u
unit T
real ang = 0
real mxd = maxdist
real pwr = power
endstruct
struct Knockback_Aftershock_Data
group g
group g2
real mxd2 = 0
real pwr2 = 0
real OX = 0
real OY = 0
endstruct
function Knockback_Filter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction
function Knockback_Aftershock takes nothing returns nothing
local timer tt = GetExpiredTimer()
local Knockback_Aftershock_Data d2 = Knockback_Aftershock_Data(GetHandleInt(tt, "d2"))
local group g = d2.g
local group g2 = d2.g2
local real mxd2 = d2.mxd2
local real pwr2 = d2.pwr2
local real OX = d2.OX
local real OY = d2.OY
local unit p
call BJDebugMsg(I2S(CountUnitsInGroup(d2.g)))
call BJDebugMsg(I2S(CountUnitsInGroup(d2.g2)))
if mxd2 > 0 then
loop
set p = FirstOfGroup(g)
exitwhen p == null
call GroupRemoveUnit(g, p)
call SetUnitPosition(p, GetUnitX(p) + pwr2 * Cos(Atan2(GetUnitY(p)-OY, GetUnitX(p)-OX)), GetUnitY(p) + pwr2 * Sin(Atan2(GetUnitY(p)-OY, GetUnitX(p)-OX)))
call DestroyEffect(AddSpecialEffect(SFX2, GetUnitX(p), GetUnitY(p)))
endloop
call GroupAddGroup(g2, d2.g)
set d2.pwr2 = d2.pwr2 * brake2
set d2.mxd2 = d2.mxd2 - d2.pwr2
else
call d2.destroy()
call PauseTimer(tt)
call FlushHandleLocals(tt)
call DestroyTimer(tt)
endif
set tt = null
set g = null
set g2 = null
endfunction
function Knockback_Effects takes nothing returns nothing
local timer t = GetExpiredTimer()
local Knockback_Data d = Knockback_Data(GetHandleInt(t, "d"))
local unit u = d.u
local unit T = d.T
local real ang = d.ang
local real mxd = d.mxd
local real pwr = d.pwr
local real polarX = GetUnitX(T) + pwr * Cos(ang)
local real polarY = GetUnitY(T) + pwr * Sin(ang)
local Knockback_Aftershock_Data d2
local group g
local boolexpr b
local timer tt
if mxd > 0 then
call SetUnitPosition(T, polarX, polarY)
call DestroyEffect(AddSpecialEffect(SFX, polarX, polarY))
call DestroyEffect(AddSpecialEffect(SFX2, polarX, polarY))
call UnitDamageTarget(u, T, damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
set d.pwr = d.pwr * brake
set d.mxd = d.mxd - d.pwr
else
set g = CreateGroup()
set b = Condition(function Knockback_Filter)
set d2 = Knockback_Aftershock_Data.create()
set tt = CreateTimer()
call GroupEnumUnitsInRange(g, GetUnitX(T), GetUnitY(T), AoE, b)
set d2.g = g
set d2.g2 = g
set d2.mxd2 = maxdist2
set d2.pwr2 = power2
set d2.OX = GetUnitX(T)
set d2.OY = GetUnitY(T)
call SetHandleInt(tt, "d2", d2)
call TimerStart(tt, tdelay, true, function Knockback_Aftershock)
call DestroyEffect(AddSpecialEffect(SFX3, GetUnitX(T), GetUnitY(T)))
call DestroyBoolExpr(b)
set g = null
set b = null
set tt = null
call PauseUnit(T, false)
call d.destroy()
call PauseTimer(t)
call FlushHandleLocals(t)
call DestroyTimer(t)
endif
set t = null
set u = null
set T = null
endfunction
function Knockback_Actions takes nothing returns nothing
local Knockback_Data d = Knockback_Data.create()
local unit u = GetTriggerUnit()
local unit T = GetSpellTargetUnit()
local real X1 = GetUnitX(u)
local real Y1 = GetUnitY(u)
local real X2 = GetUnitX(T)
local real Y2 = GetUnitY(T)
local real ang = Atan2(Y2-Y1, X2-X1)
local timer t = CreateTimer()
call PauseUnit(T, true)
set d.u = u
set d.T = T
set d.ang = ang
call SetHandleInt(t, "d", d)
call TimerStart(t, tdelay, true, function Knockback_Effects)
set u = null
set T = null
endfunction
function Knockback_Conditions takes nothing returns boolean
return GetSpellAbilityId() == ID
endfunction
function InitTrig_Knockback_Copy takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Knockback_Conditions ) )
call TriggerAddAction( t, function Knockback_Actions )
set t = null
endfunction
endscope