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

Hero Selection Lag

Status
Not open for further replies.
Level 14
Joined
Dec 29, 2009
Messages
931
  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set HR_Hashtable = (Last created hashtable)
      • Set generic_QuestGiver[1] = Sergeant Karael 0060 <gen>
      • Set generic_QuestGiver[2] = Lieutenant Ser'en 0027 <gen>
      • Set generic_QuestGiver[3] = Military Commander 0026 <gen>
      • Set generic_QuestGiver[4] = Archangel 0038 <gen>
      • Set generic_QuestGiver[5] = Grendal 0019 <gen>
      • Set generic_QuestGiver[6] = Tiron & Vero 0009 <gen>
      • Set generic_QuestGiver[7] = Alchemist 0055 <gen>
      • Set generic_QuestGiver[8] = Engineer 0046 <gen>
      • Set generic_QuestGiver[9] = |cffffcc00Queen|r 0003 <gen>
      • Set generic_QuestGiver[10] = |cffffcc00King|r 0004 <gen>
      • Set generic_QuestGiver[11] = Legionnaire 0189 <gen>
      • Set generic_QuestGiver[12] = Sergeant Ryker 0024 <gen>
      • Quest - Create a Required quest titled Map Testing with the description Testing a map suffi..., using icon path ReplaceableTextures\CommandButtons\BTNAdept 002.blp
      • Quest - Create a Required quest titled Credits with the description Due to the overwhel..., using icon path ReplaceableTextures\CommandButtons\BTNAdept 002.blp
      • Game - Hide creep camps on the minimap
      • Game - Disable ally color button and Disable creep camp button
      • Unit - Order Workman 0017 <gen> to Harvest Dalaran Ruins Tree Wall [c] 0167 <gen>
      • Unit - Order Workman 0015 <gen> to Harvest Dalaran Ruins Tree Wall [c] 0165 <gen>
      • Unit - Order Workman 0007 <gen> to Harvest Dalaran Ruins Tree Wall [c] 0180 <gen>
      • Unit - Order Workman 0014 <gen> to Harvest Dalaran Ruins Tree Wall [c] 0213 <gen>
      • Unit - Order Workman 0183 <gen> to Harvest Dalaran Ruins Tree Wall [c] 3923 <gen>
      • Unit - Order Workman 0182 <gen> to Harvest Dalaran Ruins Tree Wall [c] 3910 <gen>
      • Set generic_VisibilityRegion[1] = generic Visibility1 <gen>
      • Set HR_RevivePoint[1] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[2] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[3] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[4] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[5] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[6] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[7] = (Random point in HR RevivePoint 1 <gen>)
      • Set HR_RevivePoint[8] = (Random point in HR RevivePoint 1 <gen>)
      • Player - Make Player 9 (Gray) treat Neutral Hostile as an Ally
      • Player - Make Player 10 (Light Blue) treat Neutral Hostile as an Ally
      • Player - Make Player 11 (Dark Green) treat Neutral Hostile as an Ally
      • Player - Make Player 12 (Brown) treat Neutral Hostile as an Ally
      • Player - Make Neutral Hostile treat Player 9 (Gray) as an Ally
      • Player - Make Neutral Hostile treat Player 10 (Light Blue) as an Ally
      • Player - Make Neutral Hostile treat Player 11 (Dark Green) as an Ally
      • Player - Make Neutral Hostile treat Player 12 (Brown) as an Ally
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Make Player 9 (Gray) treat Player 11 (Dark Green) as an Ally with shared vision
          • Player - Make Player 10 (Light Blue) treat Player 11 (Dark Green) as an Ally with shared vision
          • Player - Make Player 11 (Dark Green) treat Player 9 (Gray) as an Ally with shared vision
          • Player - Make Player 11 (Dark Green) treat Player 10 (Light Blue) as an Ally with shared vision
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked player) controller) Equal to User
            • Then - Actions
              • Player - Make (Picked player) treat Player 9 (Gray) as an Ally with shared vision
              • Player - Make (Picked player) treat Player 10 (Light Blue) as an Ally with shared vision
              • Player - Make Player 9 (Gray) treat (Picked player) as an Ally with shared vision
              • Player - Make Player 10 (Light Blue) treat (Picked player) as an Ally with shared vision
            • Else - Actions
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked player) slot status) Equal to Is playing
              • ((Picked player) controller) Equal to User
            • Then - Actions
              • Player - Set (Picked player) Current gold to 200
              • Camera - Lock camera target for (Picked player) to Hero Selection 0128 <gen>, offset by (0.00, 0.00) using Default rotation
              • Visibility - Create an initially Enabled visibility modifier for (Picked player) emitting Visibility across generic_VisibilityRegion[1]
              • Set generic_HeroSelectionVisible[(Player number of (Picked player))] = (Last created visibility modifier)
            • Else - Actions
      • Unit - Create 1 Hero Chooser for Player 1 (Red) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[1] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 2 (Blue) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[2] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 3 (Teal) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[3] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 4 (Purple) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[4] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 5 (Yellow) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[5] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 6 (Orange) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[6] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 7 (Green) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[7] = (Last created unit)
      • Unit - Create 1 Hero Chooser for Player 8 (Pink) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[8] = (Last created unit)
      • Set generic_Gates[1] = Bank Vault Gate (open(down)) 3850 <gen>
      • For each (Integer generic_GatesInt) from 1 to 1, do (Actions)
        • Loop - Actions
          • Destructible - Open generic_Gates[generic_GatesInt]
      • Set generic_GatesAlt[1] = City Entrance (open(left/right)) 0384 <gen>
      • Set generic_GatesAlt[2] = Gate (open(right)) 3878 <gen>
  • HS Initialize
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set HS_TavernHeroes[1] = |cffcc0000Champion|r
      • Set HS_TavernHeroes[2] = |cffcc0000Savior|r
      • Set HS_TavernHeroes[3] = |cffcc0000Warp Knight|r
      • Set HS_TavernHeroes[4] = |cffcc0000Demon Knight|r
      • Set HS_TavernHeroes[5] = |cff00cc00Dark Huntress|r
      • Set HS_TavernHeroes[6] = |cff00cc00Ancient Titan|r
      • Set HS_TavernHeroes[7] = |cff00cc00Demonic Avatar|r
      • Set HS_TavernHeroes[8] = |cff00ccccArcane Ranger|r
      • Set HS_TavernHeroes[9] = |cff6bb2edHoly Matron|r
      • Set HS_TavernHeroes[10] = |cff6bb2edMystic|r
      • Set HS_TavernHeroes[11] = |cff00cc00Berserker|r
      • Set HS_TavernHeroes[12] = |cff6bb2edSoul Mage|r
      • Set HS_RepickTrigger[1] = HS Repick1 <gen>
      • Set HS_RepickTrigger[2] = HS Repick2 <gen>
      • Set HS_RepickTrigger[3] = HS Repick3 <gen>
      • Set HS_RepickTrigger[4] = HS Repick4 <gen>
      • Set HS_RepickTrigger[5] = HS Repick5 <gen>
      • Set HS_RepickTrigger[6] = HS Repick6 <gen>
      • Set HS_RepickTrigger[7] = HS Repick7 <gen>
      • Set HS_RepickTrigger[8] = HS Repick8 <gen>
  • HS Chosen
    • Events
      • Unit - A unit Sells a unit
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • ((Sold unit) is A Hero) Equal to True
          • Or - Any (Conditions) are true
            • Conditions
              • (Selling unit) Equal to Hero Selection 0128 <gen>
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HS_HeroChosen[(Player number of (Owner of (Sold unit)))] Equal to True
        • Then - Actions
          • Unit - Remove (Sold unit) from the game
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: |cffff0000You've al...
        • Else - Actions
          • Set HS_HeroType[(Player number of (Owner of (Sold unit)))] = (Unit-type of (Sold unit))
          • Set HS_HeroChosen[(Player number of (Owner of (Sold unit)))] = True
          • Set HS_PlayerHero[(Player number of (Owner of (Sold unit)))] = (Sold unit)
          • Trigger - Turn on HS_RepickTrigger[(Player number of (Owner of (Sold unit)))]
          • Unit - Move (Sold unit) instantly to (Center of HS MoveTo1 <gen>), facing 0.00 degrees
          • Hero - Create Small Healing Potion and give it to (Sold unit)
          • Item - Set charges remaining in (Last created item) to 10
          • Hero - Create Small Mana Potion and give it to (Sold unit)
          • Item - Set charges remaining in (Last created item) to 10
          • Hero - Modify unspent skill points of HS_PlayerHero[(Player number of (Owner of (Sold unit)))]: Add 9 points
          • Unit - Remove HS_HeroChooser[(Player number of (Owner of (Sold unit)))] from the game
          • Player Group - Pick every player in (All players) and do (Actions)
            • Loop - Actions
              • Player - Make HS_HeroType[(Player number of (Owner of (Sold unit)))] Unavailable for training/construction by (Picked player)
          • Visibility - Disable generic_HeroSelectionVisible[(Player number of (Owner of (Sold unit)))]
          • Camera - Pan camera for (Owner of (Sold unit)) to (Center of HS MoveTo1 <gen>) over 0.00 seconds
          • Game - Display to (All players) for 8.00 seconds the text: ((Name of (Owner of (Sold unit))) + ( has chosen the |cffffcc00 + ((Name of (Sold unit)) + .)))
          • Game - Display to (Player group((Owner of (Sold unit)))) for 10.00 seconds the text: |cffff0000This is y...
          • Selection - Clear selection for (Owner of (Sold unit))
          • Selection - Add (Sold unit) to selection for (Owner of (Sold unit))
  • HS Repick1
    • Events
      • Player - Player 1 (Red) types a chat message containing -repick as An exact match
    • Conditions
      • HS_HeroChosen[(Player number of (Triggering player))] Equal to True
    • Actions
      • Cinematic - Clear the screen of text messages for (Player group((Triggering player)))
      • Custom script: call RemoveUnit(udg_HS_PlayerHero[GetConvertedPlayerId(GetTriggerPlayer())])
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Make HS_HeroType[(Player number of (Triggering player))] Available for training/construction by (Picked player)
      • Visibility - Enable generic_HeroSelectionVisible[(Player number of (Triggering player))]
      • Camera - Lock camera target for (Triggering player) to Hero Selection 0128 <gen>, offset by (0.00, 0.00) using Default rotation
      • Unit - Create 1 Hero Chooser for (Triggering player) at (Center of generic_VisibilityRegion[1]) facing 0.00 degrees
      • Set HS_HeroChooser[(Player number of (Triggering player))] = (Last created unit)
      • Set HS_HeroChosen[(Player number of (Triggering player))] = False
