• 🏆 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!

Faction System

GUI Faction system, useful for many styles of maps.

Requirements:
° Unit Indexer (already included on the map);
° UNITDATA Hashtable with all melee player races' unit's attack range stored (You need to add new data of your units to the hashtable)

So this system consists of creating many groups of units owned by the same player and make them threat each other as ally/enemy. For example I have a mercenary camp creeps and a murloc camp creeps, they're both neutral hostile, but I want to make them threat each other as enemies, we set the mercenary camp creeps into one faction, called "Mercenary Camp" and the murloc camp creeps into other faction "Murloc Camp", when they meet each other they will attack themselves as they triggered set to be enemies. This has a great use for huge RPG maps on which have many cities and the user wants one city to be at war with another and yet don't want to spend 2 player slots for them, instead you put all units of one city into a faction, let's say "City #1" and the units from another city into a different faction "City #2".

On this test map we have 4 unit groups and 2 factions: Group1 (Humans) belongs to "The Alliance", Group2 (Night Elves) also belongs to "The Alliance", Group3 (Orcs) and Group4 (Undead) belongs to "The Horde", therefore Group1 and Group2 are enemies of Group3 and Group4 because their factions are enemies. All units are owned by the same player (Player 1). To demonstrate the system, on your map you can make them Neutral Passive or Hostile to save player slots instead of using a Computer Player, for example with this system, on dota we could add 1 player to each team making it 6v6 instead of 5v5 as we would simulate the Sentinel and the Scourge inside Neutral Passive, as the minions and bases could be Neutral Passive and still interact as ally/enemies with players and each other.


How to add unit data to the UNITDATA Hashtable:
  • UNITDATA Hashtable Values
    • Events
    • Conditions
    • Actions
      • -------- PEASANT --------
      • Set UNITDATA_UnitType = Peasant
      • Custom script: set udg_UNITDATA_UnitTypeInteger = udg_UNITDATA_UnitType
      • Hashtable - Save 90 as UNITDATA_ATTACKRANGE of UNITDATA_UnitTypeInteger in UNITDATA_Hash
This will save 90 as the Peasant's attack range on our hashtable.



Pros:
° Nice for working with RPG maps and other projects that needs many factions;
° Number of factions are limited by your imagination;
° Simulates basic unit behavior, (will threat units on other groups as enemies);
° Supports:
* Attack order;
* Attack-Move order;
* Patrol order;
* Hold Position order;
* Stop order;
* Move order.
° Easy to implement, just use the function:
  • Set FACSYS_FactionName[(Custom value of (Triggering unit))] = My Faction
  • Unit Group - Add (Your Unit) to FACSYS_AssignedGroup
Where "My Faction" is replaced by the name of the faction you wish to add the unit to.

Cons:
° No buffs or abilities can be used on it's current state as the factions some times belongs to the same player (abilities won't be able to cast and buffs will also affect units on the enemy group);
° Units can only patrol between 2 points.


