A Question about Speed (JASS)

LurkerAspect

Now officially a Super Lurker
Reaction score
118
PREVIEW SUMMARY: Curious about fixing lengthy loops containing many if statements so that they don't run over each other and produce weird things

Hi there :D

The below callback runs through a set of 10 units and compares and tests a lot of things and has multiple outcomes. However, when run, I think the loop is so slow that many loops are being handled at the same time, and it produces the same results on different units.
JASS:
// Everything in CAPS is a private scope global

private function callback takes nothing returns nothing
    local integer i = 0
    local boolean explorerNearby = false
    local boolean demonNearby = false
    local group g = NewGroup() // This jass function uses GroupUtils by Rising_Dusk
    local boolexpr b = null
    local unit exp = null
    local unit dem = null
   
    if TIME_COUNTER >= REWARD_INCREMENT_TIME*NODE_COUNT then // this incrementally increases the gold per second reward
        set TIME_COUNTER = 0
        set REWARD_LEVEL = REWARD_LEVEL+1
        set CURRENT_GOLD_REWARD = CURRENT_GOLD_REWARD+GOLD_CONSTANT_REWARD_INCREMENT
        call Debug("Reward level increased")
    endif
   
   
    loop // The loop in question!
        exitwhen i > NODE_COUNT-1
        set RELEVANT_NODE = NODE<i>
       
        if NODE_OWNER<i> == 1 and NODE_STATE<i> == 1 then // Add a gold-per-second reward to the owning faction
            call ForForce(EXPLORERS,function AddGoldConstantBonus)
        elseif NODE_OWNER<i> == 2 and NODE_STATE<i> == 1 then
            call ForForce(DEMONS,function AddGoldConstantBonus)
        endif
       
       
        if NODE_OWNER<i> == 0 and NODE_STATE<i> == 1 then // check if the node is on
            set b = Filter(function CheckForExplorers)
            call GroupEnumUnitsInRange(g,GetUnitX(NODE<i>),GetUnitY(NODE<i>),CHECK_RANGE,b) // look for members of faction 1
            set exp = FirstOfGroup(g)
            if exp != null then
                set explorerNearby = true
            endif
            call DestroyBoolExpr(b)
            call GroupClear(g)
            set b = Filter(function CheckForDemons)
            call GroupEnumUnitsInRange(g,GetUnitX(NODE<i>),GetUnitY(NODE<i>),CHECK_RANGE,b) // look for members of factions 2
            set dem = FirstOfGroup(g)
            if dem != null then
                set demonNearby = true
            endif
            call DestroyBoolExpr(b)
            call ReleaseGroup(g) // clear (I hope?)
           
            if explorerNearby == true and demonNearby == false then // check the capture state depending on nearby units, then display a counter
                set NODE_SCORE<i> = NODE_SCORE<i>+1
                call SetUnitAnimation(NODE<i>,&quot;stand work&quot;)
                call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|cff00FF00&quot;) // this function uses TextTag by Cohadar
            elseif explorerNearby == false and demonNearby == true then
                set NODE_SCORE<i> = NODE_SCORE<i>-1
                call SetUnitAnimation(NODE<i>,&quot;stand work&quot;)
                call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|cffFF0000&quot;)
            elseif explorerNearby == false and demonNearby == false then
                if NODE_SCORE<i> &gt; 0 then
                    set NODE_SCORE<i> = NODE_SCORE<i>-1
                    call TextTag_Unit(NODE<i>,&quot;+&quot;+I2S(NODE_SCORE<i>),&quot;|c00C0C0C0&quot;)
                elseif NODE_SCORE<i> &lt; 0 then
                    set NODE_SCORE<i> = NODE_SCORE<i>+1
                    call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|c00C0C0C0&quot;)
                endif
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            endif
           
            if NODE_SCORE<i> &gt;= NODE_REQUIRED_SCORE then // check the resulting score and apply a final action
                call SetUnitOwner(NODE<i>,GetOwningPlayer(exp),true)
                call UnitRemoveAbility(NODE<i>,&#039;Avul&#039;)
                call DestroyEffect(AddSpecialEffect(EXPLORER_SUCCESS_SFX,GetUnitX(NODE<i>),GetUnitY(NODE<i>)))
                set NODE_OWNER<i> = 1
                call ForForce(EXPLORERS,function AddInstantGoldBonus)
                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been captured by the Explorers!|r&quot;)
                set NODE_SCORE<i> = 0
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            elseif NODE_SCORE<i> &lt;= (-1)*NODE_REQUIRED_SCORE then
                call SetUnitOwner(NODE<i>,GetOwningPlayer(dem),true)
                call UnitRemoveAbility(NODE<i>,&#039;Avul&#039;)
                call DestroyEffect(AddSpecialEffect(DEMON_SUCCESS_SFX,GetUnitX(NODE<i>),GetUnitY(NODE<i>)))
                set NODE_OWNER<i> = 2
                call ForForce(DEMONS,function AddInstantLumberBonus)
                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been captured by the Demon!|r&quot;)
                set NODE_SCORE<i> = 0
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            endif
            set exp = null
            set dem = null
        endif
        set i = i+1
    endloop
    set NODE_CYCLE = NODE_CYCLE+1
