- Joined
- Aug 27, 2012
- Messages
- 362
Hi, this is my spell, firewall. Creates a wall of fire and stuff, like diablo 2 firewall. It requires TimerUtils. Sometimes it bugs, so I wonder if I did something wrong. I post here to ask
JASS:
scope Firewall initializer OnInit
globals
private constant string EFFECT_FIRE = "war3mapImported\\FireAura.mdx" //Path of the model for the fire
private constant string EFFECT_PERIODIC = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" //Path of the special effect that occurs interval.
private constant string EFFECT_BURN = "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl"//Path of the special effect you want attached to burning units
private constant integer DUMMY_ID = 'h007' //Raw code of dummy ability
private constant integer ABIL_ID = 'A042' //Raw code of ability, should be based off stampede due to the nature of the spell.
private constant real INTERVAL = 0.5 //How often main explosion damages enemies
private constant real MAIN_DMG = 200. //Damage per level from main explosion, per interval.
private constant real BURN_INTERVAL = .25 //How often the unit takes burn damage
private constant real BURN_DMG = 5. //Damage per tick of burn(per level)
//End of configurables
private constant group GROUP = CreateGroup()
private unit CASTER
endglobals
private struct FirewallMain
unit caster
real x1
real y1
real x2
real y2
real x3
real y3
real x4
real y4
real x5
real y5
real x6
real y6
real x7
real y7
effect sfx1
effect sfx2
effect sfx3
effect sfx4
effect sfx5
effect sfx6
effect sfx7
real duration
endstruct
private struct FirewallBurn
unit source
unit burning
effect burnsfx
real duration
endstruct
native UnitAlive takes unit id returns boolean
private function BurnHandler takes nothing returns nothing
local timer t = GetExpiredTimer()
local FirewallBurn data = GetTimerData(t)
if data.duration == 0.0 then
call DestroyEffect(data.burnsfx)
call data.destroy()
call ReleaseTimer(GetExpiredTimer())
else
call Damage_Spell(data.source,data.burning,I2R(GetUnitAbilityLevel(data.source,ABIL_ID))*BURN_DMG)
set data.duration = data.duration - .5
call SetTimerData(t,data)
call TimerStart(t,BURN_INTERVAL,false,function BurnHandler)
endif
set t = null
endfunction
private function FilterActions takes nothing returns boolean
local timer t
local FirewallBurn data = FirewallBurn.create()
if UnitAlive(GetFilterUnit()) and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(CASTER)) == true and OrderId2String(GetUnitCurrentOrder(CASTER)) == "stampede" then
set t = NewTimer()
set data.source = CASTER
set data.burning = GetFilterUnit()
set data.burnsfx = AddSpecialEffectTarget(EFFECT_BURN,data.burning,"chest")
set data.duration = 4.*I2R(GetUnitAbilityLevel(data.source,ABIL_ID))
call Damage_Spell(data.source,data.burning,I2R(GetUnitAbilityLevel(data.source,ABIL_ID))*MAIN_DMG)
call SetTimerData(t,data)
call TimerStart(t,BURN_INTERVAL,false,function BurnHandler)
else
call data.destroy()
endif
set t = null
return false
endfunction
private function Handler takes nothing returns nothing
local timer t = GetExpiredTimer()
local FirewallMain data = GetTimerData(t)
set CASTER = data.caster
if OrderId2String(GetUnitCurrentOrder(data.caster)) != "stampede" then
call ReleaseTimer(GetExpiredTimer())
call DestroyEffect(data.sfx1)
call DestroyEffect(data.sfx2)
call DestroyEffect(data.sfx3)
call DestroyEffect(data.sfx4)
call DestroyEffect(data.sfx5)
call DestroyEffect(data.sfx6)
call DestroyEffect(data.sfx7)
call data.destroy()
else
call GroupEnumUnitsInRange(GROUP,data.x1,data.y1,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x2,data.y2,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x3,data.y3,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x4,data.y4,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x5,data.y5,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x6,data.y6,174.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x7,data.y7,174.,Filter(function FilterActions))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x1,data.y1))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x2,data.y2))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x3,data.y3))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x4,data.y4))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x5,data.y5))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x6,data.y6))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x7,data.y7))
call SetTimerData(t,data)
call TimerStart(t,INTERVAL,false,function Handler)
endif
set t = null
endfunction
private function Actions takes nothing returns nothing
local real angle = GetUnitFacing(GetTriggerUnit())
local timer t = NewTimer()
local FirewallMain data = FirewallMain.create()
set data.caster = GetTriggerUnit()
set data.x1 = GetSpellTargetX()
set data.y1 = GetSpellTargetY()
set data.sfx1 = AddSpecialEffect(EFFECT_FIRE,data.x1,data.y1)
set data.x2 = data.x1 + 300. * Cos((angle + 90.)*bj_DEGTORAD)
set data.y2 = data.y1 + 300. * Sin((angle + 90.)*bj_DEGTORAD)
set data.sfx2 = AddSpecialEffect(EFFECT_FIRE,data.x2,data.y2)
set data.x3 = data.x1 + 600. * Cos((angle + 90.)*bj_DEGTORAD)
set data.y3 = data.y1 + 600. * Sin((angle + 90.)*bj_DEGTORAD)
set data.sfx3 = AddSpecialEffect(EFFECT_FIRE,data.x3,data.y3)
set data.x4 = data.x1 + 900. * Cos((angle + 90.)*bj_DEGTORAD)
set data.y4 = data.y1 + 900. * Sin((angle + 90.)*bj_DEGTORAD)
set data.sfx4 = AddSpecialEffect(EFFECT_FIRE,data.x4,data.y4)
set data.x5 = data.x1 + 300. * Cos((angle - 90.)*bj_DEGTORAD)
set data.y5 = data.y1 + 300. * Sin((angle - 90.)*bj_DEGTORAD)
set data.sfx5 = AddSpecialEffect(EFFECT_FIRE,data.x5,data.y5)
set data.x6 = data.x1 + 600. * Cos((angle - 90.)*bj_DEGTORAD)
set data.y6 = data.y1 + 600. * Sin((angle - 90.)*bj_DEGTORAD)
set data.sfx6 = AddSpecialEffect(EFFECT_FIRE,data.x6,data.y6)
set data.x7 = data.x1 + 900. * Cos((angle - 90.)*bj_DEGTORAD)
set data.y7 = data.y1 + 900. * Sin((angle - 90.)*bj_DEGTORAD)
set data.sfx7 = AddSpecialEffect(EFFECT_FIRE,data.x7,data.y7)
set CASTER = data.caster
call GroupEnumUnitsInRange(GROUP,data.x1,data.y1,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x2,data.y2,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x3,data.y3,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x4,data.y4,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x5,data.y5,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x6,data.y6,150.,Filter(function FilterActions))
call GroupEnumUnitsInRange(GROUP,data.x7,data.y7,150.,Filter(function FilterActions))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x1,data.y1))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x2,data.y2))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x3,data.y3))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x4,data.y4))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x5,data.y5))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x6,data.y6))
call DestroyEffect(AddSpecialEffect(EFFECT_PERIODIC,data.x7,data.y7))
call SetTimerData(t,data)
call TimerStart(t,INTERVAL,false,function Handler)
set t = null
endfunction
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == ABIL_ID then
call Actions()
endif
return false
endfunction
private function OnInit takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function Conditions))
endfunction
endscope