- This system allows you to apply knockback to units with a decreasing speed (deceleration).
- It would add "realistic" to the gameplay by using this simple system.
- It is in GUI !
- Will add more features, perhaps this system will change its name
HOW TO USE
External Instructions
- Open World Editor > File - Preferences... > General Tab > Tick the Automatically create unknown variables while pasting trigger data
- Copy the Simple Frictional Knockback System folder.
Internal Instructions
- There are 5 variables which you can manipulate;
* FK_KnockbackUnit - The unit that is going to be knockbacked
* FK_KnockbackAngle - The angle which the unit will be knockbacked
* FK_KnockbackFriction - The knockback friction per second
* FK_KnockbackSpeed - The knockback speed per second
* FK_KnockbackSFX - The Special Effect for the knockback (make sure that the SFX model does not has any animation duration such as; birth, stand, death, etc)
- Further instructions are inside Trigger Comments: HOW TO USE (PAGE 1 & 2)
TRIGGERS
FK Loop
Events Conditions Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(FK_Group is empty) Equal to True
Then - Actions
Trigger - Turn off (This trigger)
Else - Actions
Unit Group - Pick every unit in FK_Group and do (Actions)
Loop - Actions
Custom script: local real x Custom script: local real y Set FK_KnockbackUnit = (Picked unit) Custom script: set udg_FK_Key = GetHandleId(udg_FK_KnockbackUnit) Set FK_KnockbackSpeedPerInterval = (Load 0 of FK_Key from FK_Hashtable) If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
FK_KnockbackSpeedPerInterval Greater than 0.00
Then - Actions
Set FK_KnockbackAngle = (Load 3 of FK_Key from FK_Hashtable) Custom script: set x = GetUnitX(udg_FK_KnockbackUnit) + udg_FK_KnockbackSpeedPerInterval * Cos(udg_FK_KnockbackAngle * bj_DEGTORAD) Custom script: set y = GetUnitY(udg_FK_KnockbackUnit) + udg_FK_KnockbackSpeedPerInterval * Sin(udg_FK_KnockbackAngle * bj_DEGTORAD) Custom script: call SetUnitX(udg_FK_KnockbackUnit, x) Custom script: call SetUnitY(udg_FK_KnockbackUnit, y) Special Effect - Create a special effect attached to the origin of FK_KnockbackUnit using (Load 4 of FK_Key from FK_Hashtable) Special Effect - Destroy (Last created special effect) Unit - Order FK_KnockbackUnit to Stop Hashtable - Save (FK_KnockbackSpeedPerInterval - (Load 1 of FK_Key from FK_Hashtable)) as 0 of FK_Key in FK_Hashtable
Else - Actions
Hashtable - Clear all child hashtables of child FK_Key in FK_Hashtable Unit Group - Remove FK_KnockbackUnit from FK_Group
FK Setup
Events
Map initialization
Conditions Actions
Custom script: set udg_FK_Hashtable = InitHashtable() Set FK_IntervalPerMove = 0.03 Set TempLoc = (Center of (Playable map area)) Set TempLoc2 = TempLoc Custom script: call RemoveLocation(udg_TempLoc) Trigger - Add to FK Loop <gen> the event (Time - Every FK_IntervalPerMove seconds of game time)
FK Save
Events
Conditions
Actions
Set FK_KnockbackSpeedPerInterval = (FK_KnockbackSpeed x FK_IntervalPerMove)
Set FK_KB_FrictionPerInterval = ((FK_KnockbackFriction x FK_IntervalPerMove) x FK_IntervalPerMove)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(FK_TempGroup is empty) Equal to False
Then - Actions
Unit Group - Pick every unit in FK_TempGroup and do (Actions)
Loop - Actions
Set FK_KnockbackUnit = (Picked unit)
Custom script: set udg_FK_Key = GetHandleId(udg_FK_KnockbackUnit)
Hashtable - Save FK_KnockbackSpeedPerInterval as 0 of FK_Key in FK_Hashtable
Hashtable - Save FK_KB_FrictionPerInterval as 1 of FK_Key in FK_Hashtable
Hashtable - Save Handle OfFK_KnockbackUnit as 2 of FK_Key in FK_Hashtable
Hashtable - Save FK_KnockbackAngle as 3 of FK_Key in FK_Hashtable
Hashtable - Save FK_KnockbackSFX as 4 of FK_Key in FK_Hashtable
Unit Group - Add FK_KnockbackUnit to FK_Group
Custom script: call RemoveLocation(udg_TempLoc2)
Custom script: call RemoveLocation(udg_TempLoc)
Else - Actions
Custom script: set udg_FK_Key = GetHandleId(udg_FK_KnockbackUnit)
Hashtable - Save FK_KnockbackSpeedPerInterval as 0 of FK_Key in FK_Hashtable
Hashtable - Save FK_KB_FrictionPerInterval as 1 of FK_Key in FK_Hashtable
Hashtable - Save Handle OfFK_KnockbackUnit as 2 of FK_Key in FK_Hashtable
Hashtable - Save FK_KnockbackAngle as 3 of FK_Key in FK_Hashtable
Hashtable - Save FK_KnockbackSFX as 4 of FK_Key in FK_Hashtable
Unit Group - Add FK_KnockbackUnit to FK_Group
Custom script: call DestroyGroup(udg_FK_TempGroup)
Trigger - Turn on FK Loop <gen>
[/trigger]
v1.1
- Friction calculation has been shortened
- Dead units still gets knockbacked (realism)
- Optimized some variable into caching them
v1.11
- Fixed some importing method
Rating - 0.00 (0 votes)
(Hover and click)
Moderator Comments
Not Rated
22:31, 22nd Aug 2012
Magtheridon96:
Comments
Since you're creating 1 special effect 32x times a second, you may end up causing lag. In order to reduce the amount of lag, you can create special effects half the time, or maybe even a third of the time.
Look:
Example
if randomInteger(0, 2) == 0 then
// create special effect
endif
You don't need to have the local reals x and y since you're only referencing them once. If you're referencing locals only once, then you don't need them.
You can cache the Cos/Sin values into the hashtable so you don't have to avoid retrieving the constant value in the loop during every single iteration. It's more efficient this way because Cos/Sin are heavy function calls despite their short name. (Optional)
Set FK_KB_FrictionPerInterval = (FK_KnockbackFriction x FK_IntervalPerMove) Set FK_KB_FrictionPerInterval = (FK_KB_FrictionPerInterval x FK_IntervalPerMove)
Put it into one line, no point doing it twice.
Unit - Order FK_KnockbackUnit to Stop
Why?
FK Key
Events Conditions Actions
Custom script: set udg_FK_Key = GetHandleId(udg_FK_KnockbackUnit)
Is this necessary? I mean you already do that here in FK Save:
Custom script: set udg_FK_Key = GetHandleId(udg_FK_KnockbackUnit)
Custom script: local real x
Wether these were locals or not wouldn't make any difference to the system and I get the feeling that for good practice they should be created outside of the group pick, since you're just making lots of locals when you only need one of each (x and y)
(FK_KnockbackUnit is alive) Equal to True
For realism, a dead unit wouldn't stop moving just because it died.
Load "LoadReal(udg_FK_Hashtable, udg_FK_Key, 3)" into another variable before doing anything with it. you call it twice so it's less efficient to load the same value from a hashtable twice.
Top of the actions where exactly baassee ?
Did you tried it yet ?
I tried, but it compiles error, I have talked with WaterKnight with this issues, locals must be declared inside the Unit Group action.
If you already tried it and succeed, please do share the code.
Ah that's true, cause of engine I guess - cannot allocate the local within an if. ops forgot, enumeration creates a whole new function thus the locals have to be declared within that enum func ^^
anyway, these two parts should be stored into the hashtable as well as they are always the same
Well, I would like to say on the grounds of using stop, other than stopping them from going out of bounds, I was mostly referring to the doctrine as to why you were disabling their functions, since interrupting orders isn't the most useful of things to do and stun/slow/etc. in the actual WC3 does not prevent orders, and knockback isn't really a "disable" thing. I'd suggest just putting the checking for map bounds in so that their orders aren't cancelled, guess it's preferential, but I'd still have a boolean in the "system" to allow you to enable/disable the stop being run and cancelling orders.
Just one suggestion - create a configurable variable that sets where the special effect is spawned. Some people might want it to be on the head, no the origin which makes absolutely no sense but it will be good if you put this... just in case.