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

[Solved] Issues with unit morph that walks through walls

Status
Not open for further replies.
Level 21
Joined
Mar 29, 2020
Messages
1,237
hey,

I made a morph ability based on chemical rage that makes the morphed unit have "flying type" movement for the duration of the morph. I already made a trigger to deal with the morph expiring while over water so instead of just getting stuck in the water the unit dies

  • fall and drown
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Set Landing_Tactician = (Units of type Slippery Tactician)
      • Unit Group - Pick every unit in Landing_Tactician and do (If ((Terrain pathing at (Position of (Picked unit)) of type Walkability is off) Equal to True) then do (Unit - Explode (Picked unit)) else do (Do nothing))
      • Custom script: call DestroyGroup(udg_Landing_Tactician)

but it still can expire while the unit is over a building and then the unit is stuck in the building. haven't figured out how to fix this... thanks!
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,540
There's no need for that Unit Group and Periodic Interval.

You can detect when a unit turns Chemical Rage On/Off with the Event: A unit Is issued an order with no target. Then check if Issued Order equal to "chemicalrage" in your conditions.

Keep in mind that at this stage of the Event your unit is still considered as it's previous form, meaning it hasn't Morphed just yet but it's about to. With this in mind you may need to add a 0.00 second Wait before you can properly interact with the NEW form of your Morphing unit. In my triggers case this wasn't an issue.

Here's the solution:
1) When Chemical Rage goes off check if your unit is a flying unit. If it IS a flying then then we know that your unit is morphing back into a ground unit.
2) Create an Item at the position of your Morphing unit. Warcraft 3's pathing system will kick in and shove the item to the nearest "pathable" location.
3) After creating the item, move the Unit to the position of the Item and then Remove the Item. However, we cannot use the standard "Move unit instantly to point" method, as this screws things up, instead, we need to rely on Custom Script and set the Morphing unit's X/Y coordinates to the X/Y coordinates of our Item.

This sounds complicated but it's actually rather simple. The trigger should help clear things up:

  • Morph End
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(chemicalrage))
      • ((Triggering unit) is A flying unit) Equal to True
    • Actions
      • Set VariableSet TempPoint[1] = (Position of (Triggering unit))
      • Item - Create Claws of Attack +15 at TempPoint[1]
      • Set VariableSet TempPoint[2] = (Position of (Last created item))
      • Set VariableSet X = (X of TempPoint[2])
      • Set VariableSet Y = (Y of TempPoint[2])
      • Item - Remove (Last created item)
      • -------- --------
      • -------- Move the unit using x/y coordinates. This method doesn't interrupt the "chemicalrage" order which would otherwise cause issues --------
      • Custom script: call SetUnitX(GetTriggerUnit(), udg_X)
      • Custom script: call SetUnitY(GetTriggerUnit(), udg_Y)
      • -------- --------
      • Custom script: call RemoveLocation (udg_TempPoint[1])
      • Custom script: call RemoveLocation (udg_TempPoint[2])
Variables:
X = Real
Y = Real
TempPoint = Point (Array)
 

Attachments

  • Morph Pathing.w3m
    18 KB · Views: 16
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
I discovered movement type none which makes the ability do what I had originally envisioned, and with this it kind of makes sense to be able to get stuck in buildings. so the only thing I still wanted to do was change this trigger like you suggested to not be periodic. and that's when it bugged out in a really weird way. I have all 3 levels of the ability morphing into the same unit type (as opposed to alchemist who has 3 levels of morph forms). for some reason when I tested this trigger it only worked when the ability is level 2 or 3, level 1 survived (I double checked and all levels of the ability morph to the same unit). I'm really baffled on this one.

  • drown
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(chemicalrage))
      • (Unit-type of (Triggering unit)) Equal to Slippery Tactician (Morph level 1) (Morph level 1)
      • (Terrain pathing at (Position of (Triggering unit)) of type Walkability is off) Equal to True
    • Actions
      • Unit - Explode (Triggering unit)
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,540
You're leaking a Point when you do "Position of (Triggering unit)" in your conditions.

Try this:
  • Drown
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(chemicalrage))
        • Or - Any (Conditions) are true
          • (Unit-type of (Triggering unit)) Equal to Slippery Tactician
          • (Unit-type of (Triggering unit)) Equal to Slippery Tactician (Morph level 1) (Morph level 1)
    • Actions
    • Set VariableSet TempPoint = (Position of (Triggering unit))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Terrain pathing at TempPoint of type Walkability is off) Equal to True
      • Then - Actions
        • Unit - Explode (Triggering unit).
      • Else - Actions
    • Custom script: call RemoveLocation (udg_TempPoint)
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
  • Events
    • Unit - A unit Is issued an order with no target
  • Conditions
    • (Issued order) Equal to (Order(chemicalrage))
    • (Real((Level of Squeeze Through for (Triggering unit)))) Greater than 0.00
  • Actions
    • Set TempPoint = (Position of (Triggering unit))
    • If ((Terrain pathing at TempPoint of type Walkability is off) Equal to True) then do (Unit - Explode (Triggering unit)) else do (Do nothing)
    • Custom script: call RemoveLocation (udg_TempPoint)
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
why? for the simple reason that I don't really get what they are and how they compare...:ogre_hurrhurr:... but I changed that and that level one hero is still just standing there in the deep water with a smug grin on his face...