Credits:
° @Bribe for he's "Unit Indexer" system.
° @BloodSoul for helping providing the following line of code, on which this system would not be possible:
  • -------- ------------------------- --------
  • -------- We need to use this custom script because there is no "Order unit to patrol unit" function in GUI --------
  • Custom script: call IssueTargetOrderById(udg_FACSYS_Unit[1], 851990, udg_FACSYS_PatrolTarget[udg_FACSYS_TempInteger[1]])
  • -------- ------------------------- --------
  • Readme
    • Events
    • Conditions
    • Actions
      • -------- Hello this is my faction system --------
      • -------- ---------------------------------------- --------
      • -------- First you need to add custom and neutral units that you're going to use into the UNITDATA Hashtable (the trigger is at the "Requirements" folder) --------
      • -------- It is necessary that you use the following functions to add the unit's attack range value into the UNITDATA Hashtable --------
      • -------- Example: --------
      • -------- PEASANT --------
      • Set UNITDATA_UnitType = Peasant
      • Custom script: set udg_UNITDATA_UnitTypeInteger = udg_UNITDATA_UnitType
      • Hashtable - Save 90 as UNITDATA_ATTACKRANGE of UNITDATA_UnitTypeInteger in UNITDATA_Hash
      • -------- This will save 90 as the Peasant's attack range on our hashtable. --------
      • -------- We need this value so that orders like "Hold Position", for example, work correctly. --------
      • -------- ---------------------------------------- --------
      • -------- In order to add a unit to a faction you just need to set the string variable FACSYS_FactionName[Custom value of Unit] = "name of faction" --------
      • -------- Something like this: --------
      • Set FACSYS_FactionName[(Custom value of (Triggering unit))] = My Faction
      • -------- ------- --------
      • -------- But for memory saving reasons we usually do it like this: --------
      • Set FACSYS_Unit[1] = (Triggering unit)
      • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
      • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = My Faction
      • -------- ------- --------
      • -------- ---------------------------------------- --------
      • -------- Now follows an explanation of the setup and how it works --------
      • -------- After configuring the Object Editor data, you just need to set the FACSYS_GroupInteger of an unit to the value corresponding to the faction you want the unit to join --------
      • -------- For example: --------
      • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = The Alliance
      • -------- This will make (Picked unit) join Faction with the name (The Alliance for example) --------
      • -------- If I would set it to (The Horde) for example, then it would be joining The Horde --------
      • -------- --------------------- --------
      • -------- If a unit from one faction meets one from the opposing faction they will behave like normal enemy units would --------
      • -------- But you can set a unit's faction to "Passive" if you wish that unit to have no faction, making them a passive unit --------
      • -------- --------------------- --------
      • -------- First you need to decide what will make a unit join a faction, if it's race, it's owner etc --------
      • -------- Then you set FACSYS_FactionName[Custom value of Your Unit] = The namer of the faction you want the unit to join --------
      • -------- Example: If I want all human units in the map to be part of the alliance I will do the following actions: --------
      • -------- Pick all human units in playable map area --------
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Race of (Picked unit)) Equal to Human
            • Then - Actions
              • -------- -------------------------------------------------------------- --------
              • -------- Here we set the name of the faction the unit belongs to --------
              • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = The Alliance
              • -------- In this case it's the alliance as it's number is set to "The Alliance" --------
            • Else - Actions
      • -------- -------------------------------------------------------------- --------
      • -------- If we want the unit to belong to a specific group inside the faction we just add the unit to the group --------
      • -------- For example: Now we want all human units to join the Human group inside The Alliance --------
      • -------- Again we pick the desired units --------
      • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Race of (Picked unit)) Equal to Human
            • Then - Actions
              • -------- And then add them to the Human group --------
              • Unit Group - Add (Picked unit) to FACSYS_GroupHumans
            • Else - Actions
      • -------- This way if we wish, we can remove all humans from the alliance or make them join another faction --------
      • -------- Like this: --------
      • Unit Group - Pick every unit in FACSYS_GroupHumans and do (Actions)
        • Loop - Actions
          • -------- Clear the unit's faction --------
          • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = Passive
          • -------- Or make them join another --------
          • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = The Horde
      • -------- --------------------- --------
      • -------- You can create new factions, you just need to assign them with a name of your wish --------
      • -------- Same goes for groups, you can create new ones to help identify units belonging to a race, a region (a village or town) or by owning player etc. --------
      • -------- --------------------- --------
      • -------- I think this is all the user should know before getting started, thank you and let me know if you face any issues! --------
  • FACSYS Pre Setup
    • Events
      • Game - UnitIndexEvent becomes Equal to 3.00
    • Conditions
    • Actions
      • Set FACSYS_OrderAttack = (Order(attack))
      • Set FACSYS_OrderHold = (Order(holdposition))
      • Set FACSYS_OrderMove = (Order(move))
      • Set FACSYS_OrderSmart = (Order(smart))
      • Set FACSYS_OrderStop = (Order(stop))
      • Set FACSYS_OrderPatrol = (Order(patrol))
      • Set FACSYS_PERIODIC_TIMEOUT = 0.33
      • Set FACSYS_TRIG_Region = FACSYS Region Actions <gen>
      • Set FACSYS_TRIG_Periodic = FACSYS Periodic Checking <gen>
      • Trigger - Add to FACSYS_TRIG_Periodic the event (Time - Every FACSYS_PERIODIC_TIMEOUT seconds of game time)
  • FACSYS Periodic Checking
    • Events
    • Conditions
    • Actions
      • -------- CHECK FOR NEARBY ENEMIES AND CURRENT ORDERS --------
      • -------- We pick the units on the previously set group so it saves us time and memory --------
      • Unit Group - Pick every unit in FACSYS_AssignedGroup and do (Actions)
        • Loop - Actions
          • Set FACSYS_Unit[1] = (Picked unit)
          • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
          • Set FACSYS_Loc[1] = (Position of FACSYS_Unit[1])
          • Set FACSYS_TempOrder = (Current order of FACSYS_Unit[1])
          • Set FACSYS_TempBool[1] = (FACSYS_Target[FACSYS_TempInteger[1]] is dead)
          • -------- --------------------------------------------- --------
          • -------- UNITDATA Hashtable Functions --------
          • -------- --------------------------------------------- --------
          • Set UNITDATA_UnitType = (Unit-type of FACSYS_Unit[1])
          • Custom script: set udg_UNITDATA_UnitTypeInteger = udg_UNITDATA_UnitType
          • Set FACSYS_TempReal[1] = (Real((Load UNITDATA_ATTACKRANGE of UNITDATA_UnitTypeInteger from UNITDATA_Hash)))
          • -------- --------------------------------------------- --------
          • -------- First we clear unit's target if needed --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_TempBool[1] Equal to True
            • Then - Actions
              • Set FACSYS_Target[FACSYS_TempInteger[1]] = No unit
              • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = False
            • Else - Actions
              • -------- Here we order it to attack it's target if it's alive and the unit isn't attacking, just to make sure. --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempBool[1] Equal to False
                  • FACSYS_TempOrder Not equal to FACSYS_OrderAttack
                • Then - Actions
                  • Unit - Order FACSYS_Unit[1] to Attack FACSYS_Target[FACSYS_TempInteger[1]]
                • Else - Actions
          • -------- Then we check If unit's current order is hold position this function will prevent it from following the target after it leaves it's attack range --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_Target[FACSYS_TempInteger[1]] Not equal to No unit
            • Then - Actions
              • Set FACSYS_Loc[2] = (Position of FACSYS_Target[FACSYS_TempInteger[1]])
              • Set FACSYS_TempReal[2] = (Distance between FACSYS_Loc[1] and FACSYS_Loc[2])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempReal[2] Greater than FACSYS_TempReal[1]
                  • FACSYS_HoldPosition[FACSYS_TempInteger[1]] Equal to True
                • Then - Actions
                  • Set FACSYS_Target[FACSYS_TempInteger[1]] = No unit
                  • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = False
                  • Unit - Order FACSYS_Unit[1] to Hold Position
                • Else - Actions
              • Custom script: call RemoveLocation(udg_FACSYS_Loc[2])
            • Else - Actions
          • -------- -------------------------------------------------------------- --------
          • -------- Here we can check if the unit is stopped and if a enemy is nearby then we order them to fight --------
          • -------- We always check for orders to ensure they are not interrupted --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_IsEngaged[FACSYS_TempInteger[1]] Equal to False
              • FACSYS_TempOrder Not equal to FACSYS_OrderSmart
              • FACSYS_TempOrder Not equal to FACSYS_OrderMove
            • Then - Actions
              • -------- -------------------------------------------------------------- --------
              • -------- Checking units whithin range --------
              • Set FACSYS_TempReal[3] = (Current acquisition range of FACSYS_Unit[1])
              • Set FACSYS_TempReal[4] = (X of FACSYS_Loc[1])
              • Set FACSYS_TempReal[5] = (Y of FACSYS_Loc[1])
              • Custom script: call GroupEnumUnitsInRange(udg_FACSYS_TempGroup, (udg_FACSYS_TempReal[4]), (udg_FACSYS_TempReal[5]), (udg_FACSYS_TempReal[3]), null)
              • Unit Group - Pick every unit in FACSYS_TempGroup and do (Actions)
                • Loop - Actions
                  • Set FACSYS_Unit[2] = (Picked unit)
                  • Set FACSYS_TempBool[2] = (FACSYS_Unit[2] is alive)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_TempBool[2] Equal to True
                    • Then - Actions
                      • Set FACSYS_TempInteger[2] = (Custom value of FACSYS_Unit[2])
                      • Set FACSYS_Loc[2] = (Position of FACSYS_Unit[2])
                      • -------- If the faction number (GroupInteger) differs from one unit to another, they will attack each other --------
                      • -------- The exception is for GroupInteger number 0, which menas the unit is passive and has no faction --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to FACSYS_FactionName[FACSYS_TempInteger[2]]
                          • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to Passive
                          • FACSYS_FactionName[FACSYS_TempInteger[2]] Not equal to Passive
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • FACSYS_HoldPosition[FACSYS_TempInteger[1]] Equal to False
                            • Then - Actions
                              • Unit - Order FACSYS_Unit[1] to Attack FACSYS_Unit[2]
                              • -------- Here we need to set IsEngaged to true so the unit won't be ordered to attack every 0.33 seconds --------
                              • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = True
                              • -------- -------------------------------------------------------------- --------
                              • -------- Defining a specific target --------
                              • Set FACSYS_Target[FACSYS_TempInteger[1]] = FACSYS_Unit[2]
                              • -------- -------------------------------------------------------------- --------
                            • Else - Actions
                              • Set FACSYS_TempReal[2] = (Distance between FACSYS_Loc[1] and FACSYS_Loc[2])
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • FACSYS_HoldPosition[FACSYS_TempInteger[1]] Equal to True
                                  • FACSYS_TempReal[2] Less than or equal to FACSYS_TempReal[1]
                                • Then - Actions
                                  • Unit - Order FACSYS_Unit[1] to Attack FACSYS_Unit[2]
                                  • -------- Here we need to set IsEngaged to true so the unit won't be ordered to attack every 0.33 seconds --------
                                  • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = True
                                  • -------- -------------------------------------------------------------- --------
                                  • -------- Defining a specific target --------
                                  • Set FACSYS_Target[FACSYS_TempInteger[1]] = FACSYS_Unit[2]
                                  • -------- -------------------------------------------------------------- --------
                                • Else - Actions
                        • Else - Actions
                      • Custom script: call RemoveLocation(udg_FACSYS_Loc[2])
                    • Else - Actions
            • Else - Actions
          • -------- ------------------------- --------
          • -------- Then, next we will check for unit stored orders and move on with them if needed --------
          • -------- ------------------------- --------
          • -------- Attack-Move order --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_TempOrder Not equal to FACSYS_OrderAttack
              • FACSYS_TempOrder Not equal to FACSYS_OrderPatrol
              • FACSYS_IsEngaged[FACSYS_TempInteger[1]] Equal to False
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_StoredOrder[FACSYS_TempInteger[1]] Equal to FACSYS_OrderAttack
                • Then - Actions
                  • -------- ------------------------- --------
                  • -------- Here we order the unit to Attack-Move to it's stored location --------
                  • Unit - Order FACSYS_Unit[1] to Attack-Move To FACSYS_Loc1[FACSYS_TempInteger[1]]
                  • -------- ------------------------- --------
                • Else - Actions
                  • -------- Here we will deal with patrol orders --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_StoredOrder[FACSYS_TempInteger[1]] Equal to FACSYS_OrderPatrol
                    • Then - Actions
                      • Set FACSYS_OrderPatrolling[FACSYS_TempInteger[1]] = True
                      • -------- Here we check if unit's patrol orders are towards a friendly unit or a location point --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • FACSYS_PatrolTarget[FACSYS_TempInteger[1]] Not equal to No unit
                        • Then - Actions
                          • -------- ------------------------- --------
                          • -------- We need to use this custom script because there is no "Order unit to patrol unit" function in GUI --------
                          • Custom script: call IssueTargetOrderById(udg_FACSYS_Unit[1], 851990, udg_FACSYS_PatrolTarget[udg_FACSYS_TempInteger[1]])
                          • -------- ------------------------- --------
                        • Else - Actions
                          • -------- ------------------------- --------
                          • -------- Here we check for the nearest Patrol point and order unit to patrol there --------
                          • -------- ------------------------- --------
                          • Set FACSYS_TempReal[6] = (Distance between FACSYS_Loc[1] and FACSYS_Loc[FACSYS_TempInteger[1]])
                          • Set FACSYS_TempReal[7] = (Distance between FACSYS_Loc[1] and FACSYS_Loc1[FACSYS_TempInteger[1]])
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • FACSYS_TempReal[6] Greater than FACSYS_TempReal[7]
                            • Then - Actions
                              • Unit - Order FACSYS_Unit[1] to Attack-Move To FACSYS_Loc[FACSYS_TempInteger[1]]
                            • Else - Actions
                              • Unit - Order FACSYS_Unit[1] to Attack-Move To FACSYS_Loc1[FACSYS_TempInteger[1]]
                          • -------- ------------------------- --------
                          • -------- ------------------------- --------
                    • Else - Actions
            • Else - Actions
          • -------- ------------------------- --------
          • -------- ------------------------- --------
          • -------- ------------------------- --------
          • -------- -------------------------------------------------------------- --------
          • -------- Here we clear location leak --------
          • Custom script: call RemoveLocation(udg_FACSYS_Loc[1])
      • -------- -------------------------- --------
      • -------- -------------------------- --------
  • FACSYS Order Handling
    • Events
      • Unit - A unit Is issued an order targeting an object
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
    • Conditions
    • Actions
      • -------- ------------------------------------------------------------------------------------ --------
      • -------- ------------------------------------------------------------------------------------ --------
      • -------- On this trigger we clear the "fighting state" of a unit so it can obbey orders like move/smart without interference --------
      • -------- ------------------------------------------------------------------------------------ --------
      • -------- ------------------------------------------------------------------------------------ --------
      • Set FACSYS_TempOrder = (Issued order)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • FACSYS_TempOrder Equal to FACSYS_OrderAttack
              • FACSYS_TempOrder Equal to FACSYS_OrderHold
              • FACSYS_TempOrder Equal to FACSYS_OrderMove
              • FACSYS_TempOrder Equal to FACSYS_OrderPatrol
              • FACSYS_TempOrder Equal to FACSYS_OrderSmart
              • FACSYS_TempOrder Equal to FACSYS_OrderStop
        • Then - Actions
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • Set FACSYS_Unit[1] = (Triggering unit)
          • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
          • Set FACSYS_Unit[2] = (Target unit of issued order)
          • Set FACSYS_TempInteger[2] = (Custom value of FACSYS_Unit[2])
          • Set FACSYS_Loc[1] = (Position of FACSYS_Unit[1])
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- Here we check for units being the target of the order or not --------
          • -------- If they are, we set them as the unit's current target --------
          • -------- If not we clear it's target --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_Unit[2] Equal to No unit
            • Then - Actions
              • -------- ---------------------------------- --------
              • -------- Putting unit out of fighting state --------
              • -------- ---------------------------------- --------
              • Set FACSYS_Target[FACSYS_TempInteger[1]] = No unit
              • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = False
              • -------- ---------------------------------- --------
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to FACSYS_FactionName[FACSYS_TempInteger[2]]
                  • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to Passive
                  • FACSYS_FactionName[FACSYS_TempInteger[2]] Not equal to Passive
                • Then - Actions
                  • -------- ---------------------------------- --------
                  • -------- If the target of the order is a unit then we set it as the unit's target --------
                  • -------- ---------------------------------- --------
                  • Set FACSYS_Target[FACSYS_TempInteger[1]] = (Target unit of issued order)
                  • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = True
                  • -------- ------------------------------------- --------
                • Else - Actions
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- Next we will deal with Hold Position Order --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_TempOrder Equal to FACSYS_OrderHold
            • Then - Actions
              • Set FACSYS_HoldPosition[FACSYS_TempInteger[1]] = True
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_HoldPosition[FACSYS_TempInteger[1]] Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_IsEngaged[FACSYS_TempInteger[1]] Equal to False
                    • Then - Actions
                      • Set FACSYS_HoldPosition[FACSYS_TempInteger[1]] = False
                    • Else - Actions
                • Else - Actions
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- Here we will handle Attack-Move and Patrol orders accordindly --------
          • -------- This system simulates patrols through attack-move orders from one point to the other --------
          • -------- So in order to make it work correctly we will need to set a boolean to define if a Attack-Move comes from a patrol order or if it is a legit Attack-Move order --------
          • -------- First we check to see if the current order of the unit is attack and if it's not patrolling --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • FACSYS_TempOrder Equal to FACSYS_OrderAttack
                  • FACSYS_TempOrder Equal to FACSYS_OrderPatrol
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempOrder Equal to FACSYS_OrderAttack
                  • FACSYS_OrderPatrolling[FACSYS_TempInteger[1]] Equal to False
                  • FACSYS_Unit[2] Equal to No unit
                • Then - Actions
                  • -------- ---------------------------------- --------
                  • -------- We need to set the Stored order so we can relate to it properly on the periodic trigger --------
                  • -------- ---------------------------------- --------
                  • Set FACSYS_StoredOrder[FACSYS_TempInteger[1]] = FACSYS_TempOrder
                  • -------- ---------------------------------- --------
                  • -------- ---------------------------------- --------
                  • -------- Here we set the attack-move order position --------
                  • -------- ---------------------------------- --------
                  • Set FACSYS_Loc1[FACSYS_TempInteger[1]] = (Target point of issued order)
                  • -------- ---------------------------------- --------
                  • -------- Then we create ar region on which when the unit enters the orders and leaks are removed --------
                  • -------- ---------------------------------- --------
                  • Set FACSYS_TempRegion[FACSYS_TempInteger[1]] = (Region centered at FACSYS_Loc1[FACSYS_TempInteger[1]] with size (512.00, 512.00))
                  • -------- ---------------------------------- --------
                  • -------- Add the region to a event on the Region trigger --------
                  • -------- ---------------------------------- --------
                  • Trigger - Add to FACSYS_TRIG_Region the event (Unit - A unit enters FACSYS_TempRegion[FACSYS_TempInteger[1]])
                  • -------- ---------------------------------- --------
                • Else - Actions
                  • -------- Here we check for Patrol order --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_TempOrder Equal to FACSYS_OrderPatrol
                    • Then - Actions
                      • -------- ---------------------------------- --------
                      • -------- We need to set the Stored order so we can relate to it properly on the periodic trigger --------
                      • -------- ---------------------------------- --------
                      • Set FACSYS_StoredOrder[FACSYS_TempInteger[1]] = FACSYS_TempOrder
                      • -------- ---------------------------------- --------
                      • -------- ---------------------------------- --------
                      • -------- Defining the points on which the unit will patrol --------
                      • -------- ---------------------------------- --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • FACSYS_Unit[2] Equal to No unit
                        • Then - Actions
                          • -------- ---------------------------------- --------
                          • -------- ---------------------------------- --------
                          • -------- If the target of the patrol order is a location point we set 2 location on which the unit will patrol --------
                          • -------- ---------------------------------- --------
                          • -------- ---------------------------------- --------
                          • Set FACSYS_Loc[FACSYS_TempInteger[1]] = (Position of FACSYS_Unit[1])
                          • Set FACSYS_Loc1[FACSYS_TempInteger[1]] = (Target point of issued order)
                          • -------- ---------------------------------- --------
                          • -------- ---------------------------------- --------
                        • Else - Actions
                          • -------- ---------------------------------- --------
                          • -------- Here we will check, if the target is a friendly unit then we will set it as the PatrolTarget --------
                          • -------- ---------------------------------- --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • Or - Any (Conditions) are true
                                • Conditions
                                  • FACSYS_FactionName[FACSYS_TempInteger[1]] Equal to FACSYS_FactionName[FACSYS_TempInteger[2]]
                                  • FACSYS_FactionName[FACSYS_TempInteger[1]] Equal to Passive
                                  • FACSYS_FactionName[FACSYS_TempInteger[2]] Equal to Passive
                            • Then - Actions
                              • -------- ---------------------------------- --------
                              • Set FACSYS_PatrolTarget[FACSYS_TempInteger[1]] = FACSYS_Unit[2]
                              • -------- ---------------------------------- --------
                            • Else - Actions
                              • -------- ---------------------------------- --------
                              • -------- If the unit is a enemy we set the patrol point to the position of the unit --------
                              • -------- ---------------------------------- --------
                              • Set FACSYS_Loc1[FACSYS_TempInteger[1]] = (Position of (Target unit of issued order))
                              • -------- ---------------------------------- --------
                              • -------- ---------------------------------- --------
                          • -------- ---------------------------------- --------
                          • -------- ---------------------------------- --------
                      • -------- ---------------------------------- --------
                      • -------- Creating regions to detect when the unit has reached one point of it's patrol so it is then ordered to Attack-Move to the other point --------
                      • -------- ---------------------------------- --------
                      • Set FACSYS_TempRegion[FACSYS_TempInteger[1]] = (Region centered at FACSYS_Loc[FACSYS_TempInteger[1]] with size (512.00, 512.00))
                      • Set FACSYS_TempRegion1[FACSYS_TempInteger[1]] = (Region centered at FACSYS_Loc1[FACSYS_TempInteger[FACSYS_TempInteger[1]]] with size (512.00, 512.00))
                      • -------- ---------------------------------- --------
                      • -------- We set the patrolling boolean to true so we can differ from Attack-Move and simulated Patrol --------
                      • -------- ---------------------------------- --------
                      • Set FACSYS_OrderPatrolling[FACSYS_TempInteger[1]] = True
                      • -------- ---------------------------------- --------
                      • -------- Add the regions to a event on the Region trigger --------
                      • -------- ---------------------------------- --------
                      • Trigger - Add to FACSYS_TRIG_Region the event (Unit - A unit enters FACSYS_TempRegion[FACSYS_TempInteger[1]])
                      • Trigger - Add to FACSYS_TRIG_Region the event (Unit - A unit enters FACSYS_TempRegion1[FACSYS_TempInteger[1]])
                      • -------- ---------------------------------- --------
                    • Else - Actions
            • Else - Actions
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- On the next stage of this trigger we will be running cleaning actions --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • -------- First we check for possible movment and guard orders --------
          • -------- ---------------------------------- --------
          • -------- ---------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • FACSYS_TempOrder Equal to FACSYS_OrderHold
                  • FACSYS_TempOrder Equal to FACSYS_OrderMove
                  • FACSYS_TempOrder Equal to FACSYS_OrderSmart
                  • FACSYS_TempOrder Equal to FACSYS_OrderStop
                  • And - All (Conditions) are true
                    • Conditions
                      • FACSYS_TempOrder Equal to FACSYS_OrderAttack
                      • FACSYS_Unit[2] Not equal to No unit
                      • FACSYS_TempOrder Equal to FACSYS_OrderOutside[FACSYS_TempInteger[1]]
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempOrder Equal to FACSYS_OrderSmart
                  • FACSYS_Unit[2] Not equal to No unit
                • Then - Actions
                  • -------- ---------------------------------------------------- --------
                  • -------- Here we check for right clicks of a unit from one faction to another --------
                  • -------- ---------------------------------------------------- --------
                  • Set FACSYS_Unit[1] = (Triggering unit)
                  • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
                  • Set FACSYS_TempInteger[2] = (Custom value of FACSYS_Unit[2])
                  • -------- ---------------------------------------------------- --------
                  • -------- ---------------------------------------------------- --------
                  • -------- Faction Checking --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to FACSYS_FactionName[FACSYS_TempInteger[2]]
                      • FACSYS_FactionName[FACSYS_TempInteger[1]] Not equal to Passive
                      • FACSYS_FactionName[FACSYS_TempInteger[2]] Not equal to Passive
                    • Then - Actions
                      • -------- We turn the "smart" order into "attack" --------
                      • Set FACSYS_HoldPosition[FACSYS_TempInteger[1]] = False
                      • Unit - Order FACSYS_Unit[1] to Attack FACSYS_Unit[2]
                      • -------- ---------------------------------------------------- --------
                      • -------- Setting variables so after we can perform target cleaning --------
                      • -------- FACSYS_Target means the current target of the unit --------
                      • Set FACSYS_Target[FACSYS_TempInteger[1]] = FACSYS_Unit[2]
                      • -------- FACSYS_IsEngaged menas that the unit is in combat --------
                      • Set FACSYS_IsEngaged[FACSYS_TempInteger[1]] = True
                      • -------- ---------------------------------------------------- --------
                    • Else - Actions
                  • -------- ---------------------------------------------------- --------
                  • -------- ---------------------------------------------------- --------
                • Else - Actions
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
              • -------- Here we clean the attack-move specific order if the unit is ordered to attack --------
              • -------- We will use a Order variable called OrderOutside, which means it's an order given by the user --------
              • -------- All attack unit orders triggered by the user should be stored on OrderOutside so we can know if the order was given by the user --------
              • -------- Because if it's not a order given by the user then the system should't be interrupted --------
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
              • -------- Then we null all actions and variables reffering to attack-move and patrol --------
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
              • Set FACSYS_TempString = <Empty String>
              • Set FACSYS_StoredOrder[FACSYS_TempInteger[1]] = (Order(FACSYS_TempString))
              • Set FACSYS_PatrolTarget[FACSYS_TempInteger[1]] = No unit
              • Custom script: call RemoveLocation (udg_FACSYS_Loc[udg_FACSYS_TempInteger[1]])
              • Custom script: call RemoveLocation (udg_FACSYS_Loc1[udg_FACSYS_TempInteger[1]])
              • Custom script: call RemoveRect(udg_FACSYS_TempRegion[udg_FACSYS_TempInteger[1]])
              • Custom script: call RemoveRect(udg_FACSYS_TempRegion1[udg_FACSYS_TempInteger[1]])
              • -------- ---------------------------------- --------
              • -------- ---------------------------------- --------
            • Else - Actions
          • Custom script: call RemoveLocation (udg_FACSYS_Loc[1])
          • -------- Removing Leaks --------
        • Else - Actions
      • -------- ---------------------------------- --------
      • -------- ---------------------------------- --------
  • FACSYS Region Actions
    • Events
    • Conditions
    • Actions
      • -------- ---------------------------------- --------
      • -------- On this trigger we will be dealing with actions reffering to the regions created by Attack-Move and Patrol orders --------
      • -------- ---------------------------------- --------
      • Set FACSYS_Unit[1] = (Triggering unit)
      • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
      • Set FACSYS_Loc[1] = (Position of FACSYS_Unit[1])
      • -------- ---------------------------------- --------
      • -------- ---------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • FACSYS_StoredOrder[FACSYS_TempInteger[1]] Equal to FACSYS_OrderAttack
          • FACSYS_OrderPatrolling[FACSYS_TempInteger[1]] Equal to False
        • Then - Actions
          • -------- ---------------------------------- --------
          • -------- Here we clear the location and order of Attack-Move when the unit gets to the targeted location --------
          • -------- ---------------------------------- --------
          • Set FACSYS_TempString = <Empty String>
          • Custom script: set udg_FACSYS_TempString = null
          • Set FACSYS_StoredOrder[FACSYS_TempInteger[1]] = (Order(FACSYS_TempString))
          • Custom script: call RemoveLocation (udg_FACSYS_Loc1[udg_FACSYS_TempInteger[1]])
          • -------- ---------------------------------- --------
        • Else - Actions
          • -------- ---------------------------------- --------
          • -------- Next we deal with Patrol order and Location handling --------
          • -------- ---------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_StoredOrder[FACSYS_TempInteger[1]] Equal to FACSYS_OrderPatrol
              • FACSYS_OrderPatrolling[FACSYS_TempInteger[1]] Equal to True
            • Then - Actions
              • -------- ---------------------------------- --------
              • -------- Unit got to first Patrol location --------
              • -------- ---------------------------------- --------
              • Set FACSYS_TempBool[1] = (FACSYS_TempRegion[FACSYS_TempInteger[1]] contains FACSYS_Loc[1])
              • Set FACSYS_TempBool[2] = (FACSYS_TempRegion1[FACSYS_TempInteger[1]] contains FACSYS_Loc[1])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempBool[1] Equal to True
                • Then - Actions
                  • -------- ---------------------------------- --------
                  • -------- Order it to "Patrol" to the second location --------
                  • -------- ---------------------------------- --------
                  • Unit - Order FACSYS_Unit[1] to Attack-Move To FACSYS_Loc1[FACSYS_TempInteger[1]]
                  • -------- ---------------------------------- --------
                • Else - Actions
                  • -------- ---------------------------------- --------
                  • -------- Unit got to second Patrol location --------
                  • -------- ---------------------------------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • FACSYS_TempBool[2] Equal to True
                    • Then - Actions
                      • -------- ---------------------------------- --------
                      • -------- Order it to "Patrol" to the first location --------
                      • -------- ---------------------------------- --------
                      • Unit - Order FACSYS_Unit[1] to Attack-Move To FACSYS_Loc[FACSYS_TempInteger[1]]
                      • -------- ---------------------------------- --------
                    • Else - Actions
            • Else - Actions
      • Custom script: call RemoveLocation(udg_FACSYS_Loc[1])

  • FACSYS Demo Setup
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • -------- This is a demo trigger on how to set up a unit's faciton --------
      • Set FACSYS_Unit[1] = UDexUnits[UDex]
      • Set FACSYS_TempInteger[1] = (Custom value of FACSYS_Unit[1])
      • Set FACSYS_TempRace[1] = (Race of FACSYS_Unit[1])
      • -------- -------------------------------------------------------------- --------
      • -------- Here we set a boolean to later check if unit has already been assigned to a faction or not, so we don't spend memory picking the same unit --------
      • -------- Add to a overall specific group so we won't have to get units in playable map area as it will cost us memory --------
      • Unit Group - Add FACSYS_Unit[1] to FACSYS_AssignedGroup
      • -------- -------------------------------------------------------------- --------
      • -------- Creating groups and factions --------
      • -------- You can always change the criteria on how the unit will be handled and which faction and group will it join, in this case I choose the race --------
      • -------- Set up for the allaince --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • FACSYS_TempRace[1] Equal to Human
              • FACSYS_TempRace[1] Equal to Night Elf
        • Then - Actions
          • -------- -------------------------------------------------------------- --------
          • -------- Here we set the number of the faction the unit belongs to --------
          • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = The Alliance
          • -------- -------------------------------------------------------------- --------
          • -------- Adding unit to specific group inside faction --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_TempRace[1] Equal to Human
            • Then - Actions
              • Unit Group - Add FACSYS_Unit[1] to FACSYS_GroupHumans
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempRace[1] Equal to Night Elf
                • Then - Actions
                  • Unit Group - Add FACSYS_Unit[1] to FACSYS_GroupNightElfs
                • Else - Actions
          • Unit - Change color of FACSYS_Unit[1] to Blue
        • Else - Actions
      • -------- -------------------------------------------------------------- --------
      • -------- Set up for the horde --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • FACSYS_TempRace[1] Equal to Orc
              • FACSYS_TempRace[1] Equal to Undead
        • Then - Actions
          • -------- -------------------------------------------------------------- --------
          • -------- Here we set the number of the faction the unit belongs to --------
          • Set FACSYS_FactionName[FACSYS_TempInteger[1]] = The Horde
          • -------- -------------------------------------------------------------- --------
          • -------- Adding unit to specific group inside faction --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • FACSYS_TempRace[1] Equal to Orc
            • Then - Actions
              • Unit Group - Add FACSYS_Unit[1] to FACSYS_GroupOrcs
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • FACSYS_TempRace[1] Equal to Undead
                • Then - Actions
                  • Unit Group - Add FACSYS_Unit[1] to FACSYS_GroupUndead
                • Else - Actions
          • Unit - Change color of FACSYS_Unit[1] to Red
          • -------- -------------------------- --------
        • Else - Actions
      • -------- Add to Event Handle the event "unit comes whithin acquisition range of picked unit" --------
      • -------- This event will let us know when the units acquires their targets so we can properly handle it --------
      • -------- -------------------------- --------