The problem here is that everytime a player selects a hero for the first time, there's a massive 15-25 second lagg spike.
This is obviously undesired, and I'd like to find out why it's doing this.

I've included a few triggers used for the selection itself.
The lag appears after the player chooses a hero (sold unit) from the tavern (selling unit).

Additionally, this is in the Map's custom script code;
JASS:
library GroupUtils initializer Init requires optional xebasic
globals
    //If you don't have xebasic in your map, this value will be used instead.
    //This value corresponds to the max collision size of a unit in your map.
    private constant real    MAX_COLLISION_SIZE = 197.
    //If you are insane and don't care about any of the protection involved in
    //this library, but want this script to be really fast, set this to true.
    private constant boolean LESS_SAFETY        = false
endglobals
globals
    //* Constants that are available to the user
    group    ENUM_GROUP     = CreateGroup()
    boolexpr BOOLEXPR_TRUE  = null
    boolexpr BOOLEXPR_FALSE = null
endglobals
globals
    //* Hashtable for debug purposes
    private hashtable     ht     = InitHashtable()
    //* Temporary references for GroupRefresh
    private boolean       Flag   = false
    private group         Refr   = null
    //* Arrays and counter for the group stack
    private group   array Groups
    private integer       Count  = 0
    //* Variables for use with the GroupUnitsInArea function
    private real          X      = 0.
    private real          Y      = 0.
    private real          R      = 0.
    private hashtable     H      = InitHashtable()
