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

Me and another MUI/MPI issue.

Status
Not open for further replies.
Level 17
Joined
Jun 2, 2009
Messages
1,137
Hello. I had an aggro trigger few years ago. It has flaws and one of my friends created it as Jass for me. But it has flaws too (check the pictures) and it seems it is a hard work to fix this and i have decided to create by myself as i did before. If you want to see details, just click to the link. [JASS] - Can someone help me to fix this issue?

Now i have started to re-create it again just like this.

  • Player Attack 2 Copy
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • ((Attacked unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True
          • ((Attacked unit) is A Hero) Equal to True
          • ((Attacking unit) is A Hero) Equal to True
    • Actions
      • Unit Group - Pick every unit in (Units within 700.00 of (Position of (Attacked unit))) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Owner of (Picked unit)) Equal to Player 1 (Red)
              • ((Picked unit) belongs to an enemy of (Owner of (Attacking unit))) Equal to True
              • ((Picked unit) is alive) Equal to True
              • ((Picked unit) is A Hero) Equal to False
            • Then - Actions
              • Unit - Order (Picked unit) to Attack (Attacking unit)
              • Wait 2.00 seconds
              • Unit - Order (Picked unit) to Move To (Center of Region 000 <gen>)
            • Else - Actions
I can detect where they are and where they should go after aggro ends. You can ignore the TempGroup, TempLoc or Center of Region bla bla. I will fix it later. First, i have to make it work as i expected.

My objective is this aggro duration should be 2 seconds, then units going to attack-move to location that i want.
How can i detect the attackers after 2 seconds and re-order them again

Detailed explanation: You are attacking my hero and i have a few allied footmens around me. They will start to attack you for x seconds, then they will attack-move to any location that i want. Because they have not to follow and attack you until they die


Bonus: But of course you can solve it by fixing the Jass code i have shared as a link.


The pictures shows the problem with my Jass trigger. It is just an example for you.
 

Attachments

  • 1.png
    1.png
    1.1 MB · Views: 4
  • 2.png
    2.png
    1.4 MB · Views: 5
Level 18
Joined
Oct 17, 2012
Messages
821
I would do the following:
  1. Hero attacks another hero
  2. Pick all allied units around the attacker and add them to another unit group. Be sure to check if the units are already part of a group, so you don't add them to another group.
  3. Attach the hero being attacked to the unit group via hashtable or indexing
  4. Detect all unit orders via order events
  5. Check unit being ordered on event is part of your unit group and then reorder them to attack the hero that is attached to your unit group
  6. After 2 seconds or when the hero dies, clear your unit group or destroy it.
One glaring con with the above solution is that you are going to need dynamic groups or create a lot of unit groups. The number of groups you will create depends on map content and how you go about coding the above. Since the attack event, which will run frequently, is being used, expect a massive number of unit groups being created dynamically. To circumvent this, you could check if any unit picked is part of a group already before creating a new unit group. If there are none available, don't create a new unit group.

One way you could reduce the number of groups to one or zero is to attach the hero to the unit instead. After 2 seconds or when the hero dies, remove the link between unit and hero. So, in the order events, you would check if the ordered unit has a hero attached to it and reorder them to attack the hero if the unit is ordered to do something else. With this method, however, it is bit trickier to remove the link between the unit and hero.

Overall, the two solutions mentioned above aren't really good, especially the first one, but they may bring you closer to what you seek for. So, to make the two solutions more viable, I would minimize the number of encounters between units as much as you can afford to. There is not much else you can do since any form of aggro\threat system can be quite taxing for performance since units are involved.

Popular map Gaias Retaliation also has an aggro/threat system and runs smoothly. Other than its threat system being well refined over the years, its unit encounters are not densely packed but here and there instead, which prevents the threat system from running all the time or for too long, saving a lot of manpower. Of course, this situation won't necessarily apply to your map, so you just have to do what you can and see how everything goes.

By the way, waits don't work in Pick Every Unit functions as they are. The order to move will never happen. You have to place the wait and the actions after it in another trigger. Then run the trigger in the Pick Every Unit functions.
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,537
Probably repeating SmitingDevil here but I'll provide some links and examples that may help.

You can use this method for MUI stuff: local udg_

Then you can avoid putting Waits in your Pick Every Unit function by running another trigger:
  • Loop - Actions
    • Trigger - Run RetreatActions (ignoring conditions)
RetreatActions could then do this:
  • Actions
    • Custom script: local unit udg_RetreatUnit = GetEnumUnit()
    • Wait 2.00 seconds
    • Unit - Order RetreatUnit to Move to some Point
This stores the (Picked unit) as a local unit variable and then issues an Order to it 2.00 seconds later. Local variables will retain their data even after a Wait.

You can store other data to this unit before the Wait using a Unit Indexer or Hashtable. This could come in handy depending on what you need to accomplish.

For example, you probably want to prevent a unit from being issued an order again while it's still finishing it's previous one. Using a Unit Indexer you can track whether or not a unit should ignore future orders by using a Boolean that is attached to it:
  • Loop - Actions
    • Set Variable IgnoreOrders[Custom value of (Picked unit)] = True
    • Trigger - Run RetreatActions (ignoring conditions)
This Boolean needs to be checked in your Conditions to determine whether or not the (Picked unit) should issue an order:
  • If - Conditions
    • IgnoreOrders[Custom value of (Picked unit)] Equal to False
Then in the RetreatActions trigger you can Set it to False again:
  • Actions
    • Custom script: local unit udg_RetreatUnit = GetEnumUnit()
    • Wait 2.00 seconds
    • Unit - Order RetreatUnit to Move to some Point
    • Set Variable IgnoreOrders[Custom value of RetreatUnit] = False
Now your unit is guaranteed to only run one instance of the RetreatActions trigger at a time. You can delay setting IgnoreOrders to False even longer using another Wait if you want the unit to Move away more:
  • Actions
    • Custom script: local unit udg_RetreatUnit = GetEnumUnit()
    • Wait 2.00 seconds
    • Unit - Order RetreatUnit to Move to some Point
    • Wait 2.00 seconds
    • Set Variable IgnoreOrders[Custom value of RetreatUnit] = False
 
Last edited:
Status
Not open for further replies.
Top