Credits: Bribe (Unit Indexer)
Contents

Faction System (Map)

Reviews
KILLCIDE
A fairly simple system that can be useful to users. Unfortunately, this system only supports orders like patrol, smart, hold position, etc. It would be great if the system supported spells and such, but I know that would either be impossible or really...
I'm pretty much lost when I open the map as user - no readme or info that tells me what to do.

Why is one trigger called "debug", it doesn't seem like a debug trigger, but like kind of a demo trigger, but also kind of not.

There are memory leaks.

The name conventions don't follow current standards.

I think the onIndex event should be used to register units, so a unit wont be registered multiple times.

Here are common GUI conventions: [GUI] - GPAG - GUI Proper Application Guide
And here some other nice infos, and link about memory leaks: Spell Submission Rules
 
Level 37
Joined
Jul 22, 2015
Messages
3,485

Needs Fixed

  • You are lacking a proper map description. Your map description should contain the code, credits, and how to import instructions. You should also have the import instructions inside the map
  • Seperate the needed triggers and demo triggers. Since you are lacking a "how to import," it would be really hard to tell what is needed if a user was not experienced
  • Loc2 is only created inside an If block, yet you remove the location outside of it. You should be removing the location inside the same block to prevent the chance of removing a null location
  • With that in mind, you also use Loc2 inside the unit group enumeration. This creates a location leak since you dont remove the first Loc2 reference
  • Loc2 leaks a lot inside that unit group enumeration

