| 10-22-2008, 12:56 AM | #1 |
Hello, I was creating a missile system to use it in a spell that is like the spirits of the Diablo's Necromancer (with some differences). The spell launch a Phantom that seek the target or seek a target. When the target is damaged get a buff. All the ghosts that are created later seek the target with the buff. All works fine, but i have a leak in some part, since whenever cast the spell the leaks are accumulated and accumulated. There are my n00b system JASS:library Misiles needs HSAS globals private integer array Doodad_ID endglobals public function Setea takes nothing returns nothing //Set the trees valid to destroy. set Doodad_ID[1]='ATtr' set Doodad_ID[2]='BTtw' set Doodad_ID[3]='KTtw' set Doodad_ID[4]='YTft' set Doodad_ID[5]='JTct' set Doodad_ID[6]='YTst' set Doodad_ID[7]='YTct' set Doodad_ID[8]='YTwt' set Doodad_ID[9]='JTtw' set Doodad_ID[10]='DTsh' set Doodad_ID[11]='FTtw' set Doodad_ID[12]='CTtr' set Doodad_ID[13]='ITtw' set Doodad_ID[14]='NTtw' set Doodad_ID[15]='OTtw' set Doodad_ID[16]='ZTtw' set Doodad_ID[17]='WTst' set Doodad_ID[18]='LTlt' set Doodad_ID[19]='GTsh' set Doodad_ID[20]='VTlt' set Doodad_ID[21]='WTtw' set Doodad_ID[22]='ATtc' set Doodad_ID[23]='BTtc' set Doodad_ID[24]='CTtc' set Doodad_ID[25]='ITtc' set Doodad_ID[26]='NTtc' set Doodad_ID[27]='ZTtc' endfunction function mataarbol takes nothing returns nothing local destructable d = GetEnumDestructable() local integer i set i = 1 loop exitwhen (i>27) or (GetDestructableTypeId(d)==Doodad_ID[i]) set i = i+1 endloop if (GetWidgetLife(d)> 0) and (i<=27) then call KillDestructable(d) endif set d = null endfunction private function CadaINTERVAL takes nothing returns nothing local timer t = GetExpiredTimer() local Misil M = GetAttachedStruct1(t) local unit v local real a local boolean r = false local real x1 = GetUnitX(M.proyectil) local real y1 = GetUnitY(M.proyectil) local real x2 local real y2 if(M.HaceAlPasar)then set v = M.Busca(M.Area,x1,y1,false) if(v!=null)then call M.Impacta(v) endif endif set a = SquareRoot((M.x-x1)*(M.x-x1) + (M.y-y1)*(M.y-y1)) if(M.MaxDistancia>0)then set M.distancia_misil = M.distancia_misil+SquareRoot((x1-M.x_temp)*(x1-M.x_temp) + (y1-M.y_temp)*(y1-M.y_temp)) set M.x_temp = x1 set M.y_temp = y1 endif if(M.TiempoDeVida>0.0)then set M.i = M.i+M.velocidad endif if(M.victim!=null)then set x2 = GetUnitX(M.victim) set y2 = GetUnitY(M.victim) set r = (SquareRoot((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))>50) set r = r and not((M.b) and (GetUnitAbilityLevel(M.victim,M.Spell_Buff) <= 0)) else set r = (M.MaxDistancia-M.distancia_misil>50) endif if (r) then if((M.i<=M.TiempoDeVida))then call M.mueve() //Mueve el proyectil if(M.DestroyImpact)then set M.victim = M.Busca(M.Area,GetUnitX(M.proyectil),GetUnitY(M.proyectil),false) if(M.victim!=null)then call Misil.destroy(M) endif endif else call Misil.destroy(M) endif else call Misil.destroy(M) endif set v = null set t = null endfunction struct Misil ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// // CONFIGURACION DEL MISIL ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// real x = 0.0 //Point X towards where the Missile will go. Not to fill up if the missile seeks the target. real y = 0.0 //Point Y towards where the Missile will go. Not to fill up if the missile seeks the target. real damage = 0.0 //Missile damage real velocidad = 0.03 //Time INTERVAL used in the timer. real paso = 20.0 //Distance that increases each INTERVAL determined in " velocidad". string Accion_Tipo = "None" //None : Do Nothing //Target : One target. //MultiTarget : Many targets with one single dummy spell //AoE : AoE Spell with target point (Dummy Spell) //AoESelf : AoE Spell with no targets (Dummy Spell) boolean Spell = false integer Spell_ID = 0 //Missile Spell. integer Spell_Buff = 0 //Buff that verifies if victim already received the missile and no longer it is necessity that receives buff string Spell_Order = "" //Spell dummy Order string Spell_FX = "" //Special Effect when the missile impact the target string Misil_FX = "" //Special Effect attached to the missile. Only Special Effects with Inmediate DestroyEffect. string Misil_End_FX = "" //Special Effect when the missile die. integer Spell_Nvl = 1 //Level of Dummy Spell's Missile real Area = 200.0 //AoE of the Missile real TiempoDeVida = 0.0 //Time life of the Missile real MaxDistancia = 0.0 //If you want a maximum distance that it crosses the missile, without mattering if it reached or not to its objective. boolean HaceAlPasar = false //The missile damages all the creatures around, in an AoE of "Area" while it aproach. boolean DestroyImpact = false //The missile impact in the first creature it encounters. boolean EsPersistente = false //The missile still affects the creatures who already have been affected by the spell. boolean MisilCamina = false //The missile moves according to the movespeed determined in dummy creature of the missile boolean DestroySinBuff = false //The missile will be destroyed if it followed an objective with buff and no longer it has buff suddenly. boolean PasayMataArbol = false //The missile will destroy trees around. damagetype TipoDanio = DAMAGE_TYPE_MAGIC //It determines the type of damage that does attacktype TipoAtake = ATTACK_TYPE_NORMAL //It determines the type of attack that does boolean RemueveMisil = false //It determines if the missile is removed or it is killed. By defect it is killed. unit victim = null //Set a unit so the missile follows. //If is a missile that in line goes straight not to put anything. string array Targets[14] //Array of Targets that has the spell. To add " No_" it puts the filter to the inverse one in // each case. //Alive //Alied //Mechanical //Structures //Heroes //Ilusion //Summon integer N_Targets = 0 //Size of the Array of targets. Whatever of the allowed filters you have put. //Put nothing if using the preset filters. ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// unit proyectil = null timer t = null group g = null group g_aux = null player p = null rect tmp_rect = null real x_origen = 0.0 real y_origen = 0.0 real x_temp = 0.0 real y_temp = 0.0 real distancia_misil = 0.0 real i = 0.0 real angulo = 0.0 boolean b = false static method create takes player p, integer Misil_Model, real x, real y, real a returns Misil local Misil M = Misil.allocate() set M.p = p set M.proyectil = CreateUnit(p,Misil_Model,x,y,a) set M.g = CreateGroup() //We establish the filters by defect set M.N_Targets=3 set M.Targets[1] = "Alive" set M.Targets[2] = "No_Mechanical" set M.Targets[3] = "No_Alied" return M endmethod method Vale takes unit u, boolean con_buff returns boolean local boolean r = ((GetUnitAbilityLevel(u,.Spell_Buff) > 0)==con_buff) local integer i = 1 loop exitwhen i>.N_Targets if(.Targets[i]=="Alive")then set r = r and (GetWidgetLife(u)>0.405) elseif(.Targets[i]=="No_Alive")then set r = r and (GetWidgetLife(u)<=0.405) elseif(.Targets[i]=="Alied")then set r = r and (IsUnitAlly(u,.p)) elseif(.Targets[i]=="No_Alied")then set r = r and (IsUnitAlly(u,.p)==false) elseif(.Targets[i]=="Mechanical")then set r = r and IsUnitType(u,UNIT_TYPE_MECHANICAL) elseif(.Targets[i]=="No_Mechanical")then set r = r and (IsUnitType(u,UNIT_TYPE_MECHANICAL)==false) elseif(.Targets[i]=="Structures")then set r = r and IsUnitType(u,UNIT_TYPE_STRUCTURE) elseif(.Targets[i]=="No_Structures")then set r = r and (IsUnitType(u,UNIT_TYPE_STRUCTURE)==false) elseif(.Targets[i]=="Heroes")then set r = r and IsUnitType(u,UNIT_TYPE_HERO) elseif(.Targets[i]=="No_Heroes")then set r = r and (IsUnitType(u,UNIT_TYPE_HERO)==false) elseif(.Targets[i]=="Ilusion")then set r = r and IsUnitIllusion(u) elseif(.Targets[i]=="No_Ilusion")then set r = r and (IsUnitIllusion(u)==false) elseif(.Targets[i]=="Summon")then set r = r and IsUnitType(u,UNIT_TYPE_SUMMONED) elseif(.Targets[i]=="No_Summon")then set r = r and (IsUnitType(u,UNIT_TYPE_SUMMONED)==false) endif set i = i+1 endloop if(.HaceAlPasar)then return (r and not(IsUnitInGroup(u,.g_aux))) endif return r endmethod method Busca takes real area, real x, real y, boolean con_buff returns unit local unit target = null call GroupEnumUnitsInRange(.g,x,y,area,null) loop set target = FirstOfGroup(.g) exitwhen (target==null) or this.Vale(target,con_buff) call GroupRemoveUnit(.g,target) endloop call GroupClear(.g) return target endmethod method Impacta takes unit v returns nothing local real x = GetUnitX(v) local real y = GetUnitY(v) local unit d local unit j local effect e if (.Accion_Tipo == "Target") then if(.HaceAlPasar)then call GroupAddUnit(.g_aux,v) endif if(.Spell_FX!="")then set e = AddSpecialEffect(.Spell_FX,GetUnitX(v),GetUnitY(v)) call DestroyEffectTimed(e,1.0) endif set d = CreateUnit(.p,dunit(),x,y,0) if(.damage>0.0)then call UnitDamageTarget(d,v,.damage,true,false,.TipoAtake,.TipoDanio,null) endif call UnitApplyTimedLife(d,'BTLF',1.5) if(.Spell)then debug call BJDebugMsg("Buff "+I2S(GetUnitAbilityLevel(v,.Spell_Buff))) if (GetUnitAbilityLevel(v,.Spell_Buff) <= 0) or (.EsPersistente) then debug call BJDebugMsg("Lanza el hechizos "+GetUnitName(v)) call UnitAddAbility(d,.Spell_ID) call SetUnitAbilityLevel(d, .Spell_ID, .Spell_Nvl) call IssueTargetOrder(d,.Spell_Order,v) endif endif elseif(.Accion_Tipo == "MultiTarget")then call GroupEnumUnitsInRange(.g,x,y,.Area,null) loop set j = FirstOfGroup(.g) exitwhen (j==null) call GroupRemoveUnit(.g,j) if(this.Vale(j,false)) or (this.Vale(j,.EsPersistente)) then if(.HaceAlPasar)then call GroupAddUnit(.g_aux,j) endif if(.Spell_FX!="")then set e = AddSpecialEffect(.Spell_FX,GetUnitX(j),GetUnitY(j)) call DestroyEffectTimed(e,1.0) endif set d = CreateUnit(.p,dunit(),GetUnitX(j),GetUnitY(j),0) if(.damage>0.0)then call UnitDamageTarget(d,j,.damage,true,false,.TipoAtake,.TipoDanio,null) endif call UnitApplyTimedLife(d,'BTLF',1.5) if(.Spell)then call UnitAddAbility(d,.Spell_ID) call SetUnitAbilityLevel(d, .Spell_ID, .Spell_Nvl) call IssueTargetOrder(d,.Spell_Order,j) endif endif endloop call GroupClear(.g) elseif(.Accion_Tipo == "AoE")then set d = CreateUnit(.p,dunit(),x,y,0) call UnitApplyTimedLife(d,'BTLF',1.5) call UnitAddAbility(d,.Spell_ID) call SetUnitAbilityLevel(d, .Spell_ID, .Spell_Nvl) call IssuePointOrder(d,.Spell_Order,x,y) elseif(.Accion_Tipo == "AoESelf")then set d = CreateUnit(.p,dunit(),x,y,0) call UnitApplyTimedLife(d,'BTLF',1.5) call UnitAddAbility(d,.Spell_ID) call SetUnitAbilityLevel(d, .Spell_ID, .Spell_Nvl) call IssueImmediateOrder(d,.Spell_Order) endif set e = null set j = null set d = null endmethod method onDestroy takes nothing returns nothing local effect e if(.Misil_End_FX!="")then set e = AddSpecialEffect(.Misil_End_FX,GetUnitX(.proyectil),GetUnitY(.proyectil)) call DestroyEffectTimed(e,1.0) endif if(.victim!=null)then call this.Impacta(.victim) else set .victim = this.Busca(.Area,GetUnitX(.proyectil),GetUnitY(.proyectil), false) if(.victim!=null)then call this.Impacta(.victim) endif endif if(.RemueveMisil)then call RemoveUnit(.proyectil) else if(.Spell)then call UnitApplyTimedLife(.proyectil,'BTLF',0.4) else call KillUnit(.proyectil) endif endif call DestroyGroup(.g) call DestroyGroup(.g_aux) call RemoveRect(.tmp_rect) call PauseTimer(.t) call DestroyTimer(.t) set e = null set .tmp_rect = null set .proyectil = null set .t = null set .victim = null set .g = null set .g_aux = null set .p = null endmethod method mueve takes nothing returns nothing local real a = .angulo local real x local real y if(.Misil_FX!="")then call DestroyEffect(AddSpecialEffectTarget(.Misil_FX,.proyectil,"origin")) endif if(.victim!=null)then //If victim exists, it will follow it to the missile set .x = GetUnitX(.victim) set .y = GetUnitY(.victim) set a = Atan2(.y-GetUnitY(.proyectil),.x-GetUnitX(.proyectil)) endif if(.MisilCamina)then call IssuePointOrder(.proyectil,"move",.x,.y) else set x = GetUnitX(.proyectil)+.paso*Cos(a) set y = GetUnitY(.proyectil)+.paso*Sin(a) call SetUnitPosition(.proyectil,x,y) call SetUnitFacing(.proyectil,a*57.29583) endif if(.PasayMataArbol)then set .tmp_rect = Rect(x - (.Area/2), y - (.Area/2), x + (.Area/2), y + (.Area/2)) call EnumDestructablesInRect(.tmp_rect, null, function mataarbol) endif endmethod static method dispara takes Misil M returns nothing set M.t = CreateTimer() if(M.HaceAlPasar)then set M.g_aux = CreateGroup() endif set M.x_origen = GetUnitX(M.proyectil) set M.y_origen = GetUnitY(M.proyectil) set M.x_temp = GetUnitX(M.proyectil) set M.y_temp = GetUnitY(M.proyectil) set M.angulo = Atan2(M.y-M.y_origen,M.x-M.x_origen) if(M.MaxDistancia<=0) then set M.MaxDistancia = SquareRoot((M.x-M.x_origen)*(M.x-M.x_origen) + (M.y-M.y_origen)*(M.y-M.y_origen)) endif set M.b = (M.victim!=null) //If victim already has been seteado. They boolean will be set. set M.b = M.b and (M.Spell_Buff!=0) //It detects if the Buff is defined set M.b = M.b and (GetUnitAbilityLevel(M.victim,M.Spell_Buff) > 0) //It detects if victim has buff set M.b = M.b and (M.DestroySinBuff) call AttachStruct1(M.t,M) call TimerStart(M.t,M.velocidad,true, function CadaINTERVAL) endmethod endstruct endlibrary And there are my spell: JASS:scope Espiritus globals public trigger trig private constant real INTERVAL = 0.25 private integer Spell__ID = 'AOsh' //Spell private integer Dummy_Model = 'ugar' //Ghost Model private integer Spell__Buff = 'B02I' //Curse Buff's rawcode private integer Spell_D = 'A0CN' //DummyCurse Spell 's rawcode private real Spell_AoE = 200.0 //It looks for in that area by objectives to make damage if there is no a primary objective private real Spell_Dmg_Ini = -25.0 //Damage Base private real Spell_Dmg_Pro = 75.0 //Progresive Damage per Level private string Spell__FX = "Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl" //FX of the death of the phantom. private string Dummy_Order = "cripple" endglobals private function Cond takes nothing returns boolean return GetSpellAbilityId() == Spell__ID endfunction private function Main takes nothing returns nothing local unit u = GetTriggerUnit() local real x1 = GetUnitX(u) local real y1 = GetUnitY(u) local location loc = GetSpellTargetLoc() local real x2 = GetLocationX(loc) local real y2 = GetLocationY(loc) local player p = GetOwningPlayer(u) local integer l = GetUnitAbilityLevel(u,Spell__ID) local real ang = GetAngleBetweenPoints(x1,y1,x2,y2) local Misil Phantom call RemoveLocation(loc) set Phantom = Misil.create(p,Dummy_Model,PolarProjectionX(x1,100,ang),PolarProjectionY(y1,100,ang),ang) set Phantom.x = x2 set Phantom.y = y2 set Phantom.damage = ( Spell_Dmg_Pro * l ) + Spell_Dmg_Ini + GetHeroInt(u,true) set Phantom.velocidad = INTERVAL set Phantom.Accion_Tipo = "Target" set Phantom.Spell = true set Phantom.Spell_ID = Spell_D set Phantom.Spell_Buff = Spell__Buff set Phantom.Spell_Order = Dummy_Order set Phantom.Spell_FX = Spell__FX set Phantom.Misil_End_FX = Spell__FX set Phantom.TiempoDeVida = 60.0 set Phantom.MisilCamina = true set Phantom.TipoDanio = DAMAGE_TYPE_UNIVERSAL set Phantom.TipoAtake = ATTACK_TYPE_NORMAL set Phantom.DestroySinBuff = true set Phantom.victim = Phantom.Busca(Spell_AoE,x2,y2,false) if( Phantom.victim==null)then set Phantom.victim = Phantom.Busca(9000.0,0.0,0.0, true) //If there is no damn one in the point. //I look for one that has buff. else call GroupEnumUnitsInRange(Phantom.g,0.0,0.0,9000.0,null) //I look for those that have buff and them exempt buff loop set u = FirstOfGroup(Phantom.g) exitwhen (u==null) call GroupRemoveUnit(Phantom.g,u) if(Phantom.Vale(u,true))then call UnitRemoveAbility(u,Phantom.Spell_Buff) endif endloop call GroupClear(Phantom.g) endif call Misil.dispara(Phantom) set p = null set u = null set loc = null endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set trig = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( trig, Condition( function Cond ) ) call TriggerAddAction( trig, function Main ) call Preload(Spell__FX) call Misiles_Setea() endfunction endscope Thanks in advance. P.D.: I'm using HSAS by Pandamine. |
| 10-22-2008, 09:14 AM | #2 |
In the HSAS documentation, (well, in the Usage spoiler in the HSAS thread) PandaMine indicated that you must null your struct members when they are no longer needed (i.e. in the onDestroy) |
| 10-22-2008, 01:30 PM | #3 | |
Quote:
JASS:
method onDestroy takes nothing returns nothing
local effect e
if(.Misil_End_FX!="")then
set e = AddSpecialEffect(.Misil_End_FX,GetUnitX(.proyectil),GetUnitY(.proyectil))
call DestroyEffectTimed(e,1.0)
endif
if(.victim!=null)then
call this.Impacta(.victim)
else
set .victim = this.Busca(.Area,GetUnitX(.proyectil),GetUnitY(.proyectil), false)
if(.victim!=null)then
call this.Impacta(.victim)
endif
endif
if(.RemueveMisil)then
call RemoveUnit(.proyectil)
else
if(.Spell)then
call UnitApplyTimedLife(.proyectil,'BTLF',0.4)
else
call KillUnit(.proyectil)
endif
endif
call DestroyGroup(.g)
call DestroyGroup(.g_aux)
call RemoveRect(.tmp_rect)
call PauseTimer(.t)
call DestroyTimer(.t)
set e = null
set .tmp_rect = null
set .proyectil = null
set .t = null
set .victim = null
set .g = null
set .g_aux = null
set .p = null
endmethod
|
| 10-22-2008, 03:32 PM | #4 |
Ah, my bad, didn't see the onDestroy method there ![]() |
| 10-22-2008, 04:32 PM | #5 |
Just out of curiosity, why are you designing a new system when there exist numerous (great) collision/missile systems? |
| 10-22-2008, 04:37 PM | #6 | |
Quote:
![]() |
| 10-22-2008, 05:10 PM | #7 | |
Quote:
Yeah BTW, please helpme. P.D.0: Other systems don't work with HSAS, and I want learn to use HSAS. P.D.1: I use => http://www.wc3campaigns.net/showthre...unction+DoTrue with the same fu@#ng leak. |
| 10-22-2008, 09:29 PM | #8 |
Then HSAS isn't the problem :) Try commenting out different parts of the spell and see how they affect your handle amount. |
| 10-24-2008, 05:32 AM | #9 | |
Quote:
Sorry but I can't find the problem. ![]() |
| 10-26-2008, 02:16 PM | #10 |
I already found leak. What happens is that I used the Shockwave for dummy spell. And when spell does not have model makes depressions in the map and when it does not have damage area, it accumulates leaks (fucking terrain deformation) |
