• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Creating a Magnet

Status
Not open for further replies.
Level 2
Joined
Dec 23, 2008
Messages
6
I'm making a tower defense map with several special effect and other odd towers and rules. One of the towers is a magnet that is supposed to pull units towards it. An important detail is the map has no maze and no terrain and all units move towards a random point in a region called EndPoint. I don't mind if a reply is in either straight Jass or GUI triggers. I intend to convert this all to Jass to optimize it anyway.

Here's the code I have:

  • Magnet Pull Copy Copy
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units of type Magnet) and do (Actions)
        • Loop - Actions
          • Set CurrentMagnetUnit = (Picked unit)
          • Set DensityUnit = (Picked unit)
          • Set DensityUnitType = Magnet
          • Set DensityDistance = 2000.00
          • Trigger - Run GetDensity <gen> (ignoring conditions)
          • Set DensityValue = (DensityValue x 5.00)
          • If (DensityValue Greater than or equal to 30.00) then do (Set DensityValue = 30.00) else do (Do nothing)
          • Set TempInt = 5
          • Unit Group - Pick every unit in (Units within DensityAffectMinimum of (Position of CurrentMagnetUnit) matching ((Owner of (Matching unit)) Equal to Neutral Hostile)) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TempInt Greater than 0
                • Then - Actions
                  • Set TempA = (Distance between (Position of (Picked unit)) and (Position of CurrentMagnetUnit))
                  • Set TempB = ((X of (Position of CurrentMagnetUnit)) - (X of (Position of (Picked unit))))
                  • Set TempC = ((Y of (Position of CurrentMagnetUnit)) - (Y of (Position of (Picked unit))))
                  • Set TempB = (TempB / TempA)
                  • Set TempC = (TempC / TempA)
                  • Game - Display to (All players) the text: (VecX: + ((String(TempB, 1, 2)) + (; VecY: + (String(TempC, 1, 2)))))
                  • Game - Display to (All players) the text: (Old Pos: + ((String((X of (Position of (Picked unit))), 1, 2)) + (; + (String((Y of (Position of (Picked unit))), 1, 2)))))
                  • Unit - Move (Picked unit) instantly to ((Position of (Picked unit)) offset by ((DensityValue x TempB), (DensityValue x TempC)))
                  • Unit - Order (Picked unit) to Move To (Random point in Path End <gen>)
                  • Game - Display to (All players) the text: (New Pos: + ((String((X of (Position of (Picked unit))), 1, 2)) + (; + (String((Y of (Position of (Picked unit))), 1, 2)))))
                  • If (TempInt Equal to 0) then do (Skip remaining actions) else do (Do nothing)
                • Else - Actions
There are a lot of global variables in this map that serve multiple purposes. I know it's bad style, but I just wanted it done first. There is also a density calculation trigger used for another purpose. CurrentMagnetUnit will be the current magnet tower. Another trigger selects them all and calls this for each one.

The algorithm for this trigger is as follows:
Pick every unit within DensityAffectMinimum of CurrentMagnetUnit
- Calculate the distance
- Calculate a normal vector from PickedUnit to CurrentMagnetUnit
- Instantly Move PickedUnit towards CurrentMagnetUnit
- Move PickedUnit to Random Location in EndPoint

The trouble is, Warcraft 3 units have no momentum so it's impossible to just nudge a unit towards another. I've done a physics simulation of this in C++, which is where I got the idea from. So, I'm forced to use Unit - Move (Instantly). The problem is it looks jerky and it forces a reset of the unit's original destination because Unit - Move cancels the previous order. Because of that, I have to make the unit pick a new random point in EndPoint to move towards.

Does anyone have a better solution? I thought if all else fails I may just force any unit in range move through the magnet to the other side. With that, it would only attempt to be a magnet from one side or it would never allow a unit to pass it.
 
Last edited:
Level 2
Joined
Dec 23, 2008
Messages
6
What I really need is a way for a tower to only affect a unit once, and being able to set a waypoint, ie, first order is direct unit to magnet, second order, go to end point, without requiring two separate ticks of the magnet on the unit. The attack a unit and move it method "works" best because it is only one action of the magnet on the unit. I have no way that I can think of such that once a magnet acts on a unit to make sure that magnet doesn't touch that unit again.
 
Status
Not open for further replies.
Top