endglobals
private function HookDestroyGroup takes group g returns nothing
    if g == ENUM_GROUP then
        call BJDebugMsg(SCOPE_PREFIX+"Warning: ENUM_GROUP destroyed")
    endif
endfunction
debug hook DestroyGroup HookDestroyGroup
private function AddEx takes nothing returns nothing
    if Flag then
        call GroupClear(Refr)
        set Flag = false
    endif
    call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
    set Flag = true
    set Refr = g
    call ForGroup(Refr, function AddEx)
    if Flag then
        call GroupClear(g)
    endif
endfunction
function NewGroup takes nothing returns group
    if Count == 0 then
        set Groups[0] = CreateGroup()
    else
        set Count = Count - 1
    endif
    static if not LESS_SAFETY then
        call SaveInteger(ht, 0, GetHandleId(Groups[Count]), 1)
    endif
    return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
    local integer id = GetHandleId(g)
    static if LESS_SAFETY then
        if g == null then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
            return false
        elseif Count == 8191 then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
            call DestroyGroup(g)
            return false
        endif
    else
        if g == null then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
            return false
        elseif not HaveSavedInteger(ht, 0, id) then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Group not part of stack")
            return false
        elseif LoadInteger(ht, 0, id) == 2 then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Groups cannot be multiply released")
            return false
        elseif Count == 8191 then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
            call DestroyGroup(g)
            return false
        endif
        call SaveInteger(ht, 0, id, 2)
    endif
    call GroupClear(g)
    set Groups[Count] = g
    set Count         = Count + 1
    return true