endfunction</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


The most notable result is that when a unit captures a single node, 4-6 are "captured" by his faction as well as the one he actually did capture.

For those who want to look at it, the full scope is below.
JASS:
scope PowerNode initializer init 

globals
    private constant real CHECK_RANGE = 300
    private constant integer NODE_REQUIRED_SCORE = 15
    private constant integer REWARD_INCREMENT_TIME = 300
    private constant integer NODE_COUNT = 10
    private constant integer GOLD_INSTANT_REWARD_BASE = 800
    private constant integer GOLD_INSTANT_REWARD_INCREMENT = 200
    private constant integer LUMBER_INSTANT_REWARD_BASE = 4
    private constant integer LUMBER_INSTANT_REWARD_INCREMENT = 1
    private constant integer GOLD_CONSTANT_REWARD_BASE = 0
    private constant integer GOLD_CONSTANT_REWARD_INCREMENT = 5
    private constant string EXPLORER_SUCCESS_SFX = &quot;Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl&quot;
    private constant string DEMON_SUCCESS_SFX = &quot;Objects\\Spawnmodels\\Undead\\UCancelDeath\\UCancelDeath.mdl&quot;
    private constant string NEUTRALISE_SUCCESS_SFX = &quot;Units\\NightElf\\Wisp\\WispExplode.mdl&quot;
    private constant string ACTIVATE_SFX = &quot;Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl&quot;
   
    private unit array NODE[9]
    private integer array NODE_OWNER[9] // 0 = neutral passive, 1 = explorers, 2 = demons
    private integer array NODE_STATE[9] // 0 = off, 1 = on
    private integer array NODE_SCORE[9] // determines the current capture state of the node. Postive value = explorer ownership, negative = demons
   
    private integer CURRENT_NODE = -1
    private timer TIMER = CreateTimer()
    private integer TIME_COUNTER = 0
    private integer REWARD_LEVEL = 0
    private integer CURRENT_GOLD_REWARD = GOLD_CONSTANT_REWARD_BASE
    private integer ACTIVE_NODES = 0
   
    private unit RELEVANT_NODE = null
   
    private integer DEBUG_COUNTER = 0
   
endglobals

private function AddGoldConstantBonus takes nothing returns nothing
    call PlayerAddGold(GetEnumPlayer(),CURRENT_GOLD_REWARD)
    call TextTag_GoldBounty(RELEVANT_NODE, I2S(CURRENT_GOLD_REWARD), GetEnumPlayer())
endfunction

private function AddInstantGoldBonus takes nothing returns nothing
    call PlayerAddGold(GetEnumPlayer(),GOLD_INSTANT_REWARD_BASE+GOLD_INSTANT_REWARD_INCREMENT*REWARD_LEVEL)
    call TextTag_GoldBounty(RELEVANT_NODE, I2S(GOLD_INSTANT_REWARD_BASE+GOLD_INSTANT_REWARD_INCREMENT*REWARD_LEVEL), GetEnumPlayer())
endfunction

private function AddInstantLumberBonus takes nothing returns nothing
    call PlayerAddLumber(GetEnumPlayer(),LUMBER_INSTANT_REWARD_BASE+LUMBER_INSTANT_REWARD_INCREMENT*REWARD_LEVEL)
    call TextTag_LumberBounty(RELEVANT_NODE, I2S(LUMBER_INSTANT_REWARD_BASE+LUMBER_INSTANT_REWARD_INCREMENT*REWARD_LEVEL), GetEnumPlayer())
endfunction
   
private function CheckForExplorers takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) &gt; 0 and IsUnitExplorer(GetFilterUnit()))
endfunction
   
private function CheckForDemons takes nothing returns boolean
    return (GetWidgetLife(GetFilterUnit()) &gt; 0 and IsUnitDemon(GetFilterUnit()))