I found one clue as to what might be causing this - in the object editor, "targets allowed" for level 1 was originally "self"while the other ones had no targets, as is true for chemical rage. I changed this so all of them are with no target, but it could have to do with the original coding of chemical rage...

I just tried using this - I added an event of targeting an object, and i tried the ability both in the current form and with that field restored to self - both did not help... :huh:
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,540
  • Morph End
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(chemicalrage))
      • ((Triggering unit) is A flying unit) Equal to True
    • Actions
      • Set VariableSet TempPoint[1] = (Position of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Terrain pathing at TempPoint[1] of type Walkability is off) Equal to True
        • Then - Actions
          • Unit - Explode (Triggering unit).
        • Else - Actions
      • Custom script: call RemoveLocation (udg_TempPoint[1])
I tested this trigger out and it works fine. Not sure what's going on with yours.

  • Morph End
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(chemicalrage))
      • (Level of Chemical Rage for (Triggering unit)) Greater than 0
    • Actions
      • Set VariableSet TempPoint[1] = (Position of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Terrain pathing at TempPoint[1] of type Walkability is off) Equal to True
        • Then - Actions
          • Unit - Explode (Triggering unit).
        • Else - Actions
      • Custom script: call RemoveLocation (udg_TempPoint[1])
This one worked as well, with Chemical Rage morphing into the same (Level 1) unit for all 3 Levels. It worked on all 3 Levels.

Why can't you use Flying movement instead of None? Maybe that's the issue.
 
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
Very strange... maybe because I'm using archaic software... maybe because I messed around with the unit values too much, maybe just a bug. I tried both of your suggestions and any variety I could think of and the only thing that works consistently is the one with the periodic timer that i posted at the top...

Why can't you use Flying movement instead of None?

just because it looked better for the ability to have the unit waking on the ground and not through the air, but this made no difference in terms of the triggers.

how bad is it to keep as a periodic? I know it's not ideal but this doesn't seem like a very cpu (or whatever the right term is) heavy trigger... no? anyhow it seems like I don't really have many other options...
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,540
I would say try adding a 0.00 second Wait before you Explode the unit, and if that still fails then go for your Periodic Timer setup.

Also, have you tried using just the "chemicalrage' Order conditon, no unit-type checks or other stuff?

And feel free to upload your map or PM me your map (you can create a Pastebin for it to attach it in PMs) if you want me to take a quick look.
 
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
for the sake of anyone else who this can help I'll post the solutions that @Uncle found for me. this is to morph into a form that can walk through walls, but so it will die when it morphs back while under deep water:

Alright, Chemical Rage is just a buggy mess or something. I found a workaround though.
  • Squeeze Through
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Squeeze Through
    • Actions
      • Wait 0.00 seconds
      • Unit - Turn collision for (Triggering unit) Off.
      • Wait (5.00 x (Real((Level of (Ability being cast) for (Triggering unit))))) seconds
      • Unit - Turn collision for (Triggering unit) On.
      • Set VariableSet TempPoint = (Position of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Terrain pathing at TempPoint of type Walkability is off) Equal to True
        • Then - Actions
          • Unit - Explode (Triggering unit).
        • Else - Actions
      • Custom script: call RemoveLocation (udg_TempPoint)
I also edited some of the fields on the Squeeze Through ability. I set the Duration Normal to 0.00, and ticked on "Immediate Take Off" and "Immediate Landing". Not sure if all of those changes were necessary, but it works so I wouldn't mess with it.

Oh and make sure the Morph version of your Hero doesn't have None for it's Movement Type since i'm turning off it's collision through triggers. The Morph version should be similar to the normal Hero version (you can still add movement speed and other stats to it but don't mess with Movement Type).

also, while with no collision the unit can walk past the map borders, so this is a quick way to stop that from happening:

  • Leave Bounds
    • Events
      • Unit - A unit leaves (Playable map area)
    • Conditions
    • Actions
      • Set VariableSet TempPoint1 = (Position of (Triggering unit))
      • Set VariableSet TempPoint2 = (Center of (Playable map area))
      • Set VariableSet TempPoint3 = (TempPoint1 offset by 50.00 towards (Angle from TempPoint1 to TempPoint2) degrees.)
      • -------- --------
      • Unit - Move (Triggering unit) instantly to TempPoint3
      • -------- --------
      • Custom script: call RemoveLocation (udg_TempPoint1)
      • Custom script: call RemoveLocation (udg_TempPoint2)
      • Custom script: call RemoveLocation (udg_TempPoint3)
 
Status
Not open for further replies.
Top