endfunction
private function Filter takes nothing returns boolean
    return IsUnitInRangeXY(GetFilterUnit(), X, Y, R)
endfunction
private function HookDestroyBoolExpr takes boolexpr b returns nothing
    local integer bid = GetHandleId(b)
    if HaveSavedHandle(H, 0, bid) then
        //Clear the saved boolexpr
        call DestroyBoolExpr(LoadBooleanExprHandle(H, 0, bid))
        call RemoveSavedHandle(H, 0, bid)
    endif
endfunction
hook DestroyBoolExpr HookDestroyBoolExpr
private constant function GetRadius takes real radius returns real
    static if LIBRARY_xebasic then
        return radius+XE_MAX_COLLISION_SIZE
    else
        return radius+MAX_COLLISION_SIZE
    endif
endfunction
function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
    local real    prevX = X
    local real    prevY = Y
    local real    prevR = R
    local integer bid   = 0
 
    //Set variables to new values
    set X = x
    set Y = y
    set R = radius
    if filter == null then
        //Adjusts for null boolexprs passed to the function
        set filter = Condition(function Filter)
    else
        //Check for a saved boolexpr
        set bid = GetHandleId(filter) 
        if HaveSavedHandle(H, 0, bid) then
            //Set the filter to use to the saved one
            set filter = LoadBooleanExprHandle(H, 0, bid)
        else
            //Create a new And() boolexpr for this filter
            set filter = And(Condition(function Filter), filter)
            call SaveBooleanExprHandle(H, 0, bid, filter)
        endif
    endif
    //Enumerate, if they want to use the boolexpr, this lets them
    call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), filter)
    //Give back original settings so nested enumerations work
    set X = prevX
    set Y = prevY
    set R = prevR
endfunction
function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
    local real prevX = X
    local real prevY = Y
    local real prevR = R
 
    //Set variables to new values
    set X = x
    set Y = y
    set R = radius
    //Enumerate
    call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), Condition(function Filter))
    //Give back original settings so nested enumerations work
    set X = prevX
    set Y = prevY
    set R = prevR
endfunction
private function True takes nothing returns boolean
    return true
endfunction
private function False takes nothing returns boolean
    return false
endfunction
private function Init takes nothing returns nothing
    set BOOLEXPR_TRUE  = Condition(function True)
    set BOOLEXPR_FALSE = Condition(function False)
endfunction
endlibrary

