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

Get closest waypoint - Optimization

Status
Not open for further replies.
Hello, I made this trigger not so long ago where the traveller unit should get to the nearest waypoint unit when the trigger detects that the traveller unit is idle. Unfortunately it is causing lags recently due to massive amounts of traveller units and waypoint units I created (256 WP units, 50 travellers). Is there any way to optimize this so it picks lesser units?

Get closer waypoint units triggers

  • Trave Init Timer
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Countdown Timer - Start Travel_CheckTimer as a Repeating timer that will expire in 2.00 seconds
  • Travel Unit Stopped
    • Events
      • Time - Travel_CheckTimer expires
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Travel_GroupTest and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Current order of (Picked unit)) Equal to (Order(stand down))
              • ((Picked unit) is alive) Equal to True
            • Then - Actions
              • Game - Display to (All players) the text: Traveller is IDLE!
              • Set Travel_IdleUnit = (Picked unit)
              • Trigger - Run Travel Get Nearest Waypoint <gen> (ignoring conditions)
            • Else - Actions
              • Do nothing
  • Travel Get Nearest Waypoint
    • Events
    • Conditions
    • Actions
      • Set Travel_HighestReal = 1000000000.00
      • Set Travel_ClosestWaypointUnit = No unit
      • Set Travel_IdleUnitLoc = (Position of Travel_IdleUnit)
      • -------- - --------
      • For each (Integer A) from 1 to Travel_WaypointUnitCount, do (Actions)
        • Loop - Actions
          • Set Travel_WaypointUnitLoc = (Position of Travel_WaypointUnitArray[(Integer A)])
          • Set Travel_WaypointDistanceReal = (Distance between (Position of Travel_IdleUnit) and Travel_WaypointUnitLoc)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Travel_WaypointDistanceReal Less than Travel_HighestReal
            • Then - Actions
              • Set Travel_HighestReal = (Distance between Travel_IdleUnitLoc and Travel_WaypointUnitLoc)
              • Set Travel_ClosestWaypointUnit = Travel_WaypointUnitArray[(Integer A)]
            • Else - Actions
              • Do nothing
          • Custom script: call RemoveLocation(udg_Travel_WaypointUnitLoc)
      • Custom script: call RemoveLocation(udg_Travel_IdleUnitLoc)
      • Unit - Order Travel_IdleUnit to Move To (Position of Travel_ClosestWaypointUnit)
Creating waypoint units triggers

  • Travel Set Waypoint Units To Regions Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = 0
      • Set Travel_WaypointUnitOwner = Neutral Passive
      • Set Travel_WaypointUnitType = Wisp
      • -------- --------
      • Trigger - Run Travel Set Waypoint Units To Regions Part 1 <gen> (ignoring conditions)
      • Trigger - Run Travel Set Waypoint Units To Regions Part 2 <gen> (ignoring conditions)
      • Trigger - Run Travel Set Waypoint Units To Regions Part 3 <gen> (ignoring conditions)
      • Trigger - Run Travel Set Waypoint Units To Regions Part 4 <gen> (ignoring conditions)
      • Trigger - Run Travel Set Waypoint Units To Regions Part 5 <gen> (ignoring conditions)
      • Trigger - Run Travel Create Waypoint Units To Regions <gen> (ignoring conditions)
  • Travel Set Waypoint Units To Regions Part 1
    • Events
    • Conditions
    • Actions
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 001 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 002 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 003 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 004 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 005 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 006 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 007 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 007 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 008 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 009 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 010 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 011 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 012 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 013 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 014 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 015 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 016 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 017 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 018 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 019 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 020 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 021 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 022 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 023 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 024 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 025 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 026 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 027 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 028 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 029 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 030 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 031 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 032 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 033 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 034 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 035 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 036 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 037 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 038 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 039 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 040 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 041 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 042 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 043 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 044 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 045 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 046 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 047 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 048 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 049 <gen>
      • -------- --------
      • Set Travel_WaypointUnitMaxIndex = (Travel_WaypointUnitMaxIndex + 1)
      • Set Travel_WaypointRegionArray[Travel_WaypointUnitMaxIndex] = Travel Waypoint 050 <gen>
  • This goes up to 210...
  • Travel Create Waypoint Units To Regions
    • Events
    • Conditions
    • Actions
      • Set Travel_WaypointUnitCount = 0
      • For each (Integer A) from 1 to Travel_WaypointUnitMaxIndex, do (Actions)
        • Loop - Actions
          • Set Travel_SpawnPointTemp = (Center of Travel_WaypointRegionArray[Travel_WaypointUnitCount])
          • Set Travel_WaypointUnitCount = (Travel_WaypointUnitCount + 1)
          • Unit - Create 1 Travel_WaypointUnitType for Travel_WaypointUnitOwner at Travel_SpawnPointTemp facing 0.00 degrees
          • Set Travel_WaypointUnitArray[Travel_WaypointUnitCount] = (Last created unit)
          • Unit Group - Add (Last created unit) to Travel_WaypointUnitGroup
          • Unit - Hide (Last created unit)
          • Custom script: call UnitAddAbility(GetLastCreatedUnit(),'Aloc')
          • Custom script: call RemoveLocation(udg_Travel_SpawnPointTemp)
