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

GUI Knockback System (Non-MUI, "PUI")

Level 15
Joined
Sep 3, 2006
Messages
1,738
GUI Knockback System
by: En_Fuego

This is a GUI Knockback System I made for wc3Creations without realizing that the Hiveworkshop lacked one. It is not MUI but it is "PUI" (not sure if that's actually a term). "PUI", for those of you who don't know, is when it can be used by multiple players at the same time but those players can't individually have multiple units use it. It is easily done by using Arrays for your variables.
I won't do much in explaining the actual code itself, but I will explain how editing the code in different places can change the effects, speed, and distance.

First, I'll start off with what this code does. It creates a single-target spell that moves a unit backwards from the spot where it was hit, making it look like it took a severe amount of damage. In addition, any units the unit makes contact along the way are also pushed and take damage. Now, we'll start:

Before we start with the actual code, you'll need to create some variables:
Code:
Kinteger - Integer Array[12] - 0
Knockbackcasting - Unit Array[12] - none
Knockbackdegrees - Real Array[12] - 0
Knockbackdegrees2 - Real Array[12] - 0
Knockbackedunit - Unit Array[12] - none
Knockbackedunitpoint - Point Array[12] - none
Knockbackedunits - Unit Group Array[12] - empty
Knockbacklevel - Integer Array[12] - 0
Knockbackpoint - Point Array[12] - none
Knockbacktarget - Unit Array[12] - none
Knockbacktargetpoint - Point Array[12] - none
Knockbacktargetpointcheck - Point Array[12] - none
Knockbacktargetpointcheck2 - Point Array[12] - none


  • Knockback
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Knockback
    • Actions
      • Set Knockbacklevel[(Player number of (Owner of (Casting unit)))] = (Level of Knockback for (Casting unit))
      • Set Knockbackpoint[(Player number of (Owner of (Casting unit)))] = (Position of (Casting unit))
      • Set Knockbacktarget[(Player number of (Owner of (Casting unit)))] = (Target unit of ability being cast)
      • Set Knockbackcasting[(Player number of (Owner of (Casting unit)))] = (Casting unit)
      • Set Knockbacktargetpoint[(Player number of (Owner of (Casting unit)))] = (Position of (Triggering unit))
      • Set Kinteger[(Player number of (Owner of (Casting unit)))] = 0
      • Unit - Turn collision for Knockbacktarget[(Player number of (Owner of (Casting unit)))] Off
This trigger sets all of our values that we're going to need. It's basically the pre-trigger. It tells us what unit is being targetted, where that unit is, and it allows us to calculate where the unit will be knockbacked to.
  • Knockback more
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set Knockbackdegrees[(Integer A)] = (Angle from Knockbackpoint[(Integer A)] to Knockbacktargetpoint[(Integer A)])
          • Set Knockbacktargetpointcheck2[(Integer A)] = (Position of Knockbacktarget[(Integer A)])
          • Set Knockbacktargetpointcheck[(Integer A)] = (Knockbacktargetpointcheck2[(Integer A)] offset by 125.00 towards Knockbackdegrees[(Integer A)] degrees)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Kinteger[(Integer A)] Less than 80
              • ((Playable map area) contains Knockbacktargetpointcheck[(Integer A)]) Equal to True
            • Then - Actions
              • Unit Group - Pick every unit in Knockbackedunits[(Integer A)] and do (Actions)
                • Loop - Actions
                  • Unit - Turn collision for (Picked unit) On
              • Custom script: call DestroyGroup(udg_Knockbackedunits[GetForLoopIndexA()])
              • Custom script: call RemoveLocation(udg_Knockbacktargetpoint[GetForLoopIndexA()])
              • Special Effect - Create a special effect at Knockbacktargetpointcheck2[(Integer A)] using Abilities\Spells\Human\FlakCannons\FlakTarget.mdl
              • Set Smokeeffect = (Last created special effect)
              • Special Effect - Destroy Smokeeffect
              • Unit - Cause Knockbackcasting[(Integer A)] to damage Knockbacktarget[(Integer A)], dealing 2.00 damage of attack type Chaos and damage type Normal
              • Set Knockbacktargetpoint[(Integer A)] = (Knockbacktargetpointcheck2[(Integer A)] offset by 10.00 towards Knockbackdegrees[(Integer A)] degrees)
              • Unit - Move Knockbacktarget[(Integer A)] instantly to Knockbacktargetpoint[(Integer A)]
              • Set Knockbackedunits[(Integer A)] = (Units within 90.00 of (Knockbacktargetpointcheck2[(Integer A)] offset by 50.00 towards Knockbackdegrees[(Integer A)] degrees) matching ((((Matching unit) belongs to an enemy of (Player((Integer A)))) Equal to True) and ((Matching unit) Not equal to Knockback
              • Unit Group - Pick every unit in Knockbackedunits[(Integer A)] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Playable map area) contains Knockbackedunitspoint[(Integer A)]) Equal to True
                      • Knockbacktarget[(Integer A)] Not equal to No unit
                    • Then - Actions
                      • Set Knockbackedunit[(Integer A)] = (Picked unit)
                      • Set Knockbackedunitpoint[(Integer A)] = (Position of (Picked unit))
                      • Set Knockbackdegrees2[(Integer A)] = (Angle from Knockbacktargetpoint[(Integer A)] to Knockbackedunitpoint[(Integer A)])
                      • Set Knockbackedunitspoint[(Integer A)] = (Knockbackedunitpoint[(Integer A)] offset by 10.00 towards Knockbackdegrees2[(Integer A)] degrees)
                      • Unit - Turn collision for (Picked unit) Off
                      • Unit - Move (Picked unit) instantly to Knockbackedunitspoint[(Integer A)]
                      • Unit - Cause Knockbackcasting[(Integer A)] to damage Knockbacktarget[(Integer A)], dealing 1.00 damage of attack type Chaos and damage type Normal
                      • Unit - Cause Knockbackcasting[(Integer A)] to damage (Picked unit), dealing 1.00 damage of attack type Chaos and damage type Normal
                      • Special Effect - Create a special effect at Knockbackedunitpoint[(Integer A)] using Abilities\Spells\Human\FlakCannons\FlakTarget.mdl
                      • Set Smokeeffect = (Last created special effect)
                      • Special Effect - Destroy Smokeeffect
                      • Custom script: call RemoveLocation(udg_Knockbackedunitpoint[GetForLoopIndexA()])
                      • Custom script: call RemoveLocation(udg_Knockbackedunitspoint[GetForLoopIndexA()])
                    • Else - Actions
                      • Do nothing
              • Set Kinteger[(Integer A)] = (Kinteger[(Integer A)] + 1)
            • Else - Actions
              • Unit Group - Pick every unit in Knockbackedunits[(Integer A)] and do (Unit - Turn collision for (Picked unit) On)
              • Unit - Turn collision for Knockbacktarget[(Player number of (Owner of (Casting unit)))] On
              • Set Knockbacktarget[(Integer A)] = No unit
              • Custom script: call RemoveLocation(udg_Knockbackpoint[GetForLoopIndexA()])
              • Set Kinteger[(Integer A)] = (Kinteger[(Integer A)] + 1)
          • Custom script: call RemoveLocation(udg_Knockbacktargetpointcheck2[GetForLoopIndexA()])
          • Custom script: call RemoveLocation(udg_Knockbacktargetpointcheck[GetForLoopIndexA()])
This trigger is the actual knockback. It picks the unit that was saved in the first variable every 0.04 seconds, creates an effect, and moves the unit. To change the movement rate, you want to edit the Event time and make it lower (less than 0.04) to be quicker or higher (more than 0.04) to be slower. If you want to change the distance the unit moves, you'll need to edit the third line of code where the offset is. You can either make it higher or lower. I suggest if anything, to keep it less than 70, otherwise it gets very choppy. To change the special effect, change the value of the smokeeffect variable.

This may be a lot to take in, but it's actually very easy once you start coding it. I'll add a demo-map along with it in case you need it.
 

Attachments

  • GUI Knockback System.w3x
    22.5 KB · Views: 59
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
Some people use PUI, some use MPI.

To En_Fuego, have an Integer A loop from, say, 1 to 200, and assign each knockbacked unit a value based on an integer called CurrentIndex. When CurrentIndex passes the maximum (200 in this case), reset it to 1.

Then, in the periodic trigger, just loop from 1 to 200, or whichever values you used.

  • 1
    • Actions
      • Set CurrentIndex = CurrentIndex + 1
      • If ..
        • If
          • CurrentIndex Greater than 200
        • Then
          • Set CurrentIndex = 0
        • Else
      • Set someData[CurrentIndex] = someValue
  • 2
    • Events
      • Time - Every .03 seconds of Game Time
    • Actions
      • For Each Integer A from 1 to 200, do Actions
        • Loop - Actions
 
Top