Suggestions

  • You call the same function multiple times a lot in your code. I recommend you store these into variables and reference the variable instead (ex: Custom value of a unit)
  • Periodic trigger should be configurable
  • Position of (Picked unit) -> Position of (FACSYS_Unit1)
  • (Position of (Picked unit) -> Position of (FACSYS_Unit2)
  • Matching unit is a really ugly way of filtering units. I recommend you read Convenient Unit Group Filtering in GUI
  • GetUnitsInRangeOfLocAll() has a handle refernce leak that cannot be removed if you use the GUI function

Status

Awaiting Update
 
Level 11
Joined
Oct 9, 2015
Messages
721

Needs Fixed

  • You are lacking a proper map description. Your map description should contain the code, credits, and how to import instructions. You should also have the import instructions inside the map
  • Seperate the needed triggers and demo triggers. Since you are lacking a "how to import," it would be really hard to tell what is needed if a user was not experienced
  • Loc2 is only created inside an If block, yet you remove the location outside of it. You should be removing the location inside the same block to prevent the chance of removing a null location
  • With that in mind, you also use Loc2 inside the unit group enumeration. This creates a location leak since you dont remove the first Loc2 reference
  • Loc2 leaks a lot inside that unit group enumeration

Suggestions

  • You call the same function multiple times a lot in your code. I recommend you store these into variables and reference the variable instead (ex: Custom value of a unit)
  • Periodic trigger should be configurable
  • Position of (Picked unit) -> Position of (FACSYS_Unit1)
  • (Position of (Picked unit) -> Position of (FACSYS_Unit2)
  • Matching unit is a really ugly way of filtering units. I recommend you read Convenient Unit Group Filtering in GUI
  • GetUnitsInRangeOfLocAll() has a handle refernce leak that cannot be removed if you use the GUI function

Status

Awaiting Update

Needs Fixed
° Added the code into map description
° Separated the needed triggers from the useless
° Loc2 is now removed inside the same block it was added

Suggestions
° Made all functions work with variables and reduced the number of "()" to 0
° I need to know what do you mean configurable on the periodic trigger, please.
° Corrected Locations putting them into variables to reffer later
° Corrected Matching Unit issue
° Corrected "Units within range issue", now it uses:
  • Unit Group Correction
    • Events
    • Conditions
    • Actions
      • Set FACSYS_TempReal = (Current acquisition range of FACSYS_Unit1)
      • Set FACSYS_TempGroup = (Units within FACSYS_TempReal of FACSYS_Loc1)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in FACSYS_TempGroup and do (Actions)
        • Loop - Actions
          • -------- Actions --------
 
Level 5
Joined
May 2, 2015
Messages
109
I need to know what do you mean configurable on the periodic trigger, please.
Maybe the 0.33s interval and the trigger constants should be configurable.

° Corrected "Units within range issue", now it uses:
I don't think the tempGroup is necessary when
  • Custom script: set bj_wantDestroyGroup = true
exists.
It should be like this,
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within FACSYS_TempReal of FACSYS_Loc1) and do (Actions)
    • Loop - Actions
    • -------- Actions --------
 
Last edited:
Level 11
Joined
Oct 9, 2015
Messages
721
Maybe the 0.33s interval and the trigger constants should be configurable.


I don't think the tempGroup is necessary when
  • Custom script: set bj_wantDestroyGroup = true
exists.
It should be like this,
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within FACSYS_TempReal of FACSYS_Loc1) and do (Actions)
    • Loop - Actions
    • -------- Actions --------