Test part, creating traveller units

  • Travel Spawn Test
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set Travel_SpawnPointTemp = (Center of Travel Waypoint 001 <gen>)
      • Unit - Create 1 Village Civilian - Male for Player 2 (Blue) at (Center of Travel Waypoint 001 <gen>) facing Default building facing degrees
      • Unit Group - Add (Last created unit) to Travel_GroupTest
      • Custom script: call RemoveLocation(udg_Travel_SpawnPointTemp)

There are about 210 triggers similar to this
  • Travel Waypoint 1
    • Events
      • Unit - A unit enters Travel Waypoint 001 <gen>
    • Conditions
    • Actions
      • Set Travel_ChoiceMaxIndex = 0
      • -------- - --------
      • Set Travel_ChoiceMaxIndex = (Travel_ChoiceMaxIndex + 1)
      • Set Travel_WaypointPointArray[Travel_ChoiceMaxIndex] = (Center of Travel Waypoint 002 <gen>)
      • -------- - --------
      • Set Travel_ChoiceMaxIndex = (Travel_ChoiceMaxIndex + 1)
      • Set Travel_WaypointPointArray[Travel_ChoiceMaxIndex] = (Center of Travel Waypoint 004 <gen>)
      • -------- - --------
      • Set Travel_ChoiceMaxIndex = (Travel_ChoiceMaxIndex + 1)
      • Set Travel_WaypointPointArray[Travel_ChoiceMaxIndex] = (Center of Travel Waypoint 006 <gen>)
      • -------- - --------
      • Set Travel_ChoiceMaxIndex = (Travel_ChoiceMaxIndex + 1)
      • Set Travel_WaypointPointArray[Travel_ChoiceMaxIndex] = (Center of Travel Waypoint 008 <gen>)
      • -------- - --------
      • Trigger - Run Travel Actions <gen> (ignoring conditions)
      • -------- - --------
      • For each (Integer A) from 1 to Travel_ChoiceMaxIndex, do (Actions)
        • Loop - Actions
          • Custom script: call RemoveLocation(udg_Travel_WaypointPointArray[udg_Travel_ChoiceMaxIndex])
  • Travel Actions
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Unit-type of (Entering unit)) Not equal to Travel_WaypointUnitType
              • (Owner of (Entering unit)) Not equal to Player 1 (Red)
        • Then - Actions
          • Set Travel_ChoiceRandomizer = (Random integer number between 1 and Travel_ChoiceMaxIndex)
          • Unit - Order (Entering unit) to Attack-Move To Travel_WaypointPointArray[Travel_ChoiceRandomizer]
        • Else - Actions
          • Do nothing
I decided to just make 'em teleport
  • Travel Get Nearest Waypoint Teleport
    • Events
    • Conditions
    • Actions
      • -------- --------
      • -------- Temporary was added intentionally to avoid units getting stucked at STOP order --------
      • Set Travel_GroupTestSpawnPoint = (Center of Travel Waypoint 001 <gen>)
      • Set Travel_SpawnTemp = (Center of (Playable map area))
      • Unit - Move Travel_IdleUnit instantly to Travel_SpawnTemp
      • Unit - Move Travel_IdleUnit instantly to Travel_GroupTestSpawnPoint
      • Custom script: call RemoveLocation(udg_Travel_GroupTestSpawnPoint)
      • Custom script: call RemoveLocation(udg_Travel_SpawnTemp)
