| 12-15-2004, 12:41 PM | #1 |
I have a function that does this. It moves a unit a small distance every 0.01 sec. Im using polarprjoectionBJ function, I use local locations, I set them, I destroy them and then I set them to null. Having about 4 triggers like this, the memory usage does'nt go up noticable, but If I have like 16, the memory usage goes up about 200kb every second. I do clear out all memory leaks, and as I've read, polarprojectionBJ function does not leak if you destory the location created, I haven't got my code here but it looks someething like this. Code:
local location l local location l2 local unit u set u = triggering unit set l = position of u set l2 = polarprojectiobj( l, 25, unit facing u ) call moveunitloc ( l2, u ) removelocation l removelocation l2 set u = null set l = null set l2 = null |
| 12-15-2004, 12:50 PM | #2 |
The fact that it's every 0.01 second will cause leaks regardless of how well you clean them. |
| 12-15-2004, 01:03 PM | #3 |
no.. for the last time, it wont! could we have the exact trigger? |
| 12-19-2004, 08:11 PM | #4 | |
Quote:
Ok, well, Im not sure it leaks, the trigger might just be to heavy, every time you use this ability, a trigger is created that runs every 0.01 sec. 15 sec later the trigger is destroyed, the lag stops. But during those 15 sec the memory usage increases a lot, and it does'nt decrease after the trigger has been destroyed. Code:
function IsLocPathable2 takes location l returns boolean
local real x = GetLocationX(l)
local real y = GetLocationY(l)
local real ad = ((GetCameraBoundMaxX()+GetCameraMargin(CAMERA_MARGIN_RIGHT)) - (GetCameraBoundMinX()-GetCameraMargin(CAMERA_MARGIN_LEFT))) / 720
local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),'odoc',x,y,0)
call ShowUnit(u,false)
call UnitAddAbility(u,'Aeye')
if (GetUnitX(u) > x + ad) or (GetUnitX(u) < x - ad) or (GetUnitY(u) > y + ad) or (GetUnitY(u) < y - ad) then
call KillUnit( u )
call RemoveUnit(u)
return false
elseif IssuePointOrder(u,"evileye",x,y) then
call KillUnit( u )
call RemoveUnit(u)
return true
endif
call KillUnit( u )
call RemoveUnit(u)
return false
endfunction
function ShellConditions takes nothing returns boolean
if ( GetSpellAbilityId() == 'A00A') then
return true
endif
return false
endfunction
function MoveShell takes nothing returns nothing
local location l = null
local location l2 = null
local location l4 = null
local location l5 = null
local rect re = null
local effect e = null
local integer i
local integer y = 1
set i = GetHandleInt5(GetTriggeringTrigger(),"index5")
set l = GetUnitLoc(udg_UnitShell[i])
set l2 = PolarProjectionBJ(l, 100.00, udg_RealShellFacing[i])
set re = RectFromCenterSizeBJ(l2, 100.00, 100.00)
if ( IsLocPathable2(l2) == false ) then
set udg_RealShellFacing[i] = ( udg_RealShellFacing[i] + GetRandomReal(75.00, 120.00) )
else
endif
set l4 = PolarProjectionBJ(l, 35.00, udg_RealShellFacing[i])
call SetUnitPositionLoc(udg_UnitShell[i], l4)
call RemoveLocation (l)
call RemoveLocation (l2)
call RemoveLocation (l4)
set l = null
set l2 = null
set l4 = null
loop
exitwhen y > 4
if ( (RectContainsUnit(re, udg_PlayerCar[y]) == true) and udg_PlayerCar[y] != udg_PlayerCar[1] ) then
if ( udg_BoolStar[y] != true ) then
set udg_PlayerSpeed[y] = 0.00
else
endif
call KillUnit( udg_UnitShell[i] )
call RemoveUnit( udg_UnitShell[i] )
set l5 = GetUnitLoc(udg_PlayerCar[y])
call AddSpecialEffectLocBJ(l5 , "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl" )
set e = GetLastCreatedEffectBJ()
call DestroyEffectBJ( e )
set e = null
call RemoveLocation (l5)
call DestroyTrigger( GetTriggeringTrigger() )
set y = 7
endif
set y = y + 1
endloop
call RemoveRect(re)
set re = null
endfunction
function ShellActions takes nothing returns nothing
local unit caster
local integer i
local location l
local location l2
local real r
local trigger t
set udg_IntShell = udg_IntShell + 1
set t = CreateTrigger()
set caster = GetTriggerUnit()
set i = GetConvertedPlayerId(GetOwningPlayer(caster))
set l = GetUnitLoc(caster)
set l2 = PolarProjectionBJ(l , 150.00, GetUnitFacing(caster))
call CreateNUnitsAtLoc(1, 'ogru', Player(i), l2, GetUnitFacing(caster) )
set udg_UnitShell[udg_IntShell] = GetLastCreatedUnit()
call SetUnitPathing( udg_UnitShell[udg_IntShell], false )
set udg_RealShellFacing[udg_IntShell] = GetUnitFacing(udg_PlayerCar[i])
call SetHandleInt5(t,"index5",udg_IntShell)
call TriggerRegisterTimerEventPeriodic( t, 0.01 )
call TriggerAddAction( t, function MoveShell )
call RemoveLocation (l)
call RemoveLocation (l2)
set l = null
set l2 = null
set caster = null
call PolledWait(15)
call DestroyTrigger( t )
set t = null
endfunction
//===========================================================================
function InitTrig_Cast_Shell takes nothing returns nothing
set gg_trg_Cast_Shell = CreateTrigger( )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(0), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(1), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(2), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(3), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Cast_Shell, Condition( function ShellConditions ) )
call TriggerAddAction( gg_trg_Cast_Shell, function ShellActions )
endfunction
|
| 12-19-2004, 08:34 PM | #5 | |
Quote:
anyways, I noted that a timer of 0.05 seems to do the same effect to the human eye, and uses far less process time than one of 0.01 . |
| 12-20-2004, 02:21 AM | #6 | |
Quote:
Hmm.. I've tried to fix it but it still does'nt work very good. I've lowered the time to every 0.03 sec, but lower then that I can't go. Maybe I should tell what the trigger is for and what it does. Ok. Have you ever played mariokart? Maybe you know there is a mariokart mod in the making right now. I'm created the movement system and the abilities, this is for the green shell. what the trigger does is, when someone gets a greenshell and fires it off, a unit is created ( the shell ) and moves with high speed, it bounces on trees, cliffs, etc like in real mariokart, and it does so until it hits a car or dies by itself, which it does after 60 sec. I can't have the timer to check higher then 0.03 , that would make, either the shell to move to slow, or the shell could go through a car not "hitting it" because it would already be out of range, because of the fact that the shell does'nt use real movement, but is instantly "teleported" to a new location every 0.03 sec. If you fire off one shell, and it moves around, you won't see any change in memory usage. But if you fire off like 5 shells at the same time. the memory usage will increase by roughly 250kb / sec, until the shell is destroyed. With 10 shells out there, I have about 5fps or something, and I have a pretty new comp. So if u have any idea how I could fix this trigger... or any idea of another rework, it would be realy appreciated. Thanks. Code:
function IsLocPathable2 takes location l returns boolean
local real x = GetLocationX(l)
local real y = GetLocationY(l)
local real ad = ((GetCameraBoundMaxX()+GetCameraMargin(CAMERA_MARGIN_RIGHT)) - (GetCameraBoundMinX()-GetCameraMargin(CAMERA_MARGIN_LEFT))) / 720
local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),'odoc',x,y,0)
call ShowUnit(u,false)
call UnitAddAbility(u,'Aeye')
if (GetUnitX(u) > x + ad) or (GetUnitX(u) < x - ad) or (GetUnitY(u) > y + ad) or (GetUnitY(u) < y - ad) then
call KillUnit( u )
call RemoveUnit(u)
return false
elseif IssuePointOrder(u,"evileye",x,y) then
call KillUnit( u )
call RemoveUnit(u)
return true
endif
call KillUnit( u )
call RemoveUnit(u)
return false
endfunction
function ShellConditions takes nothing returns boolean
if ( GetSpellAbilityId() == 'A00A') then
return true
endif
return false
endfunction
function MoveShell takes nothing returns nothing
local location l = null
local location l2 = null
local location l4 = null
local location l5 = null
local rect re = null
local effect e = null
local integer i
local integer y = 1
set i = GetHandleInt5(GetTriggeringTrigger(),"index5")
set l = GetUnitLoc(udg_UnitShell[i])
set l2 = PolarProjectionBJ(l, 100.00, udg_RealShellFacing[i])
set re = RectFromCenterSizeBJ(l2, 150.00, 150.00)
if ( IsLocPathable2(l2) == false ) then
set udg_RealShellFacing[i] = ( udg_RealShellFacing[i] + GetRandomReal(75.00, 120.00) )
else
endif
set l4 = PolarProjectionBJ(l, 95.00, udg_RealShellFacing[i])
call SetUnitPositionLoc(udg_UnitShell[i], l4)
call RemoveLocation (l)
call RemoveLocation (l2)
call RemoveLocation (l4)
set l = null
set l2 = null
set l4 = null
loop
exitwhen y > 4
if (RectContainsUnit(re, udg_PlayerCar[y]) ) then
if ( udg_BoolStar[y] != true ) then
set udg_PlayerSpeed[y] = 0.00
else
endif
call KillUnit( udg_UnitShell[i] )
call RemoveUnit( udg_UnitShell[i] )
set l5 = GetUnitLoc(udg_PlayerCar[y])
call AddSpecialEffectLocBJ(l5 , "Objects\\Spawnmodels\\NightElf\\NEDeathMedium\\NEDeath.mdl" )
set e = GetLastCreatedEffectBJ()
call DestroyEffectBJ( e )
set e = null
call RemoveLocation (l5)
call DestroyTrigger( GetTriggeringTrigger() )
set y = 7
endif
set y = y + 1
endloop
call RemoveRect(re)
set re = null
endfunction
function ShellActions takes nothing returns nothing
local unit caster
local integer i
local integer u
local location l
local location l2
local real r
local trigger t
set udg_IntShell = udg_IntShell + 1
set u = udg_IntShell
set t = CreateTrigger()
set caster = GetTriggerUnit()
set i = GetConvertedPlayerId(GetOwningPlayer(caster))
set l = GetUnitLoc(caster)
set l2 = PolarProjectionBJ(l , 250.00, GetUnitFacing(caster))
call CreateNUnitsAtLoc(1, 'ogru', Player(i), l2, GetUnitFacing(caster) )
set udg_UnitShell[u] = GetLastCreatedUnit()
call SetUnitPathing( udg_UnitShell[u], false )
set udg_RealShellFacing[u] = GetUnitFacing(udg_PlayerCar[i])
call SetHandleInt5(t,"index5", u)
call TriggerRegisterTimerEventPeriodic( t, 0.03 )
call TriggerAddAction( t, function MoveShell )
call RemoveLocation (l)
call RemoveLocation (l2)
set l = null
set l2 = null
set caster = null
call PolledWait(60)
call SetHandleInt5(t,"index5",0)
call FlushHandleLocals5(t)
call KillUnit( udg_UnitShell[u] )
call RemoveUnit( udg_UnitShell[u] )
call DestroyTrigger( t )
set t = null
endfunction
//===========================================================================
function InitTrig_Cast_Shell takes nothing returns nothing
set gg_trg_Cast_Shell = CreateTrigger( )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(0), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(1), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(2), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast_Shell, Player(3), EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Cast_Shell, Condition( function ShellConditions ) )
call TriggerAddAction( gg_trg_Cast_Shell, function ShellActions )
endfunction
|
| 12-21-2004, 02:48 PM | #7 |
you are not clearing the handle variable, but you don't only have to change the timer to 0.05, you after that have to change every single calculation to consider that it is going at 0.05 instead of 0.01 |
| 12-26-2004, 03:37 PM | #8 | |
Quote:
What handle variable? could you display it in code? |
| 12-30-2004, 03:26 AM | #9 |
First of, You should deffinetely make it run every 0.05 seconds. As 0.01 is just crazy. As vexorian says, you ofcourse just need to edit all constants to fit to the new timing. Becouse... 100 times per second is WAY too much. most people don't even reach that FPS in WC3. Most movie-conent runs at 20-25 frames per second... and you won't notice that being slow/flickery/anything. So visually, 0.05 is optimal for anything visual. Plus, then people like me who only have intermediate computers, can actually run your map. Secondly. By running through your code, I can spot a couple of things that you should fix, memory-wise: null the unit variable in IsLocPathable when done. These are the rare instances that you should null a unit variable, this leak could sum up pretty easily, since it runs every tick. You should null "l5" in the rare instances that you use it. (when you hit something). This leak is very rare. And lastly, you should Remove the action that you add to your trigger when you're done. I think I remember it leaking somewhat. You do this by catching the TriggerAction returned by the TriggerAddAction function. Then you call TriggerRemoveAction (you might wanna look it up, since i'm writing from memory) using the TriggerAction. Again, only a once per shell leak. Other than this, it's pretty clean. You might wanna improve the performance by using native functions rather than BJ functions, considering you're doing a periodic timer. ~Cubasis |
| 12-30-2004, 06:58 PM | #10 |
BLizzard's Azeroth GRand PRix map uses 0.05 for the timer, as if they read all of my posts |
| 12-30-2004, 09:10 PM | #11 | |
Quote:
my comp reaches over 150 fps, and the human eye can see 24 frames per second, so 0.04 would be better :P |
