- Joined
- Nov 25, 2008
- Messages
- 1,309
JASS:
function AddCorpseData takes integer Spn,integer RoS,integer max,integer Cid,real Rad returns nothing
// Takes a unit type (Spn) and adds the given spawner data about it; Seconds to spawn a corpse (RoS), maximum corpses (max), the unit type of the corpse (Cid), and how far away the corpses are spawned (Rad).
call SaveInteger(udg_CorpseTable,Spn,0,RoS)
call SaveInteger(udg_CorpseTable,Spn,1,max)
call SaveInteger(udg_CorpseTable,Spn,2,Cid)
call SaveReal(udg_CorpseTable,Spn,3,Rad)
call SaveReal(udg_CorpseTable,Spn,4,360.0/I2R(max))
endfunction
function AddCorpseCost takes integer Bld,integer num returns nothing
// Takes a unit type (Bld) adds a corpse cost (num) to it.
call SaveInteger(udg_CorpseTable,Bld,10,num)
endfunction
function AddCorpseSpawner takes unit Spn returns nothing
// Takes a unit (Spn) and turns it into a corpse spawner, provided spawner data exists for its unit type.
local integer hid=GetHandleId(Spn)
local integer uid=GetUnitTypeId(Spn)
if LoadInteger(udg_CorpseTable,uid,1)>0then
call SaveGroupHandle(udg_CorpseTable,hid,0,CreateGroup())
call SaveInteger(udg_CorpseTable,hid,1,0)
call SaveInteger(udg_CorpseTable,hid,2,LoadInteger(udg_CorpseTable,uid,0))
call GroupAddUnit(udg_Corpses,Spn)
endif
endfunction
function NewCorpse takes unit Spn returns nothing
// Takes a corpse spawner (Spn) and creates another corpse for it, provided it doesn't go over the maximum number of corpses. Resets the time to spawn a new corpse.
local integer uid=GetUnitTypeId(Spn)
local integer hid=GetHandleId(Spn)
local player own=GetOwningPlayer(Spn)
local unit cps=null // Possible corpse to be made.
local integer num=LoadInteger(udg_CorpseTable,hid,1)
local real ang=R2I(num)*LoadReal(udg_CorpseTable,uid,4)*bj_DEGTORAD
local real rad=LoadReal(udg_CorpseTable,uid,3)
if num<LoadInteger(udg_CorpseTable,uid,1)then
// Make a new corpse!
set cps=CreateCorpse(own,LoadInteger(udg_CorpseTable,uid,2),GetWidgetX(Spn)+rad*Cos(ang),GetWidgetY(Spn)+rad*Sin(ang),ang*bj_RADTODEG)
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl",cps,"origin"))
call GroupAddUnit(LoadGroupHandle(udg_CorpseTable,hid,0),cps)
call SaveInteger(udg_CorpseTable,hid,1,num+1)
call SaveInteger(udg_CorpseTable,hid,2,LoadInteger(udg_CorpseTable,uid,0))
// Make corpse permanent.
call SetUnitBlendTime(cps,0)
call SetUnitAnimation(cps,"decay bone")
call UnitSuspendDecay(cps,true)
set cps=null
endif
set own=null
endfunction
function CorpseCount takes player P returns integer
// Loops over all corpse spawners owned by the given player (P) and returns the number of corpses he or she owns.
local unit Spn=null
local integer Num=0
local group G=CreateGroup()
local player Own=null
call GroupAddGroup(udg_Corpses,G)
loop
set Spn=FirstOfGroup(G)
exitwhen Spn==null
call GroupRemoveUnit(G,Spn)
set Own=GetOwningPlayer(Spn)
if Own==P then
set Num=Num+LoadInteger(udg_CorpseTable,GetHandleId(Spn),1)
endif
set Own=null
set Spn=null
endloop
call DestroyGroup(G)
set G=null
return Num
endfunction
function RemoveCorpseSpawner takes unit Spn returns nothing
// Takes a corpse spawner (Spn) and removes all corpse spawner handling from it; clearing it's data entry and corpses.
local integer hid=GetHandleId(Spn)
local integer uid=GetUnitTypeId(Spn)
local group G=LoadGroupHandle(udg_CorpseTable,hid,0)
local unit cps=null
loop
set cps=FirstOfGroup(G)
exitwhen cps==null
call GroupRemoveUnit(G,cps)
call SetUnitBlendTime(cps,.15)
call UnitSuspendDecay(cps,false)
set cps=null
endloop
call GroupRemoveUnit(udg_Corpses,Spn)
call DestroyGroup(G)
set G=null
call SaveGroupHandle(udg_CorpseTable,hid,0,null)
call FlushChildHashtable(udg_CorpseTable,hid)
endfunction
function SpendCorpse takes integer amt,player P returns boolean
// Spends a number of corpses (amt) for player (P), and returns true if there was enough corpses, or false if not enough. Spent corpses (if returns true) are removed from their spawners.
local group G=null
local group Spn=null
local unit spn=null
local unit cps=null
local player Own=null
local integer hid
if amt>CorpseCount(P)then
return false
elseif amt<1then
return true
endif
set G=CreateGroup()
call GroupAddGroup(udg_Corpses,G)
loop
set spn=FirstOfGroup(G)
exitwhen spn==null
call GroupRemoveUnit(G,spn)
set Own=GetOwningPlayer(spn)
if Own==P then
set hid=GetHandleId(spn)
set Spn=LoadGroupHandle(udg_CorpseTable,hid,0)
loop
set cps=FirstOfGroup(Spn)
exitwhen cps==null or amt==0
call GroupRemoveUnit(Spn,cps)
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl",GetWidgetX(cps),GetWidgetY(cps)))
call RemoveUnit(cps)
call SaveInteger(udg_CorpseTable,hid,1,LoadInteger(udg_CorpseTable,hid,1)-1)
set cps=null
set amt=amt-1
endloop
set Spn=null
endif
set Own=null
set spn=null
endloop
call DestroyGroup(G)
set G=null
return true
endfunction
function CorpseTick takes nothing returns nothing
// Loops over all corpse spawners and checks to see if they to be removed (because they died), or checks if they are due to spawn a corpse.
local group G=CreateGroup()
local unit Spn=null
local integer I
local boolean Run=false
call GroupAddGroup(udg_Corpses,G)
loop
set Spn=FirstOfGroup(G)
exitwhen Spn==null
set Run=true
call GroupRemoveUnit(G,Spn)
if GetWidgetLife(Spn)<.405then
call RemoveCorpseSpawner(Spn)
else
set I=LoadInteger(udg_CorpseTable,GetHandleId(Spn),2)-1
if I<=0 then
call NewCorpse(Spn)
else
call SaveInteger(udg_CorpseTable,GetHandleId(Spn),2,I)
endif
endif
set Spn=null
endloop
call DestroyGroup(G)
set G=null
endfunction
function InitTrig_Corpses takes nothing returns nothing
set gg_trg_Corpses=CreateTrigger()
call TriggerRegisterTimerExpireEvent(gg_trg_Corpses,udg_CorpseTimer)
call TriggerAddCondition(gg_trg_Corpses,Condition(function CorpseTick))
call TimerStart(udg_CorpseTimer,1,true,null)
set udg_CorpseTable=InitHashtable()
call AddCorpseData('h000',1,3,'hpea',128)
call AddCorpseData('h001',1,5,'hpea',128)
call AddCorpseData('h002',1,7,'hpea',128)
call AddCorpseCost('h001',2)
call AddCorpseCost('h002',3)
endfunction
So the issue is, given this code, that my corpses don't decay properly when the spawner is destroyed, or the corpses of a spawner sometimes decay?
Any insight appreciated.