Here's how I detect them when idle
  • Travel Unit Stopped
    • Events
      • Time - Global_TickTimer expires
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Travel_GroupTest and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Current order of (Picked unit)) Equal to (Order(stand down))
            • Then - Actions
              • Game - Display to (All players) the text: Traveller is IDLE!
              • Set Travel_IdleUnit = (Picked unit)
              • Trigger - Run Travel Get Nearest Waypoint Teleport <gen> (ignoring conditions)
            • Else - Actions
              • Do nothing
Pull them out of the group when dead
  • Travel Unit Died
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Dying unit) is in Travel_GroupTest) Equal to True
    • Actions
      • Unit Group - Remove (Dying unit) from Travel_GroupTest
Test trigger
  • Travel Spawn Test
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set Travel_SpawnPointTemp = (Center of Travel Waypoint 001 <gen>)
      • Unit - Create 1 Rebel Mercenary - Axe for Player 2 (Blue) at (Center of Travel Waypoint 001 <gen>) facing Default building facing degrees
      • Unit Group - Add (Last created unit) to Travel_GroupTest
      • Custom script: call RemoveLocation(udg_Travel_SpawnPointTemp)
 
Last edited:
Maybe you can use this?

Also this would be more efficient I believe;

  • Pick Units
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((((Matching unit) is alive) Equal to True) and ((Current order of (Matching unit)) Equal to (Order(stand down))))) and do (Actions)
        • Loop - Actions
In your trigger you first pick all units, then filter them out. In my trigger you filter them out and pick only the relevant ones.
 
I feel like the problem was specifically happening in Travel Get Nearest Waypoint trigger. I was hoping that maybe that can be optimized?

Maybe you can use this?

Also this would be more efficient I believe;

  • Pick Units
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((((Matching unit) is alive) Equal to True) and ((Current order of (Matching unit)) Equal to (Order(stand down))))) and do (Actions)
        • Loop - Actions
In your trigger you first pick all units, then filter them out. In my trigger you filter them out and pick only the relevant ones.

Sadly didn't work, it actually caused more lag since I believe this is actually picking all units in the map and does the same thing, filtering the units with the conditions.

Fixed the location leaks.

I'll post updated triggers within 30 minutes, wait.
 
Last edited:
Level 9
Joined
Jul 30, 2018
Messages
445
In your trigger you first pick all units, then filter them out. In my trigger you filter them out and pick only the relevant ones.

There's no difference whether you are using the Matching unit or first picking all units and the filtering them with an if. They are always filtered by first picking every unit and then checking which units fit the Matching unit conditions anyway.

I even prefer to first picking all units and then filtering them with an if, because it's a lot more clear to read and a lot easier to modify, if you want to change the conditions.
 
Maybe you can use this?

Tried it right now, though the problem now is that it says the unit stopped even though the unit didn't actually stopped but only turned around.

By the way I updated the post and fixed the location leaks. I'm still hoping someone can help me think what else can I do to optimize it especially the 'Travel Get Nearest Waypoint' triggers.
 
Last edited:
I think the problem might be your repeating timer. Try making it non-repeating, and starting it again at the very end of
base.gif
Travel Get Nearest Waypoint and also in
base.gif
Travel Unit Stopped where now you have Do Nothing.

You should probably also use a unit group instead of Travel_WaypointUnitArray.

You still have location leaks, e.g. (Position of Travel_IdleUnit) in Distance between (Position of Travel_IdleUnit) and Travel_WaypointUnitLoc). But I think you just forgot to replace it with the Travel_IdleUnitLoc variable.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
Edit: After some testing of my own I see why you're doing it this way. So my question is what causes your Travelers to become idle?

Also, why not use "A unit enters/leaves region"?

I uploaded a map using a system I threw together. It uses a Unit Indexer and the "A unit enters Region" Event to control the Travelers/Waypoints. I haven't tested it with 256 Waypoints and on a larger map but I think this should be more efficient.

