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

Knock Back 3D Help

Status
Not open for further replies.
Level 10
Joined
Sep 25, 2013
Messages
521
I’m using T.D.W’s knockback system to have ranged units knock back the units that they hit. The problem is when multiple ranged units hit the same target the knock back effect stacks and sends the hit unit flying. I want units that have been knocked back to be immune to further knock back effects for duration. So if a bunch of ranged units hit a unit, only the first hit will register and the unit can’t be knocked back again until a duration expires. I’m not good at triggers and the triggers are all JASS so if anyone can help me implement this function I’d be grateful. I would have asked the creator of the system for help but he hasn’t been on since 2018
Link to T.D.W’s knockback system
Knock-Back 3D - MMS 3D V. 3.2.1
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
You can add the unit to a unit group before executing the system's knockback function. And remove the unit via user-defined end trigger (runs after the knockback ends). I believe there's also a dedicated feature to let the user input such triggers during knockback, afaik.

Edit: Found out that you can identify if the unit is currently in knockback state via boolean condition. Use this method first, if it fails then use the method above. I suggest reading the system's configuration guide and features furthermore.
 
Last edited:
Level 10
Joined
Sep 25, 2013
Messages
521
So add the unit to a unit group, save a integer value to the unit in a hashtable, then run a periodic event which loads the integer value of each unit in the unit group and subtracts from that value and resaves it. Once the value reaches zero, remove the unit from the unit group? I wanted to do this but I cant figure out how to do this with the damage detection system.

  • Uruk Hai KnockBack Copy
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Uruk Bowman
      • (DamageEventTarget is A structure) Not equal to True
      • (DamageEventTarget is A Hero) Not equal to True
      • (DamageEventTarget is Mechanical) Not equal to True
      • (DamageEventTarget has buff Knock Back ) Not equal to True
    • Actions
      • Set VariableSet TempPoint = (Position of DamageEventTarget)
      • Set VariableSet KB3D_Unit = DamageEventTarget
      • Set VariableSet KB3D_Range = 200.00
      • Set VariableSet KB3D_Speed = 800.00
      • Set VariableSet KB3D_Accel = 0.00
      • Set VariableSet KB3D_Zoffset = 100.00
      • Set VariableSet KB3D_StopTime = 0.00
      • Set VariableSet KB3D_KillatTime = 0.00
      • Set VariableSet KB3D_Angle = (Angle from (Position of DamageEventSource) to (Position of DamageEventTarget))
      • Set VariableSet KB3D_Fx = Objects\Spawnmodels\Undead\ImpaleTargetDust\ImpaleTargetDust.mdl
      • Set VariableSet KB3D_TrailFx = <Empty String>
      • Set VariableSet KB3D_EndFx = <Empty String>
      • Set VariableSet KB3D_AoEKB = False
      • Set VariableSet KB3D_EndwhenDead = False
      • Set VariableSet KB3D_KBTarget = False
      • Set VariableSet KB3D_KillatEnd = False
      • Set VariableSet KB3D_AllowOutSiding = False
      • Set VariableSet KB3D_DestroyTree = False
      • Set VariableSet KB3D_DisableUnit = True
      • Set VariableSet KB3D_EndWhenHit = False
      • Set VariableSet KB3D_FaceAngle = False
      • Set VariableSet KB3D_Attach = origin
      • Set VariableSet KB3D_iKB = True
      • Set VariableSet KB3D_KillWhenHit = False
      • Set VariableSet KB3D_KillifOutSider = False
      • Set VariableSet KB3D_UnpathableStop = True
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Game - Display to (All players) the text: (Travel Time: + ((String(KB3D_Time)) + s))

