• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[vJASS] Lag when buying a hero

Status
Not open for further replies.
Level 4
Joined
May 23, 2010
Messages
83
Hello, I'm working on a RPG dungeon-based map. I've made some systems, but one doesn't seem to be working as I expected. When I pick my hero, the game get really laggy (for about 0.5 secs) and returns to normal speed again. I wonder what is causing that amount of lag, but I have no idea, as I don't know much about memory usage and etc. I tried to 'organize' the code for better understanding, so I hope someone helps me out.

JASS:
scope HeroPick initializer onInit

    globals
    
        private string array  Icon
        private string array  Class
        private integer array Code
        
        private constant integer Count = 4
        
        unit array Hero
        
        private fogmodifier array FOG
        
    endglobals
    
    private function revealArea takes nothing returns nothing
    
        local player  p = GetEnumPlayer()
        local integer i = GetPlayerId(p)
        local real    x = GetRectCenterX(gg_rct_heropickarea)
        local real    y = GetRectCenterY(gg_rct_heropickarea)
        local unit    u = CreateUnit(p, 'e000', x, y, 0)
        
        set FOG[i] = CreateFogModifierRect(p, FOG_OF_WAR_VISIBLE, gg_rct_heropickarea, false, true)
        
        call FogModifierStart(FOG[i])
        call SetUnitAnimation(u, "birth")
        call SetUnitPathing(u, false)
        
        set p = null
    endfunction
    
    private function Conditions takes nothing returns boolean
        return (GetPlayerSlotState(GetFilterPlayer()) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(GetFilterPlayer()) == MAP_CONTROL_USER)
    endfunction
    
    private function Setup takes nothing returns nothing
        local force f = CreateForce()
        call ForceEnumPlayers(f, Condition(function Conditions))
        call ForForce(f, function revealArea)
    endfunction
    
    private function Pick takes nothing returns nothing
        local unit    u  = GetSoldUnit()
        local unit    b  = GetBuyingUnit()
        local real    x  = GetRectCenterX(gg_rct_heropickspawn)
        local real    y  = GetRectCenterY(gg_rct_heropickspawn)
        local player  p  = GetOwningPlayer(u)
        local integer i  = GetPlayerId(p)
        local integer in = 0
        local integer ih = 0

        if (IsUnitType(u, UNIT_TYPE_HERO) == true) and (GetPlayerController(p) == MAP_CONTROL_USER) then 
            loop
                exitwhen in > (Count - 1)
                if Code[in] == GetUnitTypeId(u) then
                    if (GetLocalPlayer() == p) then
                        call SetUnitPosition(u, x, y)
                        call DestroyFogModifier(FOG[i])
                        call KillUnit(b)
                        call Multiboard_SetHero(Icon[in], Class[in], i)
                        
                        set AllowCamDistance[i] = true                                         //----- camera system global variables -----
                        set AllowCamRotation[i] = true                                         //
                        set AllowUnitLock[i]    = true                                         //
                        set CamUnit[i]          = u                                            //
                        set CamDistance[i]      = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE) //                                       
                        set CamAngle[i]         = GetCameraField(CAMERA_FIELD_ROTATION) + 90   //----- camera system global variables -----
                        set Hero[i]             = u
                        
                        call ClearSelection()
                        call SelectUnit(u, true)
                    endif
                    
                    loop
                        call SetPlayerTechMaxAllowed(p, Code[ih], 0)
                        exitwhen ih >= 3
                        set ih = ih + 1
                    endloop
                endif
                set in = in + 1
            endloop
        endif
        
    endfunction
    
    
    private function onInit takes nothing returns nothing
    
        local trigger Init = CreateTrigger()
        local trigger pick = CreateTrigger()
        local integer i    = 0
        local player p
        
        loop
            set p = Player(i)
            call TriggerRegisterPlayerUnitEvent(pick, p, EVENT_PLAYER_UNIT_SELL, null)
            exitwhen i >= 9
            set i = i + 1
        endloop
        
        set p = null
        
        call TriggerAddAction(pick, function Pick)
        
        call TriggerRegisterTimerEvent(Init, 0.5, false)\
        call TriggerAddAction( Init, function Setup )
        
        set Code[0] = 'H001'
        set Code[1] = 'H002'
        set Code[2] = 'H003'
        set Code[3] = 'H004'
        
        set Icon[0] = "ReplaceableTextures\\CommandButtons\\BTNBandit.blp"
        set Icon[1] = "ReplaceableTextures\\CommandButtons\\BTNBanditMage.blp"
        set Icon[2] = "ReplaceableTextures\\CommandButtons\\BTNPriest.blp"
        set Icon[3] = "ReplaceableTextures\\CommandButtons\\BTNBanditSpearThrower.blp"
        
        set Class[0] = "Warrior"
        set Class[1] = "Sorcerer"
        set Class[2] = "Priest"
        set Class[3] = "Archer"
        
    endfunction
    
endscope

EDIT: before someone ask, on my map we use 10 players max (10 palyers, 1 enemy and 1 friendly npc)
 
The most common solution is pre-placing your heroes on the map and then removing them at map initialization. The lag is caused by the game having to load all the spells when you choose a hero.

Also, you should clear the leaks you have:
JASS:
// do this for all unit locals:
set u = null

 // do this for all player locals:
set p = null

 // do this for all temporary forces:
call DestroyForce(f)
set f = null

You could also set the trigger variables to null, but that isn't too important.
 
just like when you add a dummy ability to a dummy caster for the first time - the game lags as it initially loads that ability - so we alleviate this be preloading abilities prior to the map loading

when the hero is created, you have 4 or more abilities loaded for the first time, so this lag is amplified - the same lag you experience in game will be added to your loading time if you choose to preload units in the same way we do abilities
 
and as for dummy abilities? shoul i create a dummy and add every custom ability i have too at map initialization?
 
Thank you guys, problem solved. I tested the map and it really works fine. I'll try with the dummy too, hope I won't increase too much time to loading.
 
Status
Not open for further replies.
Back
Top