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

[General] Unique Defense "keep attention" system - how can I do it?

Level 11
Joined
May 9, 2021
Messages
189
Basically, I'm thinking of making a LOTR "Battle at the Black Gate" map, and there's one unique feature I'd like to have in it.

I want there to be a part of the map where Frodo and Sam are climbing to Mount Doom to destroy the Ring, which they should reach by the end of a timer.

I also want Sauron's eye to be included, and you, playing as the Army of the West, have to keep fighting to divert Sauron's gaze and give Frodo and Sam the time they need. If Sauron's eye stays on Frodo and Sam for too long, the game is lost.

  • How can I make Frodo and Sam reach the end when the timer runs out? Just make them move really slowly? Some sort of Caravan-type system?
  • How can I make the "divert attention" system? I wouldn't even know where to begin with this.

Help will be appreciated.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,564
1) Can Frodo and Sam be controlled or manipulated in any way? If so, it's impossible to determine the exact time that they'll reach the end since the user can force them to stop moving. But I'll just assume that they're owned by a Neutral player and have no dynamic obstacles, in other words, it always takes them the exact same time to reach their destination. If so, you should adjust the Timer based on how long this takes, which would vary based on their Movement speed and any obstacles in the way. You could use an in-game Timer or just google a Stopwatch/your phone's Stopwatch app to calculate roughly how long it takes, then use that value when starting your Time. Adjust their Movement speed as necessary to speed up and slow down the process. It'll be a rough estimate but through trial and error you can get very close to a consistent result.

That being said, is a Timer really even necessary here? It sounds like you want to do Distance checks from the position of say Frodo to the final destination since that gives more precision and will account for any obstacles or interference that could change the total time it takes.

2) I'll assume that the Eye of Sauron is controlled by a Computer and the user cannot manipulate it. All of this could be handled with a Damage detection system where you track the Damage Per Second being dealt to Sauron's army. For every second that this DPS value is too low you would increase an Integer variable by 1. Once this Integer reaches say 30 the game ends because that implies that the Players haven't dealt enough damage for 30 seconds straight. You'll have to figure out the numbers yourself since it all depends on how much damage and how often units deal damage in your map.


Here's an example map, this Start trigger should occur when you're ready to begin the "Destroy The Ring" event:
  • DTR Start
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • -------- This should happen when you're ready to start the "Destroy The Ring" event! --------
      • -------- --------
      • -------- Eye of Sauron stuff --------
      • Set VariableSet DTR_Check_For_Game_Over = True
      • Trigger - Turn on DTR Check Damage Per Second <gen>
      • Trigger - Turn on DTR Get Damage Per Second <gen>
      • -------- --------
      • -------- Frodo and Sam stuff --------
      • Set VariableSet DTR_Current_Point = (Center of DTR Start <gen>)
      • Set VariableSet DTR_End_Point = (Center of DTR End <gen>)
      • Set VariableSet DTR_Total_Distance = (Distance between DTR_Current_Point and DTR_End_Point)
      • Set VariableSet DTR_Current_Distance = DTR_Total_Distance
      • Custom script: call RemoveLocation( udg_DTR_Current_Point )
      • Unit - Order Frodo 0001 <gen> to Move To DTR_End_Point
      • Trigger - Turn on DTR Check Ring Completion <gen>