Thanks for pointing that out, but it's always good to minimize the number of "()" present in actions. By the way what do you think about the system ?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485

Needs Fixed

  • TempGroup leaks. set bj_wantDestroyGroup = true needs to be before the unit group is created

Suggestions

  • In FACSYS Faction Setup, you store the custom value of the triggering unit into a variable, but you don't use it
  • Periodic timeout should be configurable
  • Why do you compare the custom value of a unit to the distance to it's target?
  • You can store the current order of the unit into a variable instead of constantly calling the function
  • Instead of converting the string orders into regular orders all the time, you can just store them into global variables and reference them when you need to
  • Units within range has a handle reference leak

Status

Awaiting Update
 
Level 11
Joined
Oct 9, 2015
Messages
721
Suggestions:
° In FACSYS Faction Setup I use it (FACSYS_TempInteger) to set the "GroupInteger" variable of the unit itself throught the TempInteger, which is set on the begining of the trigger
  • Set FACSYS_GroupInteger[FACSYS_TempInteger] = 1
° The issue with custom value of unit has been corrected and set to "point value" of unit, you need to change the point value of all units you're going to use, in the object editor change the value of the point value of unit to be equal to it's attack range (as described on the instructions).
° "Current order" have been stored
° I don't know if it solves the "Units whithing range" leak problem but I'm now using
  • Set FACSYS_TempReal = (Current acquisition range of FACSYS_Unit1)
  • Set FACSYS_TempGroup = (Units within FACSYS_TempReal of FACSYS_Loc1)
  • Unit Group - Pick every unit in FACSYS_TempGroup and do (Actions)
    • Loop - Actions
      • -------- Actions --------
  • Custom script: call DestroyGroup(udg_FACSYS_TempGroup)
