System Unit Knockback System

Reaction score
341
Unit Knockback System
TriggerHappy187


Current Version - v1.04

Hello everybody. I Was practicing structs and decided to make a Knockback System.... And i did! If you don't know what a knockback system does , it slides the unit back to a point , as if he was pushed. Anyways , this is my FIRST time using structs. I'm not done with this system.... yet. I'm looking to implement cliff detection , Destructible collision ( finished ). It only requires JassNewGen pack , it is not dependent of any other systems :) . Also please do not say "theres alot of these around...." , i know but i made this for fun and practice.

Changelog :
v1.00 Beta
  • Released
v1.01
  • Added Destructable Collision
v1.02
  • Fixed a problem were the count would screw up
  • Fixed the onDestroy Method
  • Removed a missed leak
v1.03
  • Now doesn't loop through unneeded instances
v1.04
  • Fixed a few leaks
  • Some minor coding fixes

Readme :
Installing this system is very easy.

First , download the demo map
Then Copy the folder UKS - Knockback System , in the trigger editor
Then open your map , and copy the triggers.

If your not sure how to use the system , check out the example provided with the triggers
Features :
  • Ground or Water Detection
  • GUI Friendly
  • Easy to set parameters
  • MUI (Hopefully)
  • Destructable Collision

Code :

JASS:
library UKS // Version 1.02

globals
    private constant boolean SHOW_EFFECT = true 
    // Show effect on unit when he gets knockbacked
    private constant boolean DESTROY = true
    // Set to yes if you want to destroy doodads
    private constant string EFFECT_POS = "origin" 
    // where on the unit to show the effect
    private constant string EFFECT_GROUND = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" 
    // The effect when a unit is knocked on ground
    private constant string EFFECT_WATER = "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl" 
    // The effect when a unit is knocked on water
    private constant real INTERVAL = 0.03 
    // How fast the timer will run periodicly
    private constant boolean IGNORE_PATHING = false
    // Allow the unit being moved to move over cliffs

   // End of Configurables. Necessary globals. \\

    private timer TIMER = CreateTimer() 
    private integer COUNT = 0
endglobals

private struct UKSData
    unit u
    real speed
    real dec
    real ticksMax
    real ticksCur
    location l
    static UKSData array List
    
    static method create takes unit u1, location l1, real speed1, real dec returns UKSData
        local UKSData d = UKSData.allocate()
        local real dx = GetUnitX(u1) - GetLocationX(l1)
        local real dy = GetUnitY(u1) - GetLocationY(l1)
        set d.l = l1
        set d.u = u1
        set d.speed = speed1
        set d.dec = dec
        set d.ticksMax = SquareRoot(dx * dx + dy * dy)
        set d.ticksCur = 0
        set .List[COUNT] = d
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        set .u = null
        call RemoveLocation(.l)
        set .l = null
    endmethod
    
endstruct

private function DestructGroup takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

private function DestroyDestruct takes unit u returns nothing
    local rect r
    local real centerX = GetUnitX(u)
    local real centerY = GetUnitY(u)
    local real radius = 90
    local location loc = GetUnitLoc(u)
    local boolexpr filter
    if (radius >= 0) then
        set bj_enumDestructableCenter = loc
        set bj_enumDestructableRadius = radius
        set r = Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
        set filter = filterEnumDestructablesInCircleBJ
        call EnumDestructablesInRect(r, filter, function DestructGroup)
        call DestroyBoolExpr(filter)
        call RemoveRect(r)
        call RemoveLocation(loc)
    endif
    set r = null
    set loc = null
    set filter = null
endfunction

private function MoveUnits takes nothing returns nothing
    local integer i = 0
    local UKSData d
    local real x
    local real y
    local real x1
    local real y1
    local real dx
    local real dy
    local real d2
    loop
        exitwhen i >= COUNT
        set d = UKSData.List<i>
        set x1 = GetUnitX(d.u)
        set y1 = GetUnitY(d.u)
        set dx = GetLocationX(d.l) - x1
        set dy = GetLocationY(d.l) - y1
        set d2 = SquareRoot(dx * dx + dy * dy)
        set x = x1 + d.speed * dx / d2
        set y = y1 + d.speed * dy / d2
        if IGNORE_PATHING == true then
          call SetUnitX(d.u, x)
          call SetUnitY(d.u, y)
        else
          call SetUnitPosition(d.u, x, y)
        endif
        
        if SHOW_EFFECT == true then
          if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
            call DestroyEffect(AddSpecialEffectTarget(EFFECT_GROUND, d.u, EFFECT_POS))
          elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
            call DestroyEffect(AddSpecialEffectTarget(EFFECT_WATER, d.u, EFFECT_POS))
          endif
        endif
        
        if DESTROY == true then
            call DestroyDestruct(d.u)
        endif
        
        set d.ticksCur = d.ticksCur + d.speed
        
        if d.speed - d.dec &gt;= 0.000 then
            set d.speed = d.speed - d.dec
        endif
        
        if d.ticksCur &gt;= d.ticksMax or d.ticksCur &lt;= 1 or d.speed &lt;= 1 then
            set COUNT = COUNT - 1
            set UKSData.List<i> = UKSData.List[COUNT]
            set i = i - 1
            if COUNT &lt;= 0 then
                call PauseTimer(TIMER)
                set COUNT = 0
            endif
            call UKSData.destroy (d)
        endif
        set i = i + 1
    endloop