Here we're using my Distance method to determine how close Frodo is to destroying the ring in Mt Doom:
  • DTR Check Ring Completion
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Set VariableSet DTR_Current_Point = (Position of Frodo 0001 <gen>)
      • Set VariableSet DTR_Current_Distance = (Distance between DTR_Current_Point and DTR_End_Point)
      • Custom script: call RemoveLocation( udg_DTR_Current_Point )
      • -------- --------
      • -------- Ensure that this Distance number is never actually 0 since that will crash the game (never divide by 0) --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DTR_Current_Distance Less than or equal to 0.00
        • Then - Actions
          • Set VariableSet DTR_Current_Distance = 0.01
        • Else - Actions
      • -------- --------
      • -------- Get the percentage as a fractional number: --------
      • Custom script: set udg_DTR_Completion_Percentage = (1 - udg_DTR_Current_Distance / udg_DTR_Total_Distance) * 100
      • -------- --------
      • -------- Let's make sure that this number doesn't go below 0 because that'd be silly: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DTR_Completion_Percentage Less than 0.00
        • Then - Actions
          • Set VariableSet DTR_Completion_Percentage = 0.00
        • Else - Actions
      • -------- --------
      • -------- Get the percentage as a whole number (some rounding will occur): --------
      • Set VariableSet DTR_Completion_Percentage_Int = (Integer(DTR_Completion_Percentage))
      • -------- --------
      • -------- If Frodo is close enough let's consider it a win! --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DTR_Completion_Percentage Greater than or equal to 99.50
        • Then - Actions
          • Game - Display to (All players) for 30.00 seconds the text: |cff00ff00VICTORY!!...
          • Set VariableSet DTR_Completion_Percentage = 100.00
          • Set VariableSet DTR_Completion_Percentage_Int = 100
          • Trigger - Turn off DTR Check Damage Per Second <gen>
          • Trigger - Turn off DTR Get Damage Per Second <gen>
          • Trigger - Turn off DTR Check Ring Completion <gen>
        • Else - Actions
      • -------- --------
      • -------- Display the percentage: --------
      • Game - Display to (All players) for 30.00 seconds the text: (Destroy The Ring Completion: + ((String(DTR_Completion_Percentage_Int)) + / 100%))
Here we're tracking the Damage Per Second, the Neutral Hostile player represents Sauron's army:
  • DTR Get Damage Per Second
    • Events
      • Unit - A unit Takes damage
    • Conditions
      • (Owner of (Triggering unit)) Equal to Neutral Hostile
    • Actions
      • Custom script: local real damage = GetEventDamage()
      • Custom script: set udg_DTR_Damage_Per_Second = udg_DTR_Damage_Per_Second + damage
      • Wait 1.00 game-time seconds
      • Custom script: set udg_DTR_Damage_Per_Second = udg_DTR_Damage_Per_Second - damage
Here we're checking the Damage Per Second and determining whether enough is being dealt and if the game should end:
  • DTR Check Damage Per Second
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DTR_Damage_Per_Second Less than 500.00
          • DTR_Check_For_Game_Over Equal to True
        • Then - Actions
          • -------- Not enough damage is being dealt to Sauron's army, increase the game over counter! --------
          • Set VariableSet DTR_Game_Over_Counter = (DTR_Game_Over_Counter + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DTR_Game_Over_Counter Equal to 30
            • Then - Actions
              • -------- It's been 30 seconds of failing to divert Sauron's attention - End the game in defeat! --------
              • Game - Display to (All players) for 30.00 seconds the text: |cffff0000GAME OVER...
              • Trigger - Turn off DTR Check Damage Per Second <gen>
              • Trigger - Turn off DTR Get Damage Per Second <gen>
              • Trigger - Turn off DTR Check Ring Completion <gen>
            • Else - Actions
        • Else - Actions
          • -------- The players are doing well so let's reduce the game over counter --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DTR_Game_Over_Counter Greater than 0
            • Then - Actions
              • Set VariableSet DTR_Game_Over_Counter = (DTR_Game_Over_Counter - 1)
            • Else - Actions
      • Game - Display to (All players) for 30.00 seconds the text: (Game Over Counter: + ((String(DTR_Game_Over_Counter)) + / 30 seconds))
A fun addition would be to make the Eye of Sauron a Unit or Special Effect and have it move closer to or further away from Frodo based on the value of the DTR_Game_Over_Counter. For example, by default it could be positioned at the "center of the battlefield" at some Region. Then using some Distance math and the Point With Polar Offset function you could position it offset from Frodo based on the value of DTR_Game_Over_Counter. So for example, assuming that 30 is the highest the Counter can go:
  • When the Counter is 0 the Eye remains at it's default position on the battlefield.
  • When the Counter is 15 it would be half-way between the battlefield and Frodo.
  • When the Counter is 30 it would be right on top of Frodo.
It wouldn't be too difficult to add this functionality to the above DTR Check Damage Per Second trigger.
 

Attachments

  • LOTR triggers 1.w3m
    22.3 KB · Views: 2
Last edited:
Level 11
Joined
May 9, 2021
Messages
189
1) Can Frodo and Sam be controlled or manipulated in any way? If so, it's impossible to determine the exact time that they'll reach the end since the user can force them to stop moving. But I'll just assume that they're owned by a Neutral player and have no dynamic obstacles, in other words, it always takes them the exact same time to reach their destination. If so, you should adjust the Timer based on how long this takes, which would vary based on their Movement speed and any obstacles in the way. You could use an in-game Timer or just google a Stopwatch/your phone's Stopwatch app to determine roughly how long it takes. Adjust their Movement speed as necessary to speed up and slow down the process.
Yes they are controlled by a neutral Player. I hadn't thought of adjusting the timer based on their movement speed...

