- Joined
- Apr 2, 2006
- Messages
- 32
Having issues with a spell.
It basically enables the caster to control the target unit (merely) for a limited duration after which the target is killed by the spell. The caster is given an additional ability to control the target which just orders it to simply move to the chosen point.
This all works fine.
However, sometimes the CASTER is killed once the target's "time" is up.
I'm posting here because I don't have any clue as to why this is happening.
I can't see the flaw in the code.
This only seems to take place when I cast the spell on one of the turtle creeps in the map below.
If anyone would like to help me fix this bug, just take a look at the attachment and cast the spell as much as you can until it kills the caster so you get the full picture of what I am trying to say.
After you do that, read the code and see if you can find the problem, because it has me stuck.
Thanks in advance.
It basically enables the caster to control the target unit (merely) for a limited duration after which the target is killed by the spell. The caster is given an additional ability to control the target which just orders it to simply move to the chosen point.
This all works fine.
However, sometimes the CASTER is killed once the target's "time" is up.
I'm posting here because I don't have any clue as to why this is happening.
I can't see the flaw in the code.
This only seems to take place when I cast the spell on one of the turtle creeps in the map below.
If anyone would like to help me fix this bug, just take a look at the attachment and cast the spell as much as you can until it kills the caster so you get the full picture of what I am trying to say.
After you do that, read the code and see if you can find the problem, because it has me stuck.
Thanks in advance.
JASS:
scope SoulCripple
globals
private constant integer SC_Ability_ID = 'A000' //Raw code of the "Soul Cripple" ability
private constant integer SC_Sub_Ability_ID = 'A001' //Raw code of the "Issue Order" ability
private constant string SC_Effect_Path = "Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl" //Exploding-guts effect
private constant string SC_Effect_Path2 = "Abilities\\Spells\\Undead\\Cripple\\CrippleTarget.mdl" //Crippled effect
private constant string SC_Effect_Path3 = "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl" //Supernova effect
private constant integer SC_Supernova_Arc_Count = 6 //Number of arcs/arms/legs/limbs supernova effect contains
private constant real SC_Supernova_Angle_Size = 9.5 //Harshness of an arc angle; increase to raise harshness
private constant real SC_Supernova_Size = 35 //Size of supernova; increase to enlarge size
private constant real SC_Supernova_Speed = 0.1 //Speed of supernova; decrease to increase speed <<<--- read that again
private constant real SC_Supernova_Time = 0.9 //Time supernova lasts (in seconds)
endglobals
private constant function Cripple_Duration takes real lvl returns real
return 40 - (lvl * 10) //Duration of Soul Cripple
endfunction
private struct Data
unit u = GetTriggerUnit()
unit t = GetSpellTargetUnit()
effect e = AddSpecialEffectTarget(SC_Effect_Path2, .t, "chest")
trigger T = CreateTrigger()
triggeraction ta
real X
real Y
real array ang[50]
real dist = 0
real count = 0
boolean b = false
endstruct
private function Supernova takes nothing returns nothing
local timer t = GetExpiredTimer()
local Data d = Data(GetHandleInt(t, "d"))
local integer i = 1
local integer i2 = SC_Supernova_Arc_Count
local real PX
local real PY
set d.count = d.count + SC_Supernova_Speed
set d.dist = d.dist + SC_Supernova_Size
if d.count <= SC_Supernova_Time then
loop
exitwhen i > i2
set PX = d.X + d.dist * Cos(d.ang[i] * bj_DEGTORAD)
set PY = d.Y + d.dist * Sin(d.ang[i] * bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(SC_Effect_Path3, PX, PY))
set d.ang[i] = d.ang[i] + SC_Supernova_Angle_Size
set i = i + 1
endloop
else
call d.destroy()
call FlushHandleLocals(t)
call PauseTimer(t)
call DestroyTimer(t)
endif
set t = null
endfunction
private function End takes nothing returns nothing
local timer t = GetExpiredTimer()
local Data d = Data(GetHandleInt(t, "d"))
local integer i = 1
local integer i2 = SC_Supernova_Arc_Count
local timer t2
call UnitRemoveAbility(d.u, SC_Sub_Ability_ID)
call TriggerRemoveAction(d.T, d.ta)
call FlushHandleLocals(d.T)
call DestroyTrigger(d.T)
call FlushHandleLocals(t)
call PauseTimer(t)
call DestroyTimer(t)
if GetWidgetLife(d.t) > 0.405 then
set t2 = CreateTimer()
loop
exitwhen i > i2
set d.ang[i] = 360/i2 * i
set i = i + 1
endloop
set d.X = GetUnitX(d.t)
set d.Y = GetUnitY(d.t)
call DestroyEffect(d.e)
call DestroyEffect(AddSpecialEffect(SC_Effect_Path, d.X, d.Y))
call UnitDamageTarget(d.u, d.t, 999999, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
call SetHandleInt(t2, "d", d)
call TimerStart(t2, SC_Supernova_Speed, true, function Supernova)
set t2 = null
else
call d.destroy()
endif
set t = null
endfunction
private function Cast_Sub takes nothing returns nothing
local trigger T = GetTriggeringTrigger()
local Data d = Data(GetHandleInt(T, "d"))
local location l = GetSpellTargetLoc()
if GetSpellAbilityId() == SC_Sub_Ability_ID then
call IssuePointOrderLoc(d.t, "move", l)
endif
call RemoveLocation(l)
set l = null
set T = null
endfunction
private function Cast_Main takes nothing returns nothing
local Data d = Data.create()
local timer t = CreateTimer()
set d.ta = TriggerAddAction(d.T, function Cast_Sub)
call TriggerRegisterPlayerUnitEvent(d.T, GetOwningPlayer(d.u), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call UnitAddAbility(d.u, SC_Sub_Ability_ID)
call SetHandleInt(t, "d", d)
call SetHandleInt(d.T, "d", d)
call TimerStart(t, Cripple_Duration(GetUnitAbilityLevel(d.u, SC_Ability_ID)), false, function End)
set t = null
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SC_Ability_ID
endfunction
function InitTrig_Soul_Cripple takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Cast_Main)
set t = null
endfunction
endscope