• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[General] Make NPC units attempt to position behind enemy units and Attack from behind to fire damage trigger

Status
Not open for further replies.
Level 5
Joined
Feb 13, 2019
Messages
128
Say we have a trigger set up that attacks from behind (a units attack/attack animation literally strikes/touchs the back of another units model) does bonus damage,

would there a way to go about having units attempt to position well (attempt to move behind the units it is attacking) to get the most out of the extra damage trigger. I mean non-player controlled units, with no player controller.

Units probably wouldn't want to always be wasting their time in combat just walking around attempting to get a flank, also maybe we could just put it on lets say just the Archers in a combat situation, while a Mountain King isnt concerned with flanking anyone, and more or less is protecting it's archers and attempting to hold the enemy unit down with stuns.

Trigger Example


  • Backstab
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • IsDamageSpell Equal to False
    • Actions
      • -------- DamageEventSource is the unit dealing the damage --------
      • Set AttackingUnit = DamageEventSource
      • -------- DamageEventTarget is the unit that takes damage --------
      • Set AttackedUnit = DamageEventTarget
      • Set Point[1] = (Position of AttackedUnit)
      • Set Point[2] = (Position of AttackingUnit)
      • Set Angle[1] = (Facing of AttackedUnit)
      • Set Angle[2] = (Angle from Point[1] to Point[2])
      • Set Angle[3] = (Acos((Cos((Angle[2] - Angle[1])))))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Angle[3] Greater than or equal to 120.00) and (Angle[3] Less than or equal to 240.00)
        • Then - Actions
          • -------- Instead of using unit-damage target, we use DamageEventAmount variable to change the damage amount --------
          • Set DamageEventAmount = (DamageEventAmount x 2.00)
          • -------- this will deal 2x damage, when backstabbed --------
          • Special Effect - Create a special effect at Point[1] using Objects\Spawnmodels\Human\HumanBlood\HumanBloodPriest.mdl
          • Special Effect - Destroy (Last created special effect)
        • Else - Actions
      • Custom script: call RemoveLocation(udg_Point[1])
      • Custom script: call RemoveLocation(udg_Point[2])
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,584
Some ideas off the top of my head:

Have a trigger that would replace any targeted Attack order given to the Archer to instead order the Archer to move behind it's target. To do this, first I would use a Unit Indexer to store multiple Points (We can't have our Archer walk right through/past the enemy to get behind it so we would need to map several points at different offsets around our Target to make it flank around it). Then a variable to store the Target of the attack order. Finally, have a timer to periodically check if our Archer has reached a Point (If distance between Archer and Point1 <= 10 then order Archer to move to Point2). Once it's reached the final Point then we can order the Archer to Attack it's target.

Now, this would probably cause all sorts of weird interactions and there's a chance that our Archer can't actually ever reach one of our Points, so we would need some kind of system to detect if it "fails" to reach a Point. How to do that effectively, i'm not too sure. That aside, we would also want to periodically update the Archer's Points every 0.10 seconds or so since it's Target will probably have moved/turned since our Archer first started walking towards it.

Another idea, if the Archer reaches it's first Point then you could start another timer that lasts lets say 2 seconds. If the Archer has failed to get behind the enemy unit after 2 seconds then it will give up and begin to attack from wherever it currently is. That way if the Target is spinning in circles then our Archer wouldn't bug out and endlessly try to re position itself like a dog chasing it's tail.

I might mess around with some triggers tomorrow to come up with an example. Seems like a fun project, albeit maybe too much for Warcraft 3. I usually end up scrapping ideas like these because there's just too many issues that arise and we're sort of stuck using the pathing system we've been given.
 
Last edited:
Level 5
Joined
Feb 13, 2019
Messages
128
Thank you for the fast reply :grin:!

That sounds pretty solid to me with the 2 second check, :prazz: I'm hoping not to scrap this one to be honest too though, :grin:

I think it would add a lot of stress and danger to engagements when you see a rogue stealth or something and you know he's about to probably crit on top of a backstab trigger and put your hero into the dirt! :peasant-popcorn:
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,584
Here's a test map. It seems to work pretty great if the enemy ISN'T moving/turning, but you'll see that it doesn't really work properly otherwise. Maybe you could mess around with it, hopefully it's not too disorganized or confusing.

Press Escape ingame to make the demon hunter spin.

Also, you can delete the actions I linked below (ony delete the actions in the Else part of the If Else Statement). They're located in the Flank Timer trigger. They don't really work as intended so I doubt you'd want to use them anyway.

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Flank_TempReal[0] Less than or equal to 25.00
    • Then - Actions
    • Else - Actions
      • YOU CAN DELETE ALL OF THE ACTIONS IN THIS ELSE STATEMENT:
      • Set Flank_TempReal[1] = ((Facing of Flank_AttackTarget[Flank_CV]) + 90.00)
      • Set Flank_TempReal[2] = ((Facing of Flank_AttackTarget[Flank_CV]) - 90.00)
      • -------- - --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Flank_Side1[Flank_CV] Not equal to Flank_TempReal[1]
          • Flank_Side2[Flank_CV] Not equal to Flank_TempReal[2]
        • Then - Actions
          • -------- - --------
          • Set Flank_TempPoint[1] = (Position of Flank_AttackTarget[Flank_CV])
          • Set Flank_TempReal[0] = (Acos((Cos(((Angle from Flank_TempPoint[0] to Flank_TempPoint[1]) - (Facing of Flank_AttackTarget[Flank_CV]))))))
          • -------- - --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Flank_TempReal[0] Less than 90.00
              • (Distance between Flank_TempPoint[0] and Flank_TempPoint[1]) Less than or equal to Flank_AttackRange[Flank_CV]
            • Then - Actions
              • Special Effect - Destroy Flank_TempSFX[Flank_CV]
              • -------- - --------
              • Trigger - Turn off Flank Order <gen>
              • Unit - Order Flank_AttackSource[Flank_CV] to Attack Flank_AttackTarget[Flank_CV]
              • Trigger - Turn on Flank Order <gen>
              • -------- - --------
              • Set Flank_IsFlanking[Flank_CV] = False
              • Unit Group - Remove Flank_AttackSource[Flank_CV] from Flank_UG
              • Custom script: call RemoveLocation(udg_Flank_Point1[udg_Flank_CV])
            • Else - Actions
          • Custom script: call RemoveLocation(udg_Flank_TempPoint[1])
          • DON'T DELETE ANYTHING AFTER IT
        • Else - Actions
 

Attachments

  • Flank.w3x
    27.3 KB · Views: 22
Last edited:
Status
Not open for further replies.
Top