- Joined
- Sep 9, 2009
- Messages
- 658
So...I've got another question. I'm trying to convert some of my old GUI spells to JASS and I've come across this problem.
In a periodic trigger, I have shadow balls created at random locations around the target point of the ability. After 25 of them have been created, a big Shadow Ball would be created at the center of the target point. It should stay for around 1 second before being killed and damaging enemies in a large area. And herein lies the problem, how do I get it to stay for 1 second without using any kind of waits as they mess up the periodic trigger?
If it helps, I've attached the test map I'm using. It's pretty small in size so it's easy to download.
In a periodic trigger, I have shadow balls created at random locations around the target point of the ability. After 25 of them have been created, a big Shadow Ball would be created at the center of the target point. It should stay for around 1 second before being killed and damaging enemies in a large area. And herein lies the problem, how do I get it to stay for 1 second without using any kind of waits as they mess up the periodic trigger?
If it helps, I've attached the test map I'm using. It's pretty small in size so it's easy to download.
JASS:
function VW_periodic takes nothing returns nothing
//setting up the variables
local timer t = GetExpiredTimer()
local integer parentKey = GetHandleId(t)
local unit u = LoadUnitHandle(udg_Hash, parentKey, 0)
local rect r = LoadRectHandle(udg_Hash, parentKey, 1)//Loading the rect.
local integer count = LoadInteger(udg_Hash, parentKey, 2)
local real damage = LoadReal(udg_Hash, parentKey, 4)
local real x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
local real y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
local group g = CreateGroup()
local integer i = 0
local real angle = 0.174
local real px = LoadReal(udg_Hash, parentKey, 5)
local real py = LoadReal(udg_Hash, parentKey, 6)
local unit shadowball
local unit u1
local real dx
local real dy
local real px1
local real py1
//end of set up
set count = count + 1
call SaveInteger(udg_Hash, parentKey, 2, count)
set shadowball = CreateUnit(GetOwningPlayer(u), 'e001', x, y, 270)
//Can I do set shadowball = KillUnit(CreateUnit((GetOwningPlayer(u), 'e001', x, y, 270))
//and still be able to extract its X and Y coordinates?
call KillUnit(shadowball)
set dx = GetUnitX(shadowball)
set dy = GetUnitY(shadowball)
call DestroyEffect(AddSpecialEffect("DarkNova.mdx", dx, dy))
call GroupEnumUnitsInRange(g, dx, dy, 350, null)
loop
set u1 = FirstOfGroup(g)
exitwhen u1 == null
if IsUnitEnemy(u1, GetOwningPlayer(u)) then
call UnitDamageTarget(u, u1, damage, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
endif
call GroupRemoveUnit(g, u1)
endloop
if count >= 25 then
call PauseTimer(t)
set shadowball = CreateUnit(GetOwningPlayer(u), 'e002', px, py, 270)
call KillUnit(shadowball)
//This is where the problem is. I want the unit to stay alive for 1 second
//before being killing it. I can't use polledwait or triggersleep action because they
//mess up this trigger. I could use a countdown timer but is that the best option?
loop
exitwhen i == 36
set i = i + 1
set px1 = px + 300 * Cos(angle)
set py1 = py + 300 * Sin(angle)
call DestroyEffect(AddSpecialEffect("DarkPillar.mdx", px1, py1))
set px1 = px + 600 * Cos(angle)
set py1 = py + 600 * Sin(angle)
call DestroyEffect(AddSpecialEffect("DarkPillar.mdx", px1, py1))
set px1 = px + 900 * Cos(angle)
set py1 = py + 900 * Sin(angle)
call DestroyEffect(AddSpecialEffect("DarkPillar.mdx", px1, py1))
set angle = angle+0.174
endloop
//cleaning up the leaks
call DestroyTimer(t)
set u = null
set u1 = null
set shadowball = null
set g = null
call FlushChildHashtable(udg_Hash, parentKey)
endif
//cleaning up
set g = null
set u = null
set u1 = null
set t = null
set r = null //Can't do RemoveRect(r) because it messes up the spawn locations. This is fine, right?
call DestroyGroup(g)
endfunction
function Trig_Vanishing_World_Actions takes nothing returns nothing
//Declaring variables
local timer t = CreateTimer()
local unit u = GetTriggerUnit()
local location l = GetSpellTargetLoc()
local real x = GetLocationX(l)//I need this to get the coordinates so I can make my rect.
local real y = GetLocationY(l)//I need this to get the coordinates so I can make my rect.
local real px = GetLocationX(l)//I'm storing it again so I can get the target loc later on.
local real py = GetLocationY(l)//I'm storing it again so I can get the target loc later on.
local integer parentKey = GetHandleId(t)
local rect r = Rect(x-600,y-600,x+600,y+600)//the rect I want
local real final_damage = 1000 * GetHeroInt(u,true)
local real periodic_damage = (GetHeroInt(u,true) * 0.10) * 100
//End of declaration
//Setting up the hastable
call SaveUnitHandle(udg_Hash, parentKey, 0, u)//The triggering unit
call SaveRectHandle(udg_Hash, parentKey, 1, r)//I need to save the rect, right?
call SaveInteger(udg_Hash, parentKey, 2, 0)//Saving the count, so that it'll stop after 5 seconds.
call SaveReal(udg_Hash, parentKey, 3, final_damage)//I'm storing the damage so the spell will still deal damage even if the Hero dies.
call SaveReal(udg_Hash, parentKey, 4, periodic_damage)
call SaveReal(udg_Hash, parentKey, 5, px)//The coordinates of the target point
call SaveReal(udg_Hash, parentKey, 6, py)
//End of set up
call TimerStart(t,.20,true,function VW_periodic)
call RemoveLocation(l)//Removing the location
endfunction
function Trig_Vanishing_World_Conditions takes nothing returns boolean
if GetSpellAbilityId() == 'A000' then
call Trig_Vanishing_World_Actions()
endif
return false
endfunction
//===========================================================================
function InitTrig_Vanishing_World takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Trig_Vanishing_World_Conditions ) )
set t = null
set udg_Hash = InitHashtable()
endfunction