• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[JASS] Prioritizing units with more buffs

Status
Not open for further replies.
Level 12
Joined
May 20, 2009
Messages
822

JASS:
    function BuffBurn_Sorted takes nothing returns nothing
            local integer swapped = 0
            local unit temp
            local integer aindex = 0
            local integer first = 0
            local integer second = 0
            local integer MaxIndex
     
            set MaxIndex = (udg_BBTargetFilterMaxIndex - 1)
     
            // Step 1: sort the array
            loop
                    set aindex = 0
                    set swapped = 0
                    loop
                            exitwhen aindex > MaxIndex
     
                            set first = UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[aindex], false, false)
                            set second = UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[aindex + 1], false, false)
                            if (first < second) then
                                    set swapped = 1
                                    set temp = udg_BBTargetFilterArray[aindex + 1]
                                    set udg_BBTargetFilterArray[aindex + 1] = udg_BBTargetFilterArray[aindex]
                                    set udg_BBTargetFilterArray[aindex] = temp
                            endif
     
                            set aindex = (aindex + 1)
                    endloop
     
                    exitwhen swapped == 0
            endloop
     
            // Step 2: iterate over the array and issue target orders
            set aindex = 0
            loop
               exitwhen aindex > udg_BBTargetFilterMaxIndex
     
               call DisplayTextToForce( GetPlayersAll(), "Targeting unit with " + I2S(UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[aindex], false, false)) + " buffs" )
               call IssueTargetOrderBJ( udg_BBUnit[udg_BBAutoTempInit], "poisonarrowstarg", udg_BBTargetFilterArray[aindex] )
               set aindex = aindex + 1 
               exitwhen true
            endloop
           
    endfunction


My cousin made this code for me, he doesn't have a lot of experience in JASS, and neither do I, so neither of us know if this is the right way to do things.

What this is suppose to do is:

Units in range of the unit that has this spell will be sorted by which one has the most buffs, and then the unit with the spell will be ordered to target that unit (Which would be the unit that have the most buffs).

It only seems to do that sometimes, though...

Can anyone help?
 
Last edited:
Level 1
Joined
May 10, 2014
Messages
1
Correct approach to sending the order(s)

Hi, I'm the cousin. :) I'm a programmer, so I was willing to help with this bit.

BUT, the part where we're both confused is that, in terms of game mechanics, we don't know if the correct way to achieve the goal is to 1) send the targeting order toward JUST the unit with the most buffs, or 2) send targeting orders to ALL the units in range, starting with the one w/ the most buffs, or 3) send the orders to ALL the units, starting with the ones w/ the LEAST buffs, on the idea that the "last order has priority."

Making the code do any of those things is easy. Knowing which one correctly directs the game engine to accomplish the desired goal (target the unit(s) with the most buffs) is the question here, for people who know which approach is actually "right" in terms of how the Warcraft III engine actually works.

So, which way SHOULD it be done? =D
 
Level 12
Joined
May 20, 2009
Messages
822
It kind of is on a periodic timer, like this:

  • BuffBurn AutoCast Calc
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
        • Loop - Actions
          • Set BBTargetFilterMaxIndex = 0
          • Unit Group - Pick every unit in (Units within 700.00 of (Position of BBUnit[BBAutoTempInit])) and do (Actions)
            • Loop - Actions
              • Set BBBuffCount = (Number of Positive buffs considered Magic or physical on (Picked unit) (Exclude expiration timers, Exclude auras))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • BuffBurnAutoCastOn[BBAutoTempInit] Equal to True
                      • BBAttackMove[BBAutoTempInit] Equal to True
                      • ((Picked unit) is alive) Equal to True
                      • ((Picked unit) is A structure) Equal to False
                      • (Picked unit) Not equal to BBUnit[BBAutoTempInit]
                      • ((Owner of (Picked unit)) is an ally of (Owner of BBUnit[BBAutoTempInit])) Equal to False
                      • Or - Any (Conditions) are true
                        • Conditions
                          • ((Owner of (Picked unit)) is an enemy of (Owner of BBUnit[BBAutoTempInit])) Equal to True
                          • (Owner of (Picked unit)) Equal to Neutral Hostile
                • Then - Actions
                  • Set BBTargetFilterArray[BBTargetFilterMaxIndex] = (Picked unit)
                  • Set BBTargetFilterMaxIndex = (BBTargetFilterMaxIndex + 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • BBTargetFilterMaxIndex Greater than 0
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • BBTargetFilterMaxIndex Greater than 1
                        • Then - Actions
                          • Custom script: call BuffBurn_Sorted()
                        • Else - Actions
                          • Unit - Order BBUnit[BBAutoTempInit] to Neutral - Poison Arrows BBTargetFilterArray[0]
                    • Else - Actions
                • Else - Actions
EDIT: I also based the ability being cast off of Poison Arrows.


Okay, so after some more tinkering we finally fixed it. Here you go to anyone that may need help with something like this later:


JASS:
    function BuffBurn_Sorted takes nothing returns nothing
                local integer swapped = 0
                local unit temp
                local integer aindex = 0
                local integer first = 0
                local integer second = 0
                local integer MaxIndex
         
     
                set MaxIndex = (udg_BBTargetFilterMaxIndex - 2)
         
                // Step 1: sort the array
                loop
                        set aindex = 0
                        set swapped = 0
                        loop
                                exitwhen aindex > MaxIndex
         
                                set first = UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[aindex], false, false)
                                set second = UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[aindex + 1], false, false)
                                if (first < second) then
                                        set swapped = 1
                                        set temp = udg_BBTargetFilterArray[aindex + 1]
                                        set udg_BBTargetFilterArray[aindex + 1] = udg_BBTargetFilterArray[aindex]
                                        set udg_BBTargetFilterArray[aindex] = temp
                                endif
         
                                set aindex = (aindex + 1)
                        endloop
         
                        exitwhen swapped == 0
                endloop
         
                // Step 2: iterate over the array and issue target orders
          // call DisplayTextToForce( GetPlayersAll(), "Targeting unit with " + I2S(UnitCountBuffsExBJ(bj_BUFF_POLARITY_POSITIVE, bj_BUFF_RESIST_EITHER, udg_BBTargetFilterArray[0], false, false)) + " buffs" ) //Debug
          //call IssueTargetOrderBJ( udg_BBUnit[udg_BBAutoTempInit], "poisonarrowstarg", udg_BBTargetFilterArray[0] )
     
    endfunction