I can't explain this very well since I hardly know what I'm talking about, but when I try saving an integer value as 0 of the key of a unit, I can't since there's no option to choose a unit variable as a key. So I cant choose (key(DamageEventTarget).)
I can choose the key Triggering Unit function (I guess that's called a native, idk?) but there is no triggering unit for this trigger. Maybe I could create a temp unit group of all units in playable map area and then add an if than else which checks if picked units are the damage event target.

upload_2020-2-13_23-27-39.png
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
You don't need an integer or counter for this. Just make sure before adding a unit check if the unit group contains the unit (in this case DamageEventTarget) if it's false then add it. Make another trigger and refer it to the KB3D_EndTrigger variable. You can use the system unit variables on this trigger as the system calls it. Check if the unit is dead or still contained in a unit group then remove it inside that trigger. Did you try the boolean condition I stated in my edited post above?

Edit: Getting handle Id of a unit with no unit variables defined in a selection seems odd :/. However, we can use custom script for that... a simple line of
  • Custom Script: if not LoadBoolean(udg_KB3D_HA, GetHandleId(udg_DamageEventTarget), GetHandleId(udg_DamageEventTarget)) then
at the top of your variable 'TempPoint' should do the trick. Don't forget to include
  • Custom Script: endif
line at the very end of your trigger.
 
Last edited:
Level 10
Joined
Sep 25, 2013
Messages
521
Thanks for your help. I couldn't find the boolean condition which checks if a unit is currently in knockback state. I read through the information provided by the system creator. I'll reread and try to understand. I don't know what you mean when you say "Make another trigger and refer it to the KB3D_EndTrigger variable. You can use the system unit variables on this trigger as the system calls it."
Would this separate trigger be a periodic event? Or what would be the event on this trigger which checks if a unit is still part of the knockback unit group? I'm not sure I'm going to be able to understand so if I don't get it after your next response don't worry about it.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
I already provided the custom script that contains the boolean condition... You should try it. It's on my previous edited post.

Edit: You don't need such event in the seperated end trigger as the ending of the knockback is already the event for it. Which means the end trigger will be executed once the knockback is finished. Probably, you'll create such conditions and actions that will check if the unit is part of the knockbacked group then remove it. You can refer this unit as KB3D_Unit. The method is already shown in the system demo map. You can check the Zap Missile ability for using this kind of feature.
 
Last edited:
Level 10
Joined
Sep 25, 2013
Messages
521
I Did try using the custom script. I don't know where to place it. I know you explained to place it at the beginning of my trigger and the place the "endif" custom script at the end, but i don't understand what these are supposed to do. the script says "if not", i don't understand, "if not" what? Does the script go in the main trigger and is supposed to test if a unit is Knockbacked from there, or does it go in the separate end trigger and test something else? Cause I don't see how the script is checking if a unit is being knockedback, it seems to say nothing about it. Its getting the handle ID of the triggering unit i guess, but after that what am supposed to put? I'm sorry but I am terribly bad at this, I'm not trying to be rude, I am trying to understand.

  • Uruk Hai KnockBack Copy
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Uruk Bowman
      • (DamageEventTarget is A structure) Not equal to True
      • (DamageEventTarget is A Hero) Not equal to True
      • (DamageEventTarget is Mechanical) Not equal to True
      • (DamageEventTarget is in KnockBackUnitGroup.) Equal to False
    • Actions
      • Set VariableSet TempUnitGroup = (Units in (Playable map area))
      • Unit Group - Pick every unit in TempUnitGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Picked unit) Equal to DamageEventTarget
            • Then - Actions
              • Unit Group - Add (Picked unit) to KnockBackUnitGroup
            • Else - Actions
      • Custom script: call DestroyGroup (udg_TempUnitGroup)
      • Custom script: if not LoadBoolean (udg_KB3D_HA, GetHandleId(udg_DamageEventTarget), GetHandleId(udg_DamageEventTarget)) then
      • Set VariableSet TempPoint = (Position of DamageEventTarget)
      • Set VariableSet KB3D_Unit = DamageEventTarget
      • Set VariableSet KB3D_Range = 200.00
      • Set VariableSet KB3D_Speed = 800.00
      • Set VariableSet KB3D_Accel = 0.00
      • Set VariableSet KB3D_Zoffset = 100.00
      • Set VariableSet KB3D_StopTime = 0.00
      • Set VariableSet KB3D_KillatTime = 0.00
      • Set VariableSet KB3D_Angle = (Angle from (Position of DamageEventSource) to (Position of DamageEventTarget))
      • Set VariableSet KB3D_Fx = Objects\Spawnmodels\Undead\ImpaleTargetDust\ImpaleTargetDust.mdl
      • Set VariableSet KB3D_TrailFx = <Empty String>
      • Set VariableSet KB3D_EndFx = <Empty String>
      • Set VariableSet KB3D_AoEKB = False
      • Set VariableSet KB3D_EndwhenDead = False
      • Set VariableSet KB3D_KBTarget = False
      • Set VariableSet KB3D_KillatEnd = False
      • Set VariableSet KB3D_AllowOutSiding = False
      • Set VariableSet KB3D_DestroyTree = False
      • Set VariableSet KB3D_DisableUnit = True
      • Set VariableSet KB3D_EndWhenHit = False
      • Set VariableSet KB3D_FaceAngle = False
      • Set VariableSet KB3D_Attach = origin
      • Set VariableSet KB3D_iKB = True
      • Set VariableSet KB3D_KillWhenHit = False
      • Set VariableSet KB3D_KillifOutSider = False
      • Set VariableSet KB3D_UnpathableStop = True
      • Set VariableSet KB3D_EndTrigger = ENDTRIGGER <gen>
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Custom script: endif
      • Game - Display to (All players) the text: (Travel Time: + ((String(KB3D_Time)) + s))