Edit: v.1 and v.2 both work, but v.2 contains a "Returning Home" feature that forces the Travelers to ignore all other Waypoints on their way back "home" (the starting Waypoint).
Edit 2: Here's v.3 with a bunch of hostiles along the way. The Travelers are ordered to Attack-Move in this one rather than just Move.
 

Attachments

  • Travel System v.2.w3x
    29.1 KB · Views: 10
  • Travel System v.1.w3x
    27.3 KB · Views: 14
  • Travel System v.3.w3x
    30.6 KB · Views: 11
Last edited:
After some testing of my own I see why you're doing it this way. So my question is what causes your Travelers to become idle?

Warcraft 3 command system is weird, I've done a (literally) thousand tests and it all ends up the same.

Basically here are the reasons why:
1. When you command unit to 'Attack/Move' from one region to another region and find a hostile along the way, the unit's command will be hooked to the enemy, attack it, then when the hostile is dead it completely forgets the command that he was told (to move to Region B from Region A). I cannot switch it to 'Move' command because my intention is to make him actually patrol in a big map I made which is why there are around 200+ waypoints in it.
2. Even if I add the trigger 'AI - Remove AI to Unit' or 'AI - Remove all guard positions to all Player 2 units' in the trigger I mentioned at #1 it is still happening (unit forgetting the command to move to Region B).
3. When there are too much units converging to one region there are units that will be squished/imprisoned in the middle because of unit collisions, like this

0 0 0 0 0
0 1 1 1 0
0 1 2 1 0
0 1 1 1 0
0 0 0 0 0

Basically all units outside are free (the zeroes) to move since there are no units blocking their way, but those at the middle (the twos) gets stucked and it forgets the command that he was told (to move to Region B) when stucked for atleast 10-15 seconds, and after that the unit will completely stop, in a region, and the unit will not be catched by 'Entering Unit' in a region because the unit technically entered the region but forgot the command, the unit is stopped in the middle of region waypoint.

By the way thank you for takingyour time to test this :)

You should probably also use a unit group instead of Travel_WaypointUnitArray.

I cannot select the units when in Unit Group efficiently, so I had to put it all in the array. The only way to select units in Unit Groups (as far as I know) is to select all units in the map and filter the units out with Boolean condition (Picked unit is in the unit group) and that is actually way more stressful (in performance). So I went to the method of putting waypoint units to arrays so I can select it all even when the units are hidden. (Because you cannot select the waypoint units when hidden and with Locust ability - even with triggers).

On the good side though, I managed to fixed it (Well sort of), by teleporting the units (from the spawn point) when stopped instead, because it's less stressful to the game performance. I'll update the OP.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,178
If there are still performance difficulties consider a spatial data structure like a quad tree. This could resolve the nearest waypoint with much better complexity than O(n).

Of course after fixing the leak...
Set Travel_WaypointDistanceReal = (Distance between (Position of Travel_IdleUnit) and Travel_WaypointUnitLoc)
This leaks a location.
(Position of Travel_IdleUnit)
 
This leaks a location.

Fixed it, just forgot to update the OP.

If there are still performance difficulties consider a spatial data structure like a quad tree. This could resolve the nearest waypoint with much better complexity than O(n).

I wish I can do this but unfortunately this is beyond my knowledge.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
@Strydhaizer
SOME of the Region issues you talk about shouldn't happen in the map I uploaded, I found that fixing the rect (something I do) helps with a lot of weird interactions. Also, each Traveler's Current/Next Region is stored to it at all times so you can always get where a Traveler is headed and where it has just passed through at any given time.

Edit: I'm testing my map now with a bunch of Neutral Hostile units along the paths and there's absolutely no issues. The Travelers will kill them along their way and then continue back towards the correct destination. Try it out yourself!
 
Last edited:
I cannot select the units when in Unit Group efficiently, so I had to put it all in the array. The only way to select units in Unit Groups (as far as I know) is to select all units in the map and filter the units out with Boolean condition (Picked unit is in the unit group) and that is actually way more stressful (in performance). So I went to put the method of putting waypoint units to arrays so I can select it all even when the units are hidden. (Because you cannot select the waypoint units when hidden and with Locust ability - even with triggers).
If you manually add the units to a unit group variable the same way you add them to the unit array, you don't have to "pick" any units. Then you can just loop through the group:
  • Unit Group - Pick every unit in WayPointGroup and do (Actions)
    • Loop - Actions