Code
 endfunction

Paste that in the map-specific coding. You can change the function name if you like.


  • BuffBurn Target Unit
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Unit-type of (Ordered unit)) Equal to Arcane Spell Breaker
    • Actions
      • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ordered unit) Equal to BBUnit[BBAutoTempInit]
              • Or - Any (Conditions) are true
                • Conditions
                  • (Issued order) Equal to (Order(attack))
                  • (Issued order) Equal to (Order(move))
                  • (Issued order) Equal to (Order(smart))
            • Then - Actions
              • Set BBAttackMove[BBAutoTempInit] = False
              • Set BBTargetRange[BBAutoTempInit] = 700.00
            • Else - Actions


  • BuffBurn Target Point
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ordered unit) Equal to BBUnit[BBAutoTempInit]
              • Or - Any (Conditions) are true
                • Conditions
                  • (Issued order) Equal to (Order(attack))
                  • (Issued order) Equal to (Order(patrol))
            • Then - Actions
              • Set BBAttackMove[BBAutoTempInit] = True
              • Set BBTargetRange[BBAutoTempInit] = 700.00
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Ordered unit) Equal to BBUnit[BBAutoTempInit]
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (Issued order) Equal to (Order(move))
                          • (Issued order) Equal to (Order(smart))
                    • Then - Actions
                      • Set BBAttackMove[BBAutoTempInit] = False
                      • Set BBTargetRange[BBAutoTempInit] = 700.00
                    • Else - Actions
                • Else - Actions


  • BuffBurn NoTarget
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
    • Actions
      • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Ordered unit) Equal to BBUnit[BBAutoTempInit]
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Ordered unit)) Equal to Arcane Spell Breaker
                  • Or - Any (Conditions) are true
                    • Conditions
                      • (Issued order) Equal to (Order(holdposition))
                      • (Issued order) Equal to (Order(stop))
                • Then - Actions
                  • Set BBAttackMove[BBAutoTempInit] = True
                  • Set BBTargetRange[BBAutoTempInit] = 700.00
                • Else - Actions
            • Else - Actions
      • Unit Group - Pick every unit in (Units of type Arcane Spell Breaker) and do (Actions)
        • Loop - Actions


  • BuffBurn Idle
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units of type Arcane Spell Breaker) and do (Actions)
        • Loop - Actions
          • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Picked unit) Equal to BBUnit[BBAutoTempInit]
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current order of (Picked unit)) Equal to (Order(none))
                    • Then - Actions
                      • Set BBAttackMove[BBAutoTempInit] = True
                      • Set BBTargetRange[BBAutoTempInit] = 700.00
                    • Else - Actions
                • Else - Actions


  • BuffBurn AutoCast Calc
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • For each (Integer BBAutoTempInit) from 1 to BBAutoMaxIndex, do (Actions)
        • Loop - Actions
          • Set BBTargetFilterMaxIndex = 0
          • Unit Group - Pick every unit in (Units within 700.00 of (Position of BBUnit[BBAutoTempInit])) and do (Actions)
            • Loop - Actions
              • Set BBBuffCount = (Number of Positive buffs considered Magic or physical on (Picked unit) (Exclude expiration timers, Exclude auras))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • BBBuffCount Greater than 0
                      • BuffBurnAutoCastOn[BBAutoTempInit] Equal to True
                      • BBAttackMove[BBAutoTempInit] Equal to True
                      • ((Picked unit) is alive) Equal to True
                      • ((Picked unit) is A structure) Equal to False
                      • (Picked unit) Not equal to BBUnit[BBAutoTempInit]
                      • ((Owner of (Picked unit)) is an ally of (Owner of BBUnit[BBAutoTempInit])) Equal to False
                      • Or - Any (Conditions) are true
                        • Conditions
                          • ((Owner of (Picked unit)) is an enemy of (Owner of BBUnit[BBAutoTempInit])) Equal to True
                          • (Owner of (Picked unit)) Equal to Neutral Hostile
                • Then - Actions
                  • Set BBTargetFilterArray[BBTargetFilterMaxIndex] = (Picked unit)
                  • Set BBTargetFilterMaxIndex = (BBTargetFilterMaxIndex + 1)
                • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • BBTargetFilterMaxIndex Greater than 0
            • Then - Actions
              • Custom script: call BuffBurn_Sorted()
              • Unit - Order BBUnit[BBAutoTempInit] to Neutral - Poison Arrows BBTargetFilterArray[0]
            • Else - Actions
 
Last edited:
Status
Not open for further replies.
Top