Thank you for the help :)

I'll check through it.
 
Level 25
Joined
Sep 26, 2009
Messages
2,381
Then there's a bunch of ways to calculate just the % of the distance travelled.

One option would be to store the total distance at map start and during game just calculate the remaining distance based off Frodo's position.
Divide remaining distance by total distance to get the ratio, multiply it by 100 and you have the percent.
Warcraft has function for the 'real' data type/variable to get the distance between two points. The distance is always a straight line.
  • Set VariableSet distance = (Distance between PointA and PointB)
That said, how feasible this option is depends on how you created the path that Frodo follows. If you check for example the Orc's campaign map where Thrall guards kodo caravan, you will notice that developers put regions along the path. These regions serve as waypoints for the caravan.
So the caravan does not go from start to end via single point order, instead they just travel between two close waypoints.
If you created the path in a similar way, then the total distance is just the sum of distances between all pairs of waypoints.

Another option that includes these waypoints is to just take the total number of waypoints and the number of reached waypoints and calculate the % based off that. But this option is only good if you have high enough number of waypoints.
For example if you only had 10 waypoints, then the % of distance travelled would update by 10%, which may be too inaccurate. If you have 20 waypoints, it would update by 5% per waypoint, giving better precision.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,564
Then there's a bunch of ways to calculate just the % of the distance travelled.

One option would be to store the total distance at map start and during game just calculate the remaining distance based off Frodo's position.
Divide remaining distance by total distance to get the ratio, multiply it by 100 and you have the percent.
Warcraft has function for the 'real' data type/variable to get the distance between two points. The distance is always a straight line.
  • Set VariableSet distance = (Distance between PointA and PointB)
That said, how feasible this option is depends on how you created the path that Frodo follows. If you check for example the Orc's campaign map where Thrall guards kodo caravan, you will notice that developers put regions along the path. These regions serve as waypoints for the caravan.
So the caravan does not go from start to end via single point order, instead they just travel between two close waypoints.
If you created the path in a similar way, then the total distance is just the sum of distances between all pairs of waypoints.

Another option that includes these waypoints is to just take the total number of waypoints and the number of reached waypoints and calculate the % based off that. But this option is only good if you have high enough number of waypoints.
For example if you only had 10 waypoints, then the % of distance travelled would update by 10%, which may be too inaccurate. If you have 20 waypoints, it would update by 5% per waypoint, giving better precision.
I like your explanation, but just to save you from making the same triggers twice, what you described is exactly what I did in my triggers above. I was a bit misleading in my post because I told him how to handle it with Timers but I solved it using Distance.
 
Top