I believe this is used for one of the spells.
In addition to that, I'm using TimerUtils (also used for a spell).
JASS:
library TimerUtils initializer init
    globals
        private constant boolean USE_HASH_TABLE      = true
        private constant boolean USE_FLEXIBLE_OFFSET = false
        private constant integer OFFSET     = 0x100000
        private          integer VOFFSET    = OFFSET
 
        private constant integer QUANTITY   = 256
 
        private constant integer ARRAY_SIZE = 8190
    endglobals
 
    globals
        private integer array data[ARRAY_SIZE]
        private hashtable     ht
    endglobals
 
 
 
    function SetTimerData takes timer t, integer value returns nothing
        static if(USE_HASH_TABLE) then
            call SaveInteger(ht,0,GetHandleId(t), value)
 
        elseif (USE_FLEXIBLE_OFFSET) then
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-VOFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            set data[GetHandleId(t)-VOFFSET]=value
        else
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-OFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            set data[GetHandleId(t)-OFFSET]=value
        endif        
    endfunction
    function GetTimerData takes timer t returns integer
        static if(USE_HASH_TABLE) then
            return LoadInteger(ht,0,GetHandleId(t) )
 
        elseif (USE_FLEXIBLE_OFFSET) then
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-VOFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            return data[GetHandleId(t)-VOFFSET]
        else
            static if (DEBUG_MODE) then
                if(GetHandleId(t)-OFFSET<0) then
                    call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                endif
            endif
            return data[GetHandleId(t)-OFFSET]
        endif        
    endfunction
 
    globals
        private timer array tT[ARRAY_SIZE]
        private integer tN = 0
        private constant integer HELD=0x28829022
 
        private boolean       didinit = false
    endglobals
    private keyword init
 
    function NewTimerEx takes integer value returns timer
        if (tN==0) then
            if (not didinit) then 
                call init.evaluate()
                set tN = tN - 1
            else
                debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
                set tT[0]=CreateTimer()
                static if( not USE_HASH_TABLE) then
                    debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
                    static if( USE_FLEXIBLE_OFFSET) then
                        if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    else
                        if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    endif
                endif
            endif
        else
            set tN=tN-1
        endif
        call SetTimerData(tT[tN],value)
     return tT[tN]
    endfunction
 
    function NewTimer takes nothing returns timer
        return NewTimerEx(0)
    endfunction
 
 
    function ReleaseTimer takes timer t returns nothing
        if(t==null) then
            debug call BJDebugMsg("Warning: attempt to release a null timer")
            return
        endif
        if (tN==ARRAY_SIZE) then
            debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
 
            call DestroyTimer(t)
        else
            call PauseTimer(t)
            if(GetTimerData(t)==HELD) then
                debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
                return
            endif
            call SetTimerData(t,HELD)
            set tT[tN]=t
            set tN=tN+1
        endif    
    endfunction
    private function init takes nothing returns nothing
     local integer i=0
     local integer o=-1
     local boolean oops = false
        if ( didinit ) then
            return
        else
            set didinit = true
        endif
 
        static if( USE_HASH_TABLE ) then
            set ht = InitHashtable()
            loop
                exitwhen(i==QUANTITY)
                set tT[i]=CreateTimer()
                call SetTimerData(tT[i], HELD)
                set i=i+1
            endloop
            set tN = QUANTITY
        else
            loop
                set i=0
                loop
                    exitwhen (i==QUANTITY)
                    set tT[i] = CreateTimer()
                    if(i==0) then
                        set VOFFSET = GetHandleId(tT[i])
                        static if(USE_FLEXIBLE_OFFSET) then
                            set o=VOFFSET
                        else
                            set o=OFFSET
                        endif
                    endif
                    if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
                        exitwhen true
                    endif
                    if (GetHandleId(tT[i])-o>=0)  then
                        set i=i+1
                    endif
                endloop
                set tN = i
                exitwhen(tN == QUANTITY)
                set oops = true
                exitwhen not USE_FLEXIBLE_OFFSET
                debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")               
            endloop
 
            if(oops) then
                static if ( USE_FLEXIBLE_OFFSET) then
                    debug call BJDebugMsg("The problem has been fixed.")
                elseif(DEBUG_MODE) then
                    call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
                    call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
                    call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
                    call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
                endif
            endif
        endif
    endfunction
endlibrary
 
Level 16
Joined
Mar 27, 2011
Messages
1,349
I will take a closer look later, but your coding isnt very efficient.

  • Conditions
  • And - All (Conditions) are true
  • Conditions
  • ((Sold unit) is A Hero) Equal to True
  • Or - Any (Conditions) are true
  • Conditions
  • (Selling unit) Equal to Hero Selection 0128 <gen>
You or conditions is not neccicary.
 
I can't test it myself, but the best way to figure out which actions are causing the lag spike is to add debug messages. Just add Game Messages at certain points throughout the trigger. For example, you could add one right after the unit is moved saying "The unit is moved", one right after the items are given saying "The items were added", one right after giving skill points and removed, etc.