Questions:
1) How can I make periodic timeout be configurable?
2) How can I fix the handle reference leak from "Units within range" ?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
In FACSYS Faction Setup I use it (FACSYS_TempInteger) to set the "GroupInteger" variable of the unit itself throught the TempInteger, which is set on the begining of the trigger
This line -> Set FACSYS_Grouped[(Custom value of FACSYS_Unit1)] = True

1) How can I make periodic timeout be configurable?
Just make a real variable called PERIODIC_TIMEOUT or something in the setup trigger or a config trigger. Afterwards, use the "Add New Event" function

2) How can I fix the handle reference leak from "Units within range" ?
You don't have to fix it. It's just something I like to point out. If you really want to try to fix it, you have to use GroupEnumUnitsInRange() or GroupEnumUnitsInRect()
 
Level 11
Joined
Oct 9, 2015
Messages
721
This line -> Set FACSYS_Grouped[(Custom value of FACSYS_Unit1)] = True
Fixed, now it uses
  • Set FACSYS_Grouped[FACSYS_TempInteger] = True
Just make a real variable called PERIODIC_TIMEOUT or something in the setup trigger or a config trigger. Afterwards, use the "Add New Event" function
Fixed, now the value is pre-set on another trigger
You don't have to fix it. It's just something I like to point out. If you really want to try to fix it, you have to use
GroupEnumUnitsInRange()
or
GroupEnumUnitsInRect()
Fixed, now I'm using the function
Code:
GroupEnumUnitsInRange()
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Fixed, now I'm using the function
Ermm I said that units within range leaks, but youre still using it. Actually, now that I look at it, you fill your group up using Units within range, and then you fill it again using GroupEnumUnitsInRange lol. Regardless, this is a tiny issue. I'll review this sometime this weekend.
 