endfunction

public function KnockUnit takes unit u, location l, real speed, real decrement returns nothing
    local UKSData d = UKSData.create(u,l,speed,decrement)
    set COUNT = COUNT + 1
    if COUNT == 1 then
       call TimerStart(TIMER, INTERVAL, true, function MoveUnits)
    endif
endfunction

endlibrary


</i></i>

Example GUI Use :

Trigger:
  • Example Use
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Knockback Unit
    • Actions
      • Wait 0.20 seconds
      • Set UKS_Unit = (Target unit of ability being cast)
      • Set UKS_Towards = ((Position of (Target unit of ability being cast)) offset by 500.00 towards (Facing of (Casting unit)) degrees)
      • Set UKS_Speed = 40.00
      • Set UKS_Decrement = 2.20
      • -------- Move Unit (unitvar) Towards (twards var), With the speed of (speedvar) and a decrement of (decrement var) --------
      • Custom script: call UKS_KnockUnit(udg_UKS_Unit,udg_UKS_Towards,udg_UKS_Speed, udg_UKS_Decrement)


Video Example :

[YOUTUBE]<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/cTTx4MgEZ08&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/cTTx4MgEZ08&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>[/YOUTUBE]
 

Attachments

  • UKS - Unit Knockback System.w3x
    21 KB · Views: 230
  • UKS - Unit Knockback System v1.01.w3x
    22.1 KB · Views: 230
  • UKS - Unit Knockback System v1.02.w3x
    21.1 KB · Views: 249
  • UKS - Unit Knockback System v1.03.w3x
    21.7 KB · Views: 288

Dr.Jack

That's Cap'n to you!
Reaction score
109
Well as it is, its a nice system, great job on the first one using structs. Also you move them all with one timer instead of one for each instance, which is great. Why are you using location and then convert it to coords? Just make the function take coords, most Jassers hate locs (and should :p).

JASS:
set COUNT = COUNT + 1


Bah! What about structs' recycling?

JASS:

if d -1 == COUNT then
    set COUNT = COUNT + 1
endif


That way you can have 8190 instances running at the same time.

JASS:
set COUNT = COUNT - 1


That's no good. Say I create struct 0,1,2,3 and I destroy 1 before 3? More like

JASS:
if d == COUNT then
    set COUNT = COUNT - 1
endif


JASS:
if DESTROY == true then
    call DestroyDestruct(d.u)
endif


No need to call another function here, does nothing but slow down the timer and annoy the reader. Also:

JASS:
local real radius = 90


I strongly suggest the radius speed * interval + 30 or something like that, having a constant integer for that can't be good.

JASS:
set .List[COUNT] = d


Why do you need that? Instead of:

JASS:
set d = UKSData.List


simply do:

JASS:
set d = i


With all the comment, this is a nice system indeed, good job. The only problem is, as you stated yourself, there are way too many around. :p
 

emjlr3

Change can be a good thing
Reaction score
395
this should probably be in the JAS section, since it requires more help then it provides...
 

emjlr3

Change can be a good thing
Reaction score
395
Ok so why would be ppl use this over our other KB systems?
 
Reaction score
341
Could be for several reasons.

1) How it looks compared to the others.
2) Because of how i made it GUI friendly , setting up a simple variable edit Example trigger.


EDIT : Version 1.03 released!
 

Joker(Div)

Always Here..
Reaction score
86
@...Because of how i made it GUI friendly , setting up a simple variable edit Example trigger.
You're using vJASS. That's already not GUI friendly. GUI users don't use NewGen editors.
 

Joker(Div)

Always Here..
Reaction score
86
Show me how it is easier to use than this. You can easily replace your function with his and it would still be the same level of difficulty. Plus, this is not MUI. You're limiting the instance to 1 with your integer COUNT in your KnockUnit function.
 
Reaction score
341
This is MUI. that only pauses/resumes the timer depending on if there are any instances.

Uberplayers System requires ABC , while mine requires nothing.
 

ReVolver

Mega Super Ultra Cool Member
Reaction score
609
Überplayer and emjlr3's KB systems are better IMO
 
Reaction score
341
:( , everyone has their opinion and i think emjlr3's has real math calculations. But i like mine because it looks nice and smooth , and because of its simplicity.
 

thewrongvine

The Evolved Panda Commandant
Reaction score
506
:) People, this is just another KB system. He's not saying it is better nor begging others to use it. He just submitted it as his own, not to prove anything.

Take it or leave it. Doesn't matter. But yes, that would not really be GUI friendly.

But good job anyway. :)
 

emjlr3

Change can be a good thing
Reaction score
395
there is no point to having multiple of the same thing in the directory, especially when they accomplish their goal in the same fashion - therefore, there is no reason to accept this
 
Reaction score
341
So variety is a bad thing?

The one in the Systems section is different from mine.

Im sure we use different methods on moving units. Uberplayerrs also runs one 1 timer per instance , while mine runs on 1 timer for all instances.
 

emjlr3

Change can be a good thing
Reaction score
395
its not variety, its repetitive
 

Viikuna

No Marlo no game.
Reaction score
265
It might look better if you use one loopping effect, instead of creating and destroying effects over and over again. Take a look of Rising Dusk´s knockback system, he has some cool effects in it.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top