Then test it and see which messages appear before the lag spike. If they appear before the lag spike, then those parts of the code are fine. It is appears after the lag spike, then those are the areas you want to look at. From there, we can figure out what to do.

My best guess is that it is some issue that can be resolved through preloading. (similar to the way there is a lag spike when a unit learns a spell for the first time)
 
Level 14
Joined
Dec 29, 2009
Messages
931
I can't test it myself, but the best way to figure out which actions are causing the lag spike is to add debug messages. Just add Game Messages at certain points throughout the trigger. For example, you could add one right after the unit is moved saying "The unit is moved", one right after the items are given saying "The items were added", one right after giving skill points and removed, etc.

Then test it and see which messages appear before the lag spike. If they appear before the lag spike, then those parts of the code are fine. It is appears after the lag spike, then those are the areas you want to look at. From there, we can figure out what to do.

My best guess is that it is some issue that can be resolved through preloading. (similar to the way there is a lag spike when a unit learns a spell for the first time)

Unfortunately, I believe it's something else. Perhaps a different trigger.
I tried the debug messages as you've asked, and the lagg happened before ANY of the numbers appeared (0-12).

This is the trigger I used:
  • HS Chosen
    • Events
      • Unit - A unit Sells a unit
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • ((Sold unit) is A Hero) Equal to True
          • (Selling unit) Equal to Hero Selection 0128 <gen>
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HS_HeroChosen[(Player number of (Owner of (Sold unit)))] Equal to True
        • Then - Actions
          • Unit - Remove (Sold unit) from the game
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: |cffff0000You've al...
        • Else - Actions
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 0
          • Set HS_HeroType[(Player number of (Owner of (Sold unit)))] = (Unit-type of (Sold unit))
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 1
          • Set HS_HeroChosen[(Player number of (Owner of (Sold unit)))] = True
          • Set HS_PlayerHero[(Player number of (Owner of (Sold unit)))] = (Sold unit)
          • Trigger - Turn on HS_RepickTrigger[(Player number of (Owner of (Sold unit)))]
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 2
          • Unit - Move (Sold unit) instantly to (Center of HS MoveTo1 <gen>), facing 0.00 degrees
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 3
          • Hero - Create Small Healing Potion and give it to (Sold unit)
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 4
          • Item - Set charges remaining in (Last created item) to 10
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 5
          • Hero - Create Small Mana Potion and give it to (Sold unit)
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 6
          • Item - Set charges remaining in (Last created item) to 10
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 7
          • Hero - Modify unspent skill points of HS_PlayerHero[(Player number of (Owner of (Sold unit)))]: Add 9 points
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 8
          • Unit - Remove HS_HeroChooser[(Player number of (Owner of (Sold unit)))] from the game
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 9
          • Player Group - Pick every player in (All players) and do (Actions)
            • Loop - Actions
              • Player - Make HS_HeroType[(Player number of (Owner of (Sold unit)))] Unavailable for training/construction by (Picked player)
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 10
          • Visibility - Disable generic_HeroSelectionVisible[(Player number of (Owner of (Sold unit)))]
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 11
          • Camera - Pan camera for (Owner of (Sold unit)) to (Center of HS MoveTo1 <gen>) over 0.00 seconds
          • Game - Display to (Player group((Owner of (Sold unit)))) the text: 12
          • Game - Display to (All players) for 8.00 seconds the text: ((Name of (Owner of (Sold unit))) + ( has chosen the |cffffcc00 + ((Name of (Sold unit)) + .)))
          • Game - Display to (Player group((Owner of (Sold unit)))) for 10.00 seconds the text: |cffff0000This is y...
          • Selection - Clear selection for (Owner of (Sold unit))
          • Selection - Add (Sold unit) to selection for (Owner of (Sold unit))
Although, that would explain why the lag doesn't happen when the repick option is used.
It only happens once per player, and it doesn't matter which hero is chosen.
You're trustworthy, if you'd like the map I'd be more than happy to send it to you in a PM.
 
Level 14
Joined
Dec 29, 2009
Messages
931
I don't think I understand what you're saying. :p
Could you provide an example?

As for the lag, YOU'RE A GENIUS. I did some experimenting with the abilities, and the stat gain abilities have 500 levels each.
While it doesn't require any levels to learn, 3 * 500 = 1500, which for some reason is causing the lag.