Level 11
Joined
Oct 9, 2015
Messages
721
Ok, so now I'm using the following code for that specific action.
  • New
    • Events
    • Conditions
    • Actions
      • -------- -------------------------------------------------------------- --------
      • -------- Checking units whithin range --------
      • Set FACSYS_TempGroup = (Units in (Playable map area))
      • Set FACSYS_TempReal2 = (Current acquisition range of FACSYS_Unit1)
      • Set FACSYS_TempReal3 = (X of FACSYS_Loc1)
      • Set FACSYS_TempReal4 = (Y of FACSYS_Loc1)
      • Custom script: call GroupEnumUnitsInRange(udg_FACSYS_TempGroup, (udg_FACSYS_TempReal3), (udg_FACSYS_TempReal4), (udg_FACSYS_TempReal2), null)
      • Unit Group - Pick every unit in FACSYS_TempGroup and do (Actions)
        • Loop - Actions
          • -------- ACTIONS --------
      • Custom script: call DestroyGroup(udg_FACSYS_TempGroup)
Appearently if I don't set the "FACSYS_TempGroup" var before this action, nothing will happen and no unit will be picked in TempGroup.
 
Level 7
Joined
Mar 10, 2013
Messages
366
Very nice system, I really liked the idea, it sure would come in handy in a lot of situations.

Just two things I want to point out:
1. Why you're using the Value-Point of the units to check it's Attack Range? Isn't there a better method? This 'pre-configuration' sure would waste alot of time if you have alot of unit types to work with.
2. Fix your description, it's treat not threat.
 
Level 11
Joined
Oct 9, 2015
Messages
721
Very nice system, I really liked the idea, it sure would come in handy in a lot of situations.

Just two things I want to point out:
1. Why you're using the Value-Point of the units to check it's Attack Range? Isn't there a better method? This 'pre-configuration' sure would waste alot of time if you have alot of unit types to work with.
2. Fix your description, it's treat not threat.
I need to use the point value because I could't find a way to get a unit's attack range on a trigger
 
Level 37
Joined
Jul 22, 2015
Messages
3,485

Needs Fixed

  • Why are you filling TempGroup with every unit in the map, and then filling it with units in the area, AND then filtering them out?
    • Set FACSYS_TempGroup = (Units in (Playable map area))
    • Custom script: call GroupEnumUnitsInRange(udg_FACSYS_TempGroup, (udg_FACSYS_TempReal3), (udg_FACSYS_TempReal4), (udg_FACSYS_TempReal2), null)

Suggestions

  • Use the Index event provided by Bribe to catch when a unit enters a map
  • Elapsed game time is 0.00 seconds -> Map Initialization
  • Set FACSYS_Loc2 = (Position of (Picked unit)) -> (Position of FACSYS_Unit2)
  • It's really pointless to be constantly storing variables like Order(holdposition), Order(stop), and Order(smart) whenever an event occurs. Store them into global variables on map init and reference them instead
  • You don't have to empty a group before destroying it

Status

Awaiting Update
 
Level 11
Joined
Oct 9, 2015
Messages
721
Why are you filling TempGroup with every unit in the map, and then filling it with units in the area, AND then filtering them out?
  • set.gif
    Set FACSYS_TempGroup = (Units in (Playable map area))
  • page.gif
    Custom script: call GroupEnumUnitsInRange(udg_FACSYS_TempGroup, (udg_FACSYS_TempReal3), (udg_FACSYS_TempReal4), (udg_FACSYS_TempReal2), null)
Fixed TempGroup issue, now it uses a permanent group on which all units are removed after usage

Set FACSYS_Loc2 = (Position of (Picked unit)) -> (Position of FACSYS_Unit2)
FACSYS_Loc2 now is set to Position of FACSYS_Unit2
 
Level 37
Joined
Jul 22, 2015
Messages
3,485

Needs Fixed

  • Use the index event of the Unit Indexer instead of "A unit enters (Playable map area)." There is a possibility that when users import this into their map, the Faction Setup will run before the unit is actually indexed

Suggestions

  • Elapsed game time is 0.00 seconds -> Map Initilization
  • I don't know how many times I have to tell this to you, but STORE constant orders (holdposition, stop, smart, attack, etc) into global variables instead of storing it every timeout or ever event run...
  • You don't have to empty a group before destroying it

Status

Awaiting Update
 
Level 18
Joined
Nov 21, 2012
Messages
835
Very nice idea! Is this system limited to 2 factions or there may be more?

I just tested demo map, and found a bug: if you make a ghoul enemy of other ghouls and abomination - they start to fight, then when make this ghoul back allied, he stops, but other ghouls continue attacking.
I think @KILLCIDE suggests something like this
  • Created
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
    • Conditions
      • FACSYS_Grouped[UDex] Equal to False
    • Actions
      • Set FACSYS_Unit1 = UDexUnits[UDex]
Also please consider upgrade from Unit Indexer to "Unit Event" by Bribe
GUI Unit Event v2.2.1.0
 