edit: for some reason I thought your waypoints in the 210 long trigger were units and not regions, so ignore what I said xD
 
Last edited:
SOME of the Region issues you talk about shouldn't happen in the map I uploaded, I found that fixing the rect (something I do) helps with a lot of weird interactions. Also, each Traveler's Current/Next Region is stored to it at all times so you can always get where a Traveler is headed and where it has just passed through at any given time.

I didn't notice the attachment lol my bad. I'll try it.

Update: I am actually concerned why are they only taking one path (progressively)? They were suppose to take random paths, there are paths with 3, 4 and 5 choices for the units to walk through, like this (see attachment).

The Y and + paths
upload_2020-1-28_8-57-17.png


The entire map with all waypoint locations (Ignore the borders)
upload_2020-1-28_9-1-3.png


If you manually add the units to a unit group variable the same way you add them to the unit array, you don't have to "pick" any units. Then you can just loop through the group:

Like I mentioned the 'Pick' trigger doesn't actually pick the unit with locust ability/hidden, but I'll try to find a way to make this work, brb.

Dumb thought: what if you actually issue a patrol order instead of attack move? And then redirect or order a stop when they enter a node so they don’t turn around and come back.

I don't actually get this idea how this works lol, when they enter a waypoint region the entering unit will be told to move to another waypoint region.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
@Strydhaizer
I don't see how you have that setup in your triggers. Edit: The picture just loaded. I think I get how you're doing it. So you spawn a traveler on 1 of 5 pre-defined paths and when it reaches the end it what, disappears/teleports back to the start?
 
don't see how you have that setup in your triggers. Did you create 5 pre-defined paths? Or is it completely randomized for each unit?

Each unit should have choices where it should walk next to, I wanted it to work like this

(Check the map)

If the unit walked to 18 coming from 17, he should have a choice to pick 26 or 19 (but due to my limited knowledge the unit also comes back to 17 because it is included in the array and I have no idea how to make the unit remember which waypoint the unit came from).

Edit: I wish the triggers offer a multidimensional array where I can store Custom Value, Previous and Current Region, like this

Custom Value | Previous | Current
18 | Region 11 | Region 12

So you spawn a traveler on 1 of 5 pre-defined paths and when it reaches the end it what, disappears/teleports back to the start?

There is no end the map they have endless choices to walk to, they loop around the map. And yes they do spawn from 1 (for now).
 
Last edited:

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
I see now. That's certainly a challenge, lol. So are there any instances where they backtrack like moving from 1 to 2, then back to 1. Or are they always moving towards a new Waypoint (one they haven't been on yet)?
 
Last edited:
So are there any instances where they backtrack like moving from 1 to 2, then back to 1.