I removed the abilities from one hero and tried selecting it, and it worked fine.
So I need to find a way to preload them, or use a different method for gaining stats.

Thank you so much. <3
 
Level 7
Joined
Aug 15, 2012
Messages
318
np glad I could help and for the init triggers heres what I did

  • Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 8, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Player((Integer A))) slot status) Equal to Is playing
            • Then - Actions
              • Set TempLoc1 = ((Player((Integer A))) start location)
              • Unit - Create 1 Wisp for (Player((Integer A))) at TempLoc1 facing Default building facing degrees
              • Player - Add 1 to (Player((Integer A))) Available free Heroes
              • Custom script: call RemoveLocation(udg_TempLoc1)
              • Custom script: set udg_TempLoc1 = null
            • Else - Actions
      • -------- Initialize Systems --------
      • Trigger - Run NPS Initialization <gen> (ignoring conditions)
      • Trigger - Run Order Test <gen> (ignoring conditions)
      • Trigger - Run Icons <gen> (ignoring conditions)
      • Trigger - Run Indestructable Doors <gen> (ignoring conditions)
      • Trigger - Run Meet the King Quest <gen> (ignoring conditions)
  • Order Test
    • Events
    • Conditions
    • Actions
      • Unit - Order Archer 0039 <gen> to Attack Archery Target (1) 0041 <gen>
      • Unit - Order Archer 0038 <gen> to Attack Archery Target (1) 0042 <gen>
      • Unit - Order Archer 0037 <gen> to Attack Archery Target (1) 0040 <gen>
      • Unit - Order Peasant 0053 <gen> to Harvest Village Tree Wall 0091 <gen>
      • Unit - Order Peasant 0052 <gen> to Harvest Village Tree Wall 0090 <gen>
      • Unit - Order Peasant 0051 <gen> to Harvest Village Tree Wall 0088 <gen>
      • Unit - Order Peasant 0050 <gen> to Harvest Village Tree Wall 0089 <gen>
      • Unit - Order Peasant 0054 <gen> to Harvest Village Tree Wall 0093 <gen>
      • Unit - Order Peasant 0076 <gen> to Harvest Ashenvale Tree Wall 0348 <gen>
      • Unit - Order Peasant 0075 <gen> to Harvest Ashenvale Tree Wall 0442 <gen>
      • Unit - Order Town Guard 0108 <gen> to Attack Archery Target 0113 <gen>
      • Unit - Order Town Guard 0109 <gen> to Attack Archery Target 0112 <gen>
      • Unit - Order Villager (Female) 0190 <gen> to Patrol To (Center of Patrol 1 <gen>)
      • Unit - Order Villager (Female) 0188 <gen> to Patrol To (Center of Patrol 4 <gen>)
      • Unit - Order Child 0197 <gen> to Patrol To (Center of Patrol 2 <gen>)
      • Unit - Order Child (2) 0196 <gen> to Patrol To (Center of Patrol 5 <gen>)
      • Unit - Order Villager (Male 2) 0194 <gen> to Patrol To (Center of Patrol 3 <gen>)
also a way that you could do the stat bonus what I did for my map was have 100 levels for stat bonus make them all auto fill levels, level factor 1.5 and in the end I ended up with 7.5k at max level idk if that would work for you but it does for me and I made it so that it skips every 5 levels so you can just be overpowered early
 
Level 14
Joined
Dec 29, 2009
Messages
931
Oh okay, that makes sense. Yeah I might try that.

As for the abilities; I'm going to preload an invisible DebugHero while the map is loading,
so that the delay will be there rather than in-game, and should be less extensive.
Also, the level skip is 0 mainly because the abilities automatically reset themselves (meaning you cannot ever go past level 1).
The hero abilities are just used for gaining stats, but so you don't lose any attribute points, there has to be 1500 possible levels total (150 x 10 points per level).

The stat bonus isn't like the attribute bonus ability, but rather it adds the specific stat to the hero when you learn that ability. You know what I mean, I'm sure. :p
The ability is really just a placeholder for a trigger that activates when you learn it,
and then adds stats to the hero!

Once again, thank you so much..!:)
I'd give rep but I just did earlier.
 
Status
Not open for further replies.
Top