Last edited:
Level 11
Joined
Oct 9, 2015
Messages
721
Very nice idea! Is this system limited to 2 factions or there may be more?
The number of factions that can be used on the same player for this system is limited only by the warcraft engine (8190 or something).
I just tested demo map, and found a bug: if you make a ghoul enemy of other ghouls and abomination - they start to fight, then when make this ghoul back allied, he stops, but other ghouls continue attacking.
This is caused because I didn't added a "stop" action on the demo triggers. I will add the "Issue unit to stop" action on the triggers of the Demo category when I upload next, thanks for pointing that out!
I just tested demo map, and found a bug: if you make a ghoul enemy of other ghouls and abomination - they start to fight, then when make this ghoul back allied, he stops, but other ghouls continue attacking.
I think @KILLCIDE suggests something like this
  • base.gif
    Created
    • joinminus.gif
      events.gif
      Events
      • line.gif
        joinbottom.gif
        game.gif
        Game - UnitIndexEvent becomes Equal to 1.00
    • joinminus.gif
      cond.gif
      Conditions
      • line.gif
        joinbottom.gif
        if.gif
        FACSYS_Grouped[UDex] Equal to False
    • joinbottomminus.gif
      actions.gif
      Actions
      • empty.gif
        joinbottom.gif
        set.gif
        Set FACSYS_Unit1 = UDexUnits[UDex]
I got it, it's working now! (I tried doing it before with no success, thansk for writing it for me!
Also please consider upgrade from Unit Indexer to "Unit Event" by Bribe
GUI Unit Event v2.2.1.0
Can you please tell me what's the difference between them?
 
Level 18
Joined
Nov 21, 2012
Messages
835
Why did I do this? Simplification and efficiency. The current code for Unit Event is about half of what the combined length of the old Unit Event and Unit Indexer were.
I made some big improvements, as well:

UnitIndexEvent Becomes Equal to 2.00 now fires the instant the unit is removed, not after an arbitrary amount of time. It also does not bug when a paused unit is removed from a transport, so I no longer need a timer to detect when they are unloaded.

I also no longer need a timer to detect when a corpse is unloaded from a transport, as I am now using Jesus4Lyf's "enter region" trick to detect when those are unloaded.

I just thought about order attack to unit who is channeling a spell. You may want to not interrupt spells like Starfall, tranquility etc, but you have to track units for 'begin casting / stop casting ability' and set a bolean flag for each unit, but thats up to you if you want to implement such a thing :)
 
Level 11
Joined
Oct 9, 2015
Messages
721
Needs Fixed
  • Use the index event of the Unit Indexer instead of "A unit enters (Playable map area)." There is a possibility that when users import this into their map, the Faction Setup will run before the unit is actually indexed
It now used the events provided from the Unit Indexer.

Suggestions
  • Elapsed game time is 0.00 seconds -> Map Initilization
It now uses the Unit Indexer event instead of "Elapsed game time is 0.00 seconds" and "Map Initialization"
I don't know how many times I have to tell this to you, but STORE constant orders (holdposition, stop, smart, attack, etc) into global variables instead of storing it every timeout or ever event run...
I've pré-set all the order variables in the "FACSYS Pre Setup trigger".
You don't have to empty a group before destroying it
The group isnt being destroyed at all, now I'm using a Permanent Group for the "FACSYS Periodic Checking" trigger.
 
Last edited:
Level 18
Joined
Nov 21, 2012
Messages
835
8100 FACSYS_Target_Cleaning groups is not acceptable in my opinion, its better to create / destroy groups dynamically
also make optimalization like (cut some ITE):
  • FACSYS Order Check Copy
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Issued order) Equal to FACSYS_OrderSmart
      • (Target unit of issued order) Not equal to No unit
    • Actions
better to check some conditions instead of running actions each time any unit is issued order
good luck:)
 
Level 11
Joined
Oct 9, 2015
Messages
721
8100 FACSYS_Target_Cleaning groups is not acceptable in my opinion, its better to create / destroy groups dynamically
also make optimalization like (cut some ITE):
  • FACSYS Order Check Copy
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Issued order) Equal to FACSYS_OrderSmart
      • (Target unit of issued order) Not equal to No unit
    • Actions
better to check some conditions instead of running actions each time any unit is issued order
good luck:)

Fixed the 8100 groups problem, now it is created and destroyed dynamically:
  • Custom script: set udg_FACSYS_Target_Cleaning[udg_FACSYS_TempInteger] = CreateGroup()
  • Unit Group - Add FACSYS_Unit1 to FACSYS_Target_Cleaning[FACSYS_TempInteger]
  • Custom script: call DestroyGroup(udg_FACSYS_Target_Cleaning[udg_FACSYS_TempInteger])
Updated the Order Check trigger and reduced actions taken:
  • FACSYS Order Check
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
    • Actions
      • Set FACSYS_TempOrder = (Issued order)
      • Set FACSYS_Unit2 = (Target unit of issued order)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • FACSYS_TempOrder Equal to FACSYS_OrderSmart
          • FACSYS_Unit2 Not equal to No unit
        • Then - Actions
          • -------- ACTIONS --------
        • Else - Actions
Thanks for pointing that out, you've been very helpful!

I also fixed some "holdposition" order issues and removed a few useless lines, it will work as it should now.
 
Level 11
Joined
Oct 9, 2015
Messages
721
yeah but there the user have only 2 factions to work with, what if he needs more? let's say a RPG map with 30 towns, then the user can make every town have it's own faction: 30 factions across de map. If you wish you can work with neutral hostile, but then you would need to setup player alliances between players and hostiles or the hostile units would auto-attack player units.
 
Level 11
Joined
Oct 9, 2015
Messages
721
Needs Fixed
  • Use the index event of the Unit Indexer instead of "A unit enters (Playable map area)." There is a possibility that when users import this into their map, the Faction Setup will run before the unit is actually indexed
Suggestions
  • Elapsed game time is 0.00 seconds -> Map Initilization
  • I don't know how many times I have to tell this to you, but STORE constant orders (holdposition, stop, smart, attack, etc) into global variables instead of storing it every timeout or ever event run... -DONE!
  • You don't have to empty a group before destroying it -DONE!

Status
Awaiting Update

° Use the index event of the Unit Indexer instead of "A unit enters (Playable map area)." There is a possibility that when users import this into their map, the Faction Setup will run before the unit is actually indexed - DONE!

° Elapsed game time is 0.00 seconds -> Map Initilization - DONE!
° I don't know how many times I have to tell this to you, but STORE constant orders (holdposition, stop, smart, attack, etc) into global variables instead of storing it every timeout or ever event run... -DONE!
° You don't have to empty a group before destroying it -DONE!


It sounds great, I would need to implement something like this in my map but since it uses point value its incompatible, I use it for map specific purposes.
It now uses UNITDATA_Hashtable instead of point value as the previous version would conflict with many systems and maps!
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
A fairly simple system that can be useful to users. Unfortunately, this system only supports orders like patrol, smart, hold position, etc. It would be great if the system supported spells and such, but I know that would either be impossible or really complicated. Thanks for the well documented code.

Needs Fixed

  • Nothing

Suggestions

  • Include "How to Import" instructions
  • Any triggers you run in the code will be disabled when you import them between maps. I recommend you store the triggers into variables so that it is easier to fix all the disabled actions instead of having to go through the code and re-enable each one.

Status

Approved
 
Level 11
Joined
Oct 9, 2015
Messages
721
It is with great joy that I recieve my first approval on the hive, I want to tell that all Suggestions have also been met on the last file I've sent (after the last review). Thanks a lot @Bribe for your Unit Indexer System, thanks @BloodSoul for the "Patrol Object" JASS function, thanks www.hiveworkshop.com, the staff and all users from the forums who helped in a way or another to achieve it. Thanks, @KILLCIDE for the review. This is for everyone, enjoy!
 
Top