I actually wanted it not to work like this, like I mentioned past 2 replies above due to my limited knowledge I can't make the units remember which waypoint was the previous waypoint they came from so they can avoid it when picking a next waypoint.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
I actually wanted it not to work like this, like I mentioned past 2 replies above due to my limited knowledge I can't make the units remember which waypoint was the previous waypoint they came from so they can avoid it when picking a next waypoint.
I store the Regions to the unit using a Unit Indexer. The variable "NextRegion" is where the Traveler is headed towards and "RecentRegion" is the last region the Traveler passed through.

  • Traveler Enter Region
    • Events
      • Unit - A unit enters 1 <gen>
      • Unit - A unit enters 2 <gen>
      • Unit - A unit enters 3 <gen>
      • Unit - A unit enters 4 <gen>
      • Unit - A unit enters 5 <gen>
      • Unit - A unit enters 6 <gen>
      • Unit - A unit enters 7 <gen>
      • Unit - A unit enters 8 <gen>
      • Unit - A unit enters 9 <gen>
      • Unit - A unit enters 10 <gen>
      • Unit - A unit enters 11 <gen>
      • Unit - A unit enters 12 <gen>
      • Unit - A unit enters 13 <gen>
      • Unit - A unit enters 14 <gen>
      • Unit - A unit enters 15 <gen>
      • Unit - A unit enters 16 <gen>
      • Unit - A unit enters 17 <gen>
      • Unit - A unit enters 18 <gen>
      • Unit - A unit enters 19 <gen>
      • Unit - A unit enters 20 <gen>
      • Unit - A unit enters 21 <gen>
    • Conditions
      • ((Triggering unit) is in TravelerGroup) Equal to True
    • Actions
      • Set TravelUnit = (Triggering unit)
      • Set UDex = (Custom value of TravelUnit)
      • -------- - --------
      • For each (Integer A) from 1 to TravelTotalRegions, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TravelerRegions[(Integer A)] contains TravelUnit) Equal to True
            • Then - Actions
              • Set TravelerRecentRegion[UDex] = TravelerRegions[(Integer A)]
              • -------- - --------
              • -------- Determines the Next Region the Traveler should move to --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Integer A) Less than TravelTotalRegions
                • Then - Actions
                  • Set TravelPoint[1] = (Center of TravelerRegions[((Integer A) + 1)])
                  • Set TravelerNextRegion[UDex] = TravelerRegions[((Integer A) + 1)]
                • Else - Actions
                  • Set TravelPoint[1] = (Center of TravelerRegions[1])
                  • Set TravelerNextRegion[UDex] = TravelerRegions[1]
              • -------- - --------
              • Unit - Order TravelUnit to Attack-Move To TravelPoint[1]
              • -------- - --------
              • Custom script: call RemoveLocation (udg_TravelPoint[1])
            • Else - Actions
It's just that in my map I made it progressive like you said from 1 to 2, then 2 to 3, etc... But it could be modified to be random.
 
I store the Regions to the unit using a Unit Indexer. The variable "NextRegion" is where the Traveler is headed towards and "RecentRegion" is the last region the Traveler passed through.

Yeah I noticed lol, your map is actually a good reference for me I can finally make units remember the previous waypoint.

By the way thanks for the help. Really appreciate it :)

for some reason I thought your waypoints in the 210 long trigger were units and not regions, so ignore what I said xD

There were waypoint units spawned at the center of every waypoint regions, but since finding the closest waypoint unit is so stressful to the game I decided to remove it and went to the method of teleporting the units to spawn when caught idle.
 
Last edited:

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
Yeah I noticed lol, your map is actually a good reference for me I can finally make units remember the previous waypoint.

By the way thanks for the help. Really appreciate it :)

There were waypoint units spawned at the center of every waypoint regions, but since finding the closest waypoint unit is so stressful to the game I decided to remove it and went to the method of teleporting the units to spawn when caught idle.
No problem!

Check out v.4. I believe this is exactly what you wanted :D
 

Attachments

  • Travel System v.4.w3x
    33.1 KB · Views: 16
Check out v.4. I believe this is exactly what you wanted

I wasn't really asking for someone to make me a new system for this but I am not complaining lol this is great!

I see you arrayed the regions instead of waypoint units, what was I thinking all this time ordering the traveller units to move beside the nearest waypoint unit lol. Thank you very much, this helps me alot.

Man I wish you know how long I've been doing this and you just made it in just an hour like holy crap.

Video: Project Eurica - Gameplay Test - Part 6 (Dumb AI - Fail) | HIVE

If you go through that link, and look at the date at the bottom of the video you can tell how long I've been improving this system lol.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,456
No problem and I know it can kind of take the fun/challenge out of it if someone does all the work for you but I'm learning new stuff here too :p Plus there's still plenty of room for improvement.

That being said your map looks pretty interesting, I'll have to keep an eye on it!

Anyway, a spontaneous idea I had. You could break the map up into Quadrants. Like have 4 massive Regions each covering a quarter of the map. Then have a Counter on your Travelers. Everytime a Traveler enters a Region you determine which Quadrant it's in and increase that Quadrants Counter for that Traveler. Then once one of the Traveler's Quadrant Counters reaches let's say 10, the Traveler is teleported to a random region located outside of it's current Quadrant. This would prevent clusters of units from forming and would spread out units that have bad/repetitive movement patterns. Not sure if this would be good for your map or not but it sounded like a neat idea.
 
Last edited:
Status
Not open for further replies.
Top