- Joined
- Nov 22, 2006
- Messages
- 1,260
Hello, I'm sorry this is one of those "can u pls look at my code" threads. This spell crashes when it's supposed to finish! Maybe related to lightnings, can u pls look at my code?
Sorry for lot of constants, I would do better if I could use vJass (I can't because of certain reasons)
Well anyways, +rep to the one who finds the problem (if you have some code optimization suggestions, feel free to tell me)
JASS:
constant function FireDrain_SpellId takes nothing returns integer
return 'A008'
endfunction
constant function FireDrain_FireOrbId takes nothing returns integer
return 'h007'
endfunction
constant function FireDrain_LightningId takes nothing returns string
return "DRAL"
endfunction
constant function FireDrain_FireOrbHeight takes nothing returns real
return 200.0
endfunction
constant function FireDrain_DrainHeight takes nothing returns real
return 50.0
endfunction
constant function FireDrain_TargetCount takes integer lev returns integer
return 1 + lev
endfunction
constant function FireDrain_Duration takes nothing returns real
return 15.0
endfunction
constant function FireDrain_AOE takes real lev returns real
return 450.0 + 50.0 * lev
endfunction
constant function FireDrain_LifeDrained takes real lev returns real
return 100.0 + 100 * lev
endfunction
constant function FireDrain_LightningEstablishInterval takes nothing returns real
return 0.5
endfunction
constant function FireDrain_DrainInterval takes nothing returns real
return 0.5
endfunction
constant function FireDrain_SFX takes nothing returns string
return "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
endfunction
//===========================================================================
function Trig_Fire_Drain_Conditions takes nothing returns boolean
return GetSpellAbilityId() == FireDrain_SpellId()
endfunction
function FireDrain_Drain takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit c = GetHandleUnit(t, "c")
local group g = GetHandleGroup(t, "g")
local real lev = I2R(GetHandleInt(t, "lev"))
local integer i = GetHandleInt(t, "i")
local integer q = R2I((FireDrain_Duration() + FireDrain_LightningEstablishInterval() * FireDrain_TargetCount(R2I(lev)))/FireDrain_DrainInterval())
local group g2 = CreateGroup()
local unit u
local unit b
local real x
local real y
call GroupAddGroup(g, g2)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
call GroupRemoveUnit(g2, u)
set x = GetUnitX(u)
set y = GetUnitY(u)
call DestroyEffect(AddSpecialEffect(FireDrain_SFX(), x, y))
call UnitDamageTarget(c, u, FireDrain_LifeDrained(lev)/I2R(q), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null)
endloop
if i >= q - 1 then
call FlushHandleLocals(t)
call DestroyTimer(t)
else
call SetHandleInt(t, "i", i + 1)
endif
call DestroyGroup(g2)
set t = null
set c = null
set g = null
set g2 = null
set b = null
endfunction
function FireDrain_SetLightnings takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit c = GetHandleUnit(t, "c")
local group g = GetHandleGroup(t, "g")
local group g2 = GetHandleGroup(t, "g2")
local integer lev = GetHandleInt(t, "lev")
local unit u = FirstOfGroup(g2)
local lightning l = GetHandleLightning(u, "l")
local integer i = GetHandleInt(t, "i")
call GroupRemoveUnit(g2, u)
if l != null then
call SetLightningColor(l, 1, 0, 0, 1)
endif
if i >= CountUnitsInGroup(g) - 1 then
call DestroyGroup(g2)
call PauseTimer(t)
call TimerStart(t, FireDrain_DrainInterval(), true, function FireDrain_Drain)
else
call SetHandleInt(t, "i", i + 1)
endif
set t = null
set c = null
set g = null
set g2 = null
set l = null
endfunction
function FireDrain_SetPositions takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit c = GetHandleUnit(t, "c")
local unit o = GetHandleUnit(t, "o")
local group g = GetHandleGroup(t, "g")
local integer lev = GetHandleInt(t, "lev")
local group g2 = CreateGroup()
local unit u
local integer i = GetHandleInt(t, "i")
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local location p
local lightning l
call SetUnitX(o, x)
call SetUnitY(o, y)
call GroupAddGroup(g, g2)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
call GroupRemoveUnit(g2, u)
set l = GetHandleLightning(u, "l")
if l != null then
call MoveLightningEx(l, true, x, y, FireDrain_FireOrbHeight() + FireDrain_DrainHeight(), GetUnitX(u), GetUnitY(u), FireDrain_DrainHeight())
endif
if (((x-GetUnitX(u))*(x-GetUnitX(u))+(y-GetUnitY(u))*(y-GetUnitY(u))) >= (FireDrain_AOE(I2R(lev)) + 100)*(FireDrain_AOE(I2R(lev)) + 100) and l != null) or (IsUnitType(u, UNIT_TYPE_DEAD) and l != null) then
call DestroyLightning(l)
call SetHandleHandle(u, "l", null)
call GroupRemoveUnit(g, u)
endif
endloop
if i * Frequency() >= FireDrain_Duration() + FireDrain_LightningEstablishInterval() * FireDrain_TargetCount(lev) then
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
call SetHandleHandle(u, "l", null)
endloop
call DestroyGroup(g)
set p = Location(x, y)
call RemoveUnit(o)
call DestroyEffect(AddSpecialEffectZ(FireDrain_SFX(), x, y, FireDrain_FireOrbHeight() - GetLocationZ(p)))
call RemoveLocation(p)
call FlushHandleLocals(t)
call DestroyTimer(t)
else
call SetHandleHandle(t, "g", g)
call SetHandleInt(t, "i", i + 1)
endif
call DestroyGroup(g2)
set t = null
set c = null
set o = null
set p = null
set l = null
set g = null
set g2 = null
endfunction
function Trig_Fire_Drain_Actions takes nothing returns nothing
local timer t1 = CreateTimer()
local timer t2 = CreateTimer()
local unit c = GetTriggerUnit()
local real lev = I2R(GetUnitAbilityLevel(c, FireDrain_SpellId()))
local real x = GetUnitX(c)
local real y = GetUnitY(c)
local unit o = CreateUnit(GetOwningPlayer(c), FireDrain_FireOrbId(), x, y, 0)
local location p = Location(x, y)
local real h = FireDrain_FireOrbHeight() - GetLocationZ(p)
local real r = FireDrain_FireOrbHeight()
local group g = CreateGroup()
local group g2 = CreateGroup()
local boolexpr b
local unit u
local integer i = 0
local integer j
local lightning l
call RemoveLocation(p)
call SetUnitFlyHeight(o, h, r)
set bj_ghoul[100] = c
set b = Condition(function TargCond)
call GroupEnumUnitsInRange(g, x, y, FireDrain_AOE(lev), b)
call GroupAddGroup(g, g2)
set j = CountUnitsInGroup(g)
if j >= FireDrain_TargetCount(R2I(lev)) then
set j = FireDrain_TargetCount(R2I(lev))
endif
call GroupClear(g)
loop
exitwhen i == j
set u = FirstOfGroup(g2)
call GroupRemoveUnit(g2, u)
call GroupAddUnit(g, u)
set l = AddLightningEx(FireDrain_LightningId(), true, x, y, FireDrain_FireOrbHeight() + FireDrain_DrainHeight(), GetUnitX(u), GetUnitY(u), FireDrain_DrainHeight())
call LightningApplyTimedLife(l, FireDrain_Duration() + FireDrain_LightningEstablishInterval() * FireDrain_TargetCount(R2I(lev)))
call SetLightningColor(l, 1, 0, 0, 0)
call SetHandleHandle(u, "l", l)
set i = i + 1
endloop
call SetHandleHandle(t1, "c", c)
call SetHandleHandle(t1, "o", o)
call SetHandleHandle(t1, "g", g)
call SetHandleInt(t1, "lev", R2I(lev))
call TimerStart(t1, Frequency(), true, function FireDrain_SetPositions)
call GroupAddGroup(g, g2)
call SetHandleHandle(t2, "c", c)
call SetHandleHandle(t2, "g", g)
call SetHandleHandle(t2, "g2", g2)
call SetHandleInt(t2, "lev", R2I(lev))
call TimerStart(t2, FireDrain_LightningEstablishInterval(), true, function FireDrain_SetLightnings)
call DestroyBoolExpr(b)
set t1 = null
set t2 = null
set c = null
set o = null
set p = null
set g = null
set g2 = null
set b = null
set l = null
endfunction
Sorry for lot of constants, I would do better if I could use vJass (I can't because of certain reasons)
Well anyways, +rep to the one who finds the problem (if you have some code optimization suggestions, feel free to tell me)
Last edited: