• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Help filtering units in local group, please

Status
Not open for further replies.
Level 4
Joined
Nov 20, 2016
Messages
75
Hey, I'd like to ask for a little help with a spell I'm trying to make. Basically, when a unit kills another unit, I want to give friendly units near the killing unit an ability. I want to do this with local variables because I want to use a "wait" function later and using locals is the only way I know to do this. Problem is, I'm not able to filter out units from the unit group, and I don't know why is not working:
  • Inspire
    • Acontecimientos
      • Unidad - A unit Dies
    • Condiciones
      • (Level of Inspire for (Killing unit)) Mayor que 0
      • (Unit-type of (Killing unit)) Igual a Lord of Reins
    • Acciones
      • Custom script: local unit uh = GetKillingUnit()
      • Custom script: local unit g
      • Custom script: local location p = GetUnitLoc(uh)
      • Custom script: local group G = GetUnitsInRangeOfLocAll(500, p)
      • Custom script: local group G1
      • Custom script: set udg_Inspiring_Unit = uh
      • Custom script: set udg_Inspire_Loc = p
      • Custom script: loop
      • Custom script: set g = FirstOfGroup(G)
      • Custom script: exitwhen g==null
      • Custom script: if IsUnitEnemy(g, GetOwningPlayer(uh))==true or IsUnitType(g, UNIT_TYPE_MECHANICAL) == true or IsUnitType(g, UNIT_TYPE_FLYING) == true or IsUnitType(g, UNIT_TYPE_MAGIC_IMMUNE) == true then
      • Custom script: call GroupRemoveUnit(G,g)
      • Custom script: else
      • Custom script: call GroupAddUnit(G1,g)
      • Custom script: call GroupRemoveUnit(G,g)
      • Custom script: endif
      • Custom script: endloop
      • Custom script: set g = null
      • Custom script: set udg_Inspire_Group = G1
      • Grupo de unidad - Pick every unit in Inspire_Group and do (Actions)
        • Bucle: Acciones
          • Unidad - Add Damage Bonus (Inspire) to (Picked unit)
          • Unidad - Set level of Damage Bonus (Inspire) for (Picked unit) to (Level of Inspire for Inspiring_Unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • Si: Condiciones
              • Or - Any (Conditions) are true
                • Condiciones
                  • ((Picked unit) is Mechanical) Igual a True
                  • ((Picked unit) is Flying Unit) Igual a True
                  • ((Picked unit) is Magic Inmune) Igual a True
            • Entonces: Acciones
              • Grupo de unidad - Remove (Picked unit) from Inspire_Group
            • Otros: Acciones
      • Partida - Display to (All players) the text: (String((Number of units in Inspire_Group)))
The loop starts, but the condition is never met for some reason. Can anybody point me in the right direction to fix this?

P.S.: I know there are leaks, I'll fix them later, when I get the trigger to work.

EDIT: Removed one deactivated function that was in the middle of the code.
 
Last edited:

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
In your loop you have two "ifs" but only one "endif". The trigger should not even compile.
Why not use JASS and timers? Custom scripts are very hard to read and if you are so many of them you might want to use JASS instead.
Keep in mind that the "else" only refers to the last open if-block.
 
Level 4
Joined
Nov 20, 2016
Messages
75
In your loop you have two "ifs" but only one "endif". The trigger should not even compile.
Why not use JASS and timers? Custom scripts are very hard to read and if you are so many of them you might want to use JASS instead.
Keep in mind that the "else" only refers to the last open if-block.

First of all, thank you for replying ^^
oops, one of those "ifs" is deactivated in my map, I copied it and didn't remove it, but is not active.

Because... honestly I don't know how to use them. Is my first map (well, technically I've made other maps before but just putting units and tinkering with the object editor, this is my first map in which I use triggers/code anything, really). I tried reading some tutorials on timers, but I couldn't understand them all that well, I've never learned any coding and everthing in the map is mostly really noobish excepto for imported complex systems (damage detection, knockback systems).

Anyhow, consider that there's only 1 "if". Why does it not work?

Or if you want to try and explain to me how to use timers and JASS you are more than welcome to do so, I'm sure is a more efficient solution, but keep in my mind that I don't know anything about coding (in any language) and I'm mostly just googling how to do stuff in google every 5 min.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,327
instead of local group G1 use local group G1 = CreateGroup().

Leaks: keep in mind to not destroy G1 and p as they are also referenced by your global variables.
Only null these local variables and destroy them later using the global variables when you no longer need them.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
You can filter local groups the same way you filter global groups. You use the ForGroup native and remove units from the group that fail the filter test. Local variable values can be passed to the filter function by using a global as the filter function will not cause the ForGroup call to be interrupted.

The inline approach is to use a destructive group iteration loop and then add units that pass the filter test to a second group. After the loop finishes the second group will contain all units which passed the filter. This might be more efficient in some cases than ForGroup but is almost certainly more ugly/confusing.
 
Level 4
Joined
Nov 20, 2016
Messages
75
You can filter local groups the same way you filter global groups. You use the ForGroup native and remove units from the group that fail the filter test. Local variable values can be passed to the filter function by using a global as the filter function will not cause the ForGroup call to be interrupted.

The inline approach is to use a destructive group iteration loop and then add units that pass the filter test to a second group. After the loop finishes the second group will contain all units which passed the filter. This might be more efficient in some cases than ForGroup but is almost certainly more ugly/confusing.
Thanks for the advice!
 
Status
Not open for further replies.
Top