endfunction
   

private function callback takes nothing returns nothing
    local integer i = 0
    local boolean explorerNearby = false
    local boolean demonNearby = false
    local group g = NewGroup() // This jass function uses GroupUtils by Rising_Dusk
    local boolexpr b = null
    local unit exp = null
    local unit dem = null
   
    if TIME_COUNTER &gt;= REWARD_INCREMENT_TIME*NODE_COUNT then // this incrementally increases the gold per second reward
        set TIME_COUNTER = 0
        set REWARD_LEVEL = REWARD_LEVEL+1
        set CURRENT_GOLD_REWARD = CURRENT_GOLD_REWARD+GOLD_CONSTANT_REWARD_INCREMENT
        call Debug(&quot;Reward level increased&quot;)
    endif
   
   
    loop // The loop in question!
        exitwhen i &gt; NODE_COUNT-1
        set RELEVANT_NODE = NODE<i>
       
        if NODE_OWNER<i> == 1 and NODE_STATE<i> == 1 then // Add a gold-per-second reward to the owning faction
            call ForForce(EXPLORERS,function AddGoldConstantBonus)
        elseif NODE_OWNER<i> == 2 and NODE_STATE<i> == 1 then
            call ForForce(DEMONS,function AddGoldConstantBonus)
        endif
       
       
        if NODE_OWNER<i> == 0 and NODE_STATE<i> == 1 then // check if the node is on
            set b = Filter(function CheckForExplorers)
            call GroupEnumUnitsInRange(g,GetUnitX(NODE<i>),GetUnitY(NODE<i>),CHECK_RANGE,b) // look for members of faction 1
            set exp = FirstOfGroup(g)
            if exp != null then
                set explorerNearby = true
            endif
            call DestroyBoolExpr(b)
            call GroupClear(g)
            set b = Filter(function CheckForDemons)
            call GroupEnumUnitsInRange(g,GetUnitX(NODE<i>),GetUnitY(NODE<i>),CHECK_RANGE,b) // look for members of factions 2
            set dem = FirstOfGroup(g)
            if dem != null then
                set demonNearby = true
            endif
            call DestroyBoolExpr(b)
            call ReleaseGroup(g) // clear (I hope?)
           
            if explorerNearby == true and demonNearby == false then // check the capture state depending on nearby units, then display a counter
                set NODE_SCORE<i> = NODE_SCORE<i>+1
                call SetUnitAnimation(NODE<i>,&quot;stand work&quot;)
                call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|cff00FF00&quot;) // this function uses TextTag by Cohadar
            elseif explorerNearby == false and demonNearby == true then
                set NODE_SCORE<i> = NODE_SCORE<i>-1
                call SetUnitAnimation(NODE<i>,&quot;stand work&quot;)
                call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|cffFF0000&quot;)
            elseif explorerNearby == false and demonNearby == false then
                if NODE_SCORE<i> &gt; 0 then
                    set NODE_SCORE<i> = NODE_SCORE<i>-1
                    call TextTag_Unit(NODE<i>,&quot;+&quot;+I2S(NODE_SCORE<i>),&quot;|c00C0C0C0&quot;)
                elseif NODE_SCORE<i> &lt; 0 then
                    set NODE_SCORE<i> = NODE_SCORE<i>+1
                    call TextTag_Unit(NODE<i>,I2S(NODE_SCORE<i>),&quot;|c00C0C0C0&quot;)
                endif
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            endif
           
            if NODE_SCORE<i> &gt;= NODE_REQUIRED_SCORE then // check the resulting score and apply a final action
                call SetUnitOwner(NODE<i>,GetOwningPlayer(exp),true)
                call UnitRemoveAbility(NODE<i>,&#039;Avul&#039;)
                call DestroyEffect(AddSpecialEffect(EXPLORER_SUCCESS_SFX,GetUnitX(NODE<i>),GetUnitY(NODE<i>)))
                set NODE_OWNER<i> = 1
                call ForForce(EXPLORERS,function AddInstantGoldBonus)
                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been captured by the Explorers!|r&quot;)
                set NODE_SCORE<i> = 0
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            elseif NODE_SCORE<i> &lt;= (-1)*NODE_REQUIRED_SCORE then
                call SetUnitOwner(NODE<i>,GetOwningPlayer(dem),true)
                call UnitRemoveAbility(NODE<i>,&#039;Avul&#039;)
                call DestroyEffect(AddSpecialEffect(DEMON_SUCCESS_SFX,GetUnitX(NODE<i>),GetUnitY(NODE<i>)))
                set NODE_OWNER<i> = 2
                call ForForce(DEMONS,function AddInstantLumberBonus)
                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been captured by the Demon!|r&quot;)
                set NODE_SCORE<i> = 0
                call SetUnitAnimation(NODE<i>,&quot;stand alternate&quot;)
            endif
            set exp = null
            set dem = null
        endif
        set i = i+1
    endloop