I added the custom script. I also added an action which adds the damagetarget to a unitgroup. A unit can only be knocked back if they havent yet been put in that unit group based on the condition above checking if the target is in that unit group or not. In the ENDTRIGGER I somehow need to remove this specific unit from the unitgroup I guess. I don't know what the custom script is doing here.

In the ENDTRIGGER trigger, I don't know what to do.
  • ENDTRIGGER
    • Events
    • Conditions
    • Actions

EDIT: OK, so i put the custom script where you said and disabled the who unit group stuff and it seems to work. The targeted unit can't be knock back stacked by multiple attackers. So thank you! I'm still going to try some periodic event thing because I want to see if I can make the target immune to knock backs for longer period of time after being knocked back and the knock back is complete, like 4 or 5 seconds maybe. I don't really understand how the script is working, but it is.
  • Uruk Hai KnockBack Copy
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Uruk Bowman
      • (DamageEventTarget is A structure) Not equal to True
      • (DamageEventTarget is A Hero) Not equal to True
      • (DamageEventTarget is Mechanical) Not equal to True
    • Actions
      • Custom script: if not LoadBoolean (udg_KB3D_HA, GetHandleId(udg_DamageEventTarget), GetHandleId(udg_DamageEventTarget)) then
      • Set VariableSet KB3D_Unit = DamageEventTarget
      • Set VariableSet KB3D_Range = 200.00
      • Set VariableSet KB3D_Speed = 800.00
      • Set VariableSet KB3D_Accel = 0.00
      • Set VariableSet KB3D_Zoffset = 100.00
      • Set VariableSet KB3D_StopTime = 0.00
      • Set VariableSet KB3D_KillatTime = 0.00
      • Set VariableSet KB3D_Angle = (Angle from (Position of DamageEventSource) to (Position of DamageEventTarget))
      • Set VariableSet KB3D_Fx = Objects\Spawnmodels\Undead\ImpaleTargetDust\ImpaleTargetDust.mdl
      • Set VariableSet KB3D_TrailFx = <Empty String>
      • Set VariableSet KB3D_EndFx = <Empty String>
      • Set VariableSet KB3D_AoEKB = False
      • Set VariableSet KB3D_EndwhenDead = False
      • Set VariableSet KB3D_KBTarget = False
      • Set VariableSet KB3D_KillatEnd = False
      • Set VariableSet KB3D_AllowOutSiding = False
      • Set VariableSet KB3D_DestroyTree = False
      • Set VariableSet KB3D_DisableUnit = True
      • Set VariableSet KB3D_EndWhenHit = False
      • Set VariableSet KB3D_FaceAngle = False
      • Set VariableSet KB3D_Attach = origin
      • Set VariableSet KB3D_iKB = True
      • Set VariableSet KB3D_KillWhenHit = False
      • Set VariableSet KB3D_KillifOutSider = False
      • Set VariableSet KB3D_UnpathableStop = True
      • Set VariableSet KB3D_EndTrigger = ENDTRIGGER <gen>
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Custom script: endif
      • Game - Display to (All players) the text: (Travel Time: + ((String(KB3D_Time)) + s))
 
Last edited:
Status
Not open for further replies.
Top