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

[Trigger] Problem with hashtables and issuing orders

Status
Not open for further replies.
Level 4
Joined
Feb 9, 2010
Messages
48
Greetings, I'm creating a mechanic for event where I have citizens of player coming to his base. To sum it up I need those villagers to be uncontrollable, but people should be able to target them and kill them.

As such I use following triggers:
  • Citizens Route Spawn1
    • Events
      • Unit - A unit enters Dresh Citizen Spot 1 <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 6 (Orange)
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Set TempLoc = (Center of Citizen Route4 <gen>)
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Hashtable - Save Handle OfTempLoc as 0 of (Key TempHandle) in CitizenOrders
      • Unit - Set the custom value of (Triggering unit) to 1
      • Unit - Order (Triggering unit) to Move To TempLoc
      • Unit - Set the custom value of (Triggering unit) to 0
      • Custom script: call RemoveLocation (udg_TempLoc)
The above trigger is copied for every 'checkpoint' to direct the villagers to destination.

This is the trigger I'm using to prevent people from ordering any commands for the villagers:

  • Citizen orders
    • 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
      • (Custom value of (Triggering unit)) Equal to 0
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Unit - Set the custom value of (Triggering unit) to 1
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Set TempLoc = (Load 0 of (Key TempHandle) in CitizenOrders)
      • Unit - Order (Triggering unit) to Move To TempLoc
      • Custom script: call RemoveLocation (udg_TempLoc)
      • Unit - Set the custom value of (Triggering unit) to 0
The problem I have is that the trigger detects when the villager is issued a 'non-route-trigger' order, but it won't issue the order to move the unit to TempLoc. So the problem seems to lie in the hashtables. I'm not that experienced with them so it's possible I've made some mistakes, however for me it seems like they are correct. (Ofcourse I have created a hashtable at the map initalization and set the 'CitizenOrders' variable as the last created hashtable)

Do you have any ideas where are the mistakes or how to fix the problem?

Thanks in advance for the help
 
Level 13
Joined
May 10, 2009
Messages
868
At first glance, it looks like you're creating/defining those locations, storing and removing them at the same time. So, the hashtable returns null. You can either remove the location as soon as a unit reaches a new check point, or you store the rect in the hashtable and use tempLoc to obtain the center of it later.
 
Level 11
Joined
May 16, 2016
Messages
730
The problem I have is that the trigger detects when the villager is issued a 'non-route-trigger' order, but it won't issue the order to move the unit to TempLoc. So the problem seems to lie in the hashtables. I'm not that experienced with them so it's possible I've made some mistakes, however for me it seems like they are correct. (Ofcourse I have created a hashtable at the map initalization and set the 'CitizenOrders' variable as the last created hashtable)
Why not add condition Do ordered unit is selected by all player equal false? Because to order unit you need to select it first. So if the system orders unit then it wouldn't react, but if player does, then do something and don't allow any player to select them.
If they don't want to move. use store X;Y coordiantes (2 real variables) of temploc instead of point itself. Plus you stored the point that you remove after storing. so the way to store XY coordiantes is proper for you.
 
Last edited:
Level 4
Joined
Feb 9, 2010
Messages
48
Why not add condition Do ordered unit is selected by all player equal false? Because to order unit you need to select it first. So if the system orders unit then it wouldn't react, but if player does, then do something and don't allow any player to select them.
If they don't want to move. use store X;Y coordiantes (2 real variables) of temploc instead of point itself. Plus you stored the point that you remove after storing. so the way to store XY coordiantes is proper for you.
Hmm, I thought that if you store the TempLoc in a hashtable it will stay there, thought that removing TempLoc variable won't affect the insides of hashtable itself. Well was wrong, not the first time, good that I learnt something new.

I've utilized the 'save X, Y coordinates' and it works exactly as it should be. The 'selected' condition could cause problems when someone selected the villager and villager was reaching the checkpoint.

Thanks for the help ;)
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
you don't wanna disable unit control over this unit for human players?
so far this issue "disable control over a single unit" isn't solved
I can give you a hint about one trick with morph but it's one-time only, guess it won't fit to your job unless you're able to replace this worker without any consequences
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,201
There is another big problem here. You cannot cancel an order in response to that order... The order events fire before the order is actually issued so any order you issue to that unit immediately in response to that event will be cancelled out by the event order.

You will need some kind of out of order delay to cancel the order. A common way to achieve this is a 0 second timeout timer.

Why not add condition Do ordered unit is selected by all player equal false? Because to order unit you need to select it first. So if the system orders unit then it wouldn't react, but if player does, then do something and don't allow any player to select them.
Selection synchronization is subject to network latency. This is usually in the order of >100 ms which is easily noticeable as it is >6 displayed frames.
 
Level 4
Joined
Feb 9, 2010
Messages
48
I went with:
  • Citizens Route Spawn1
    • Events
      • Unit - A unit enters Dresh Citizen Spot 1 <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 6 (Orange)
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Set TempLoc = (Center of Citizen Route4 <gen>)
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Hashtable - Save (X of TempLoc) as 0 of (Key TempHandle) in CitizenOrders
      • Hashtable - Save (Y of TempLoc) as 1 of (Key TempHandle) in CitizenOrders
      • Unit - Set the custom value of (Triggering unit) to 1
      • Unit - Order (Triggering unit) to Move To TempLoc
      • Unit - Set the custom value of (Triggering unit) to 0
      • Custom script: call RemoveLocation (udg_TempLoc)
and for orders:
  • Citizen orders
    • 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
      • (Custom value of (Triggering unit)) Equal to 0
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Unit - Set the custom value of (Triggering unit) to 1
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Set TempLoc = (Point((Load 0 of (Key TempHandle) from CitizenOrders), (Load 1 of (Key TempHandle) from CitizenOrders)))
      • Unit - Order (Triggering unit) to Move To TempLoc
      • Custom script: call RemoveLocation (udg_TempLoc)
      • Unit - Set the custom value of (Triggering unit) to 0
Everything seems to be working correctly ingame. You can select the unit, attack it normally but you can't issue any orders, as the order will be instantly replaced by 'move to location', which is exactly what I want. Unless I'm wrong and I'm missing something?
 
Level 4
Joined
Feb 9, 2010
Messages
48
Where do you clean up the CitizenOrders hashtable for Key TempHandle after TempHandle unit is removed?

When the unit dies or reaches destination and is removed (Aka quest with citizen reaching destination is completed):
  • Citizen Reaches the destination
    • Events
      • Unit - A unit enters Citizen Destination <gen>
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 6 (Orange)
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Hashtable - Clear all child hashtables of child (Key TempHandle) in CitizenOrders
      • Unit - Remove (Triggering unit) from the game
      • Player - Add 10 to Player 6 (Orange) Current gold
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Current research level of Venture Into The Dark Forest for Player 6 (Orange)) Equal to 0
        • Then - Actions
          • Set DreshCitizensSaved = (DreshCitizensSaved + 1)
        • Else - Actions
  • Citizen Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Child [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Pack Horse [Dresh Citizen]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Female]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male1]
          • (Unit-type of (Triggering unit)) Equal to Villager [Dresh Citizen Male2]
    • Actions
      • Set TempUnit = (Triggering unit)
      • Custom script: set udg_TempHandle = udg_TempUnit
      • Hashtable - Clear all child hashtables of child (Key TempHandle) in CitizenOrders
 
Status
Not open for further replies.
Top