endfunction
           
private function initForces takes nothing returns nothing
    call ForceAddPlayer(EXPLORERS,Player(0))
    call ForceAddPlayer(EXPLORERS,Player(1))
    call ForceAddPlayer(EXPLORERS,Player(2))
    call ForceAddPlayer(EXPLORERS,Player(3))
    call ForceAddPlayer(EXPLORERS,Player(4))
    call ForceAddPlayer(EXPLORERS,Player(5))
    call ForceAddPlayer(EXPLORERS,Player(6))
    call ForceAddPlayer(EXPLORERS,Player(7))
    call ForceAddPlayer(EXPLORERS,Player(8))
    call ForceAddPlayer(EXPLORERS,Player(9))
    call ForceAddPlayer(EXPLORERS,Player(10))
    call ForceAddPlayer(DEMONS,Player(11))
endfunction
           
private function initArrays takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen i &gt; 9
        set NODE_OWNER<i> = 0
        set NODE_STATE<i> = 0
        set NODE_SCORE<i> = 0
        set i = i+1
    endloop
       
    set NODE[0] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint1),GetRectCenterY(gg_rct_CommandPoint1),bj_UNIT_FACING)
    set NODE[1] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint2),GetRectCenterY(gg_rct_CommandPoint2),bj_UNIT_FACING)
    set NODE[2] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint3),GetRectCenterY(gg_rct_CommandPoint3),bj_UNIT_FACING)
    set NODE[3] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint4),GetRectCenterY(gg_rct_CommandPoint4),bj_UNIT_FACING)
    set NODE[4] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint5),GetRectCenterY(gg_rct_CommandPoint5),bj_UNIT_FACING)
    set NODE[5] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint6),GetRectCenterY(gg_rct_CommandPoint6),bj_UNIT_FACING)
    set NODE[6] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint7),GetRectCenterY(gg_rct_CommandPoint7),bj_UNIT_FACING)
    set NODE[7] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint8),GetRectCenterY(gg_rct_CommandPoint8),bj_UNIT_FACING)
    set NODE[8] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint9),GetRectCenterY(gg_rct_CommandPoint9),bj_UNIT_FACING)
    set NODE[9] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint10),GetRectCenterY(gg_rct_CommandPoint10),bj_UNIT_FACING)
   
    //call Debug(&quot;Power node Arrays initialized&quot;)
endfunction

private function CreateNode takes integer i returns nothing
    if i == 0 then
        set NODE[0] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint1),GetRectCenterY(gg_rct_CommandPoint1),bj_UNIT_FACING)
    elseif i == 1 then
        set NODE[1] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint2),GetRectCenterY(gg_rct_CommandPoint2),bj_UNIT_FACING)
    elseif i == 2 then
        set NODE[2] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint3),GetRectCenterY(gg_rct_CommandPoint3),bj_UNIT_FACING)
    elseif i == 3 then
        set NODE[3] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint4),GetRectCenterY(gg_rct_CommandPoint4),bj_UNIT_FACING)
    elseif i == 4 then
        set NODE[4] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint5),GetRectCenterY(gg_rct_CommandPoint5),bj_UNIT_FACING)
    elseif i == 5 then
        set NODE[5] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint6),GetRectCenterY(gg_rct_CommandPoint6),bj_UNIT_FACING)
    elseif i == 6 then
        set NODE[6] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint7),GetRectCenterY(gg_rct_CommandPoint7),bj_UNIT_FACING)
    elseif i == 7 then
        set NODE[7] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint8),GetRectCenterY(gg_rct_CommandPoint8),bj_UNIT_FACING)
    elseif i == 8 then
        set NODE[8] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint9),GetRectCenterY(gg_rct_CommandPoint9),bj_UNIT_FACING)
    elseif i == 9 then
        set NODE[9] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),&#039;o006&#039;,GetRectCenterX(gg_rct_CommandPoint10),GetRectCenterY(gg_rct_CommandPoint10),bj_UNIT_FACING)
    endif
endfunction
       
private function TestNode takes nothing returns nothing
    set NODE_STATE[5] = 1
    call TimerStart(TIMER,1,true,function callback)
