• 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.

[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)
 
Level 17
Joined
Feb 11, 2011
Messages
1,860
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.
 
Level 12
Joined
Mar 28, 2005
Messages
160
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
 
Level 4
Joined
May 23, 2010
Messages
83
and as for dummy abilities? shoul i create a dummy and add every custom ability i have too at map initialization?
 
Level 4
Joined
May 23, 2010
Messages
83
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.
Top