endfunction
   
private function DeathActions takes nothing returns nothing
    local integer i = 0
    local boolean nodeRunning = false
    if GetUnitTypeId(GetTriggerUnit()) == &#039;o006&#039; then
        loop
            exitwhen i &gt; NODE_COUNT-1
            if GetTriggerUnit() == NODE<i> then
                call RemoveUnit(NODE<i>)
                call CreateNode(i)
                set NODE_STATE<i> = 0
                set NODE_OWNER<i> = 0
                set ACTIVE_NODES = ACTIVE_NODES-1
                //call Debug(&quot;loop tick = &quot;+I2S(i))
                call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been deactivated!|r&quot;)
                call PingMinimapEx(GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),5,0,128,255,true)
                call DestroyEffect(AddSpecialEffect(NEUTRALISE_SUCCESS_SFX,GetUnitX(NODE<i>),GetUnitY(NODE<i>)))
                //call UnitAddAbility(NODE<i>,&#039;Avul&#039;)
            endif
            set i = i+1
        endloop
       
        if ACTIVE_NODES == 0 then
            call PauseTimer(TIMER)
            call Debug(&quot;The timer was paused&quot;)
        endif
    endif
endfunction
   
public function ActivateNode takes nothing returns nothing
    local integer i = 0
    local integer array rarray
    local integer rcount = 0
    local integer result = 0
    local integer tempRandom = 0
    //local string msg = &quot;Array looks like this: &quot;
    loop
        exitwhen i &gt; NODE_COUNT-1
        set rarray<i> = -1
        set i=i+1
    endloop
    set i = 0
    loop
        exitwhen i &gt; NODE_COUNT-1
        if NODE_STATE<i> == 0 then
            set rarray[rcount] = i
            set rcount = rcount+1
        endif
        set i = i+1
    endloop    
    set tempRandom = GetRandomInt(1,rcount)-1
    //call Debug(&quot;tempRandom = &quot;+I2S(tempRandom))
    set result = rarray[tempRandom]
    //call Debug(&quot;rcount = &quot;+I2S(rcount))
    //call Debug(msg)
    if rcount == 0 then
        call Debug(&quot;Can&#039;t activate any more nodes, they&#039;re all lit :/&quot;)
    elseif result == -1 then
        call Debug(&quot;Result was -1, your system is shit xD&quot;)
    else
        set NODE_STATE[result] = 1
        set NODE_OWNER[result] = 0
        //call Debug(&quot;Activated node: &quot;+I2S(result))
        set ACTIVE_NODES = ACTIVE_NODES+1
        //call CreateNode(result)
        call DisplayTextToForce(bj_FORCE_ALL_PLAYERS,&quot;|cff87ceebA Power Node has been activated!|r&quot;)
        call PingMinimapEx(GetUnitX(NODE[result]),GetUnitY(NODE[result]),5,0,128,255,false)
        call DestroyEffect(AddSpecialEffect(NEUTRALISE_SUCCESS_SFX,GetUnitX(NODE[result]),GetUnitY(NODE[result])))
        call PlaySoundBJ(gg_snd_Warning)
    endif
   
    if ACTIVE_NODES == 1 then
        call TimerStart(TIMER,1/I2R(NODE_COUNT),true,function callback)
        //call Debug(&quot;The timer was started!&quot;)
    endif
endfunction  
   
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(t,Player(0),&quot;-node&quot;,true)
    call TriggerAddAction(t,function ActivateNode)
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(t,function DeathActions)
    set t = null
    call initArrays()
    call initForces()
endfunction

endscope
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


My solution was to reduce the callback interval to 0.1 and address one unit at a time per callback, and use a counter to cycle through the currently checked unit.

If you have a moment to show a rookie coder how things are supposed to work, I'd be really grateful :) it might go a long way to fixing some of my broken and discarded maps!
 

tom_mai78101

The Helper Connoisseur / Ex-MineCraft Host
Staff member
Reaction score
1,667
My solution was to reduce the callback interval to 0.1 and address one unit at a time per callback, and use a counter to cycle through the currently checked unit.

That's basically an "update pool" in the jardon of game programming. You iterate through an array per interval, and calling the update() functions while you're iterating an element.

In each update() function, you normally put in checking conditions and update your variables accordingly to the conditions that were met. It's been so long seeing JASS, but I think it is possible to divide-and-conquer your calls into short functions. Since each unit does something different, try and see if you can separate each unit actions and conditions that are to be called inside a single JASS function.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top