# Knock-Back Lite

#### Bribe

Code Moderator
Level 48
JASS:
``````            call SetItemPosition(checkItem, x, y)
if((GetWidgetX(checkItem)+GetWidgetY(checkItem)-x-y)<=32) then
call SetUnitX(kb.subject, x)
call SetUnitY(kb.subject, y)
endif``````

gg

Level 18
What?

#### Berb

Level 18
I'm still not sure what you are specifically referring to.

#### Berb

Level 18
I didn't even see his post. You should have told me to read this page not the previous one. I have it being displayed on the same page, at least. Either way, yea I don't really know what he was talking about.

#### Bribe

Code Moderator
Level 48
Sorry, I think I've got it set to 50 posts per page (less clicking), and I forget that there are other setups that are used..

#### Miss_Foxy

Level 19
Is it possible to do this function in GUI too?

#### Berb

Level 18
If you're using JNGP then you could probably use it. You'll need to use some custom script though.

#### Bribe

Code Moderator
Level 48
There is a problem with the item check, actually.

JASS:
``((GetWidgetX(checkItem)+GetWidgetY(checkItem)-x-y)<=32)``

This would have to be:

JASS:
``RAbsBJ(GetWidgetX(checkItem)+GetWidgetY(checkItem)-x-y)<=32)``

Logic: when y or x are greater than the unit's coordinates, this will always return true because the product opposite 32 will be negative, though it could be -5400 and still return true (flawed).

Also, this is not retrieving the actual hypotenuse. Pythagorean Theorem is l2+l2 = h2, so squaring down is not done properly as Azlier requested you use, because a true conversion will still equate SqareRoot(l2+l2) = h. Thus, your original equation:
JASS:
``((iX-x)*(iX-x) + (iY-y)*(iY-y)) <= (32*32)``

Is the best approach, because it still holds the correct arithmatic.

#### Berb

Level 18
Indeed, I think that azlier just used some sort of equation masher to produce that and seeing as how he was only holding it back from approval based on these tiny mathematical inefficiencies so I just mindlessly succumbed to his dictation.

I'm going to change the equation back for now, though it is weird that I never experienced any real bugs with this. I suppose there may have been certain flaw in the knock-back, but I didn't notice anything different upon changing it and testing it thoroughly before adjusting the calculation.

#### sephiroth1234

Level 9
I was saying you weren't using SetUnitPosition.

JASS:
``````//use an item to check the pathability of the new coordinate and
//move the unit if the point is available``````

Read that comment move the unit if the point is available

I thought you are getting serious.... No joke.

#### Bribe

Code Moderator
Level 48
Items behave differently when you set their position from units. Plus, Berbanog moves the item first because moving the unit would cause some problems.

SetUnitPosition (not to be confused) also issues the unit a "Stop" command, whereas in Berbanog's method it does not. That's a big difference in functionality.

#### musk

Level 2
Right. Squareroots are positive values, not negatives. math properties.
(a^2)^0.5 = |a|

#### Bribe

Code Moderator
Level 48
Hey, awesome approach! That's way more efficient than `RAbsBJ`.

#### Berb

Level 18
Actually it may not be.

JASS:
``````function RAbsBJ takes real a returns real
if (a >= 0) then
return a
else
return -a
endif
endfunction``````

This is a fairly quick statement, while as:

JASS:
``````function Abs2 takes real a returns real
return SquareRoot(a*a)
endfunction``````

Would probably be a little slower because of the necessity of a function call, namely the `SquareRoot` function. I don't know the actual benchmarks, it is just a strong assumption.

I

#### Bribe

Code Moderator
Level 48
No, by using his method:

JASS:
``````function Abs2 takes real a returns real
return Pow(a*a, 0.5)
endfunction``````

Should be pretty speedy. It's very quick to type, at that.

#### Berb

Level 18
Benchmarks would really be the only way to prove definitely which one is faster. I can't imagine that using the `Pow` native for a square root would be any faster than using the `SquareRoot` native; and furthermore whether or not either of those natives would be faster than an if-statement.

#### Bribe

Code Moderator
Level 48
What I meant to do was to inline that to `Pow(x*x, 0.5)`. I'll get home today, so when I do I'll plug in those numbers and compare the two in the Benchmark library.

#### Bribe

Code Moderator
Level 48
When an air-unit is knocked back, he hits walls that are a thousand feet below him and gets locked in place.

Yeah, the item-position checking doesn't account for the fact that the guy is flying and doesn't require a pathing check

#### Bribe

Code Moderator
Level 48
`call SetItemVisible(checkItem, false)`

Why do you have that in the loop trigger? You never make it visible again, so you're spamming invisibility on it.

#### Berb

Level 18
When you use `SetItemPosition` it reveals the item.

#### Berb

Level 18
Yea, if you remove that line of code then you'll clearly see the item at the center of the map, or whatever the coordinates `checkItemX` and `checkItemY` are.

#### D4RK_G4ND4LF

Level 19
your pathcheking method could be improved

the item will stay at its place if it can't move anywhere else (like a cliff full of trees)
so x and y will be equal to the item coordinates and the unit will be stuck
use a second item for that and check if the coordinates are different from the coordinates of the first item

further items will be blocked by items so one can drop an item in front of oneself to stop the knockback
pick all items in the region, save and hide them, then apply the pathing check and then reveal the items again

and units can be knocked through all paths where only items would be able to fit through (don't know how to fix that in an efficient way)

#### Berb

Level 18
further items will be blocked by items so one can drop an item in front of oneself to stop the knockback
pick all items in the region, save and hide them, then apply the pathing check and then reveal the items again

I was going to finish up the pathing checking actually but since nobody really uses this I just didn't. I realize that there are some cases where the pathing check will present bugs, and I suppose (since they've been noticed) I will update the code to fix those cases.

and units can be knocked through all paths where only items would be able to fit through (don't know how to fix that in an efficient way)

Well the alternative is to use `IsTerrainPathable`, which is only going to take a single point; this would present far more of a problem when the passages that units are being knocked into are small.

the item will stay at its place if it can't move anywhere else (like a cliff full of trees)
so x and y will be equal to the item coordinates and the unit will be stuck
use a second item for that and check if the coordinates are different from the coordinates of the first item

This problem will only occur when a unit is placed in the midst of one of these zones that you are describing. Since knock-back must be applied to a unit, the item will never be placed in a zone as you are describing unless the unit is already there. I'll see what I can do, though. I was planning on fixing this up and became occupied with other things due to the lack of download interest. It seems people either use a crappy system like Dusk's knock-back library or they insist on making their own.

#### Bribe

Code Moderator
Level 48
A lot of it has to do with the fact that people aren't looking in here for resources. Put some of your systems in your signature so people know they exist to begin with. Advertising is what makes everything from garage sales to communism function.

I recommend you join up TheHelper.net, too. They could use a bright mind like yours there and it gives you more opportunities to flex and test your skills to have feedback from an additional community.

#### Berb

Level 18
I do have an account on TheHelper.net, and I have for quite some time. I was never really that active there, though, their forum isn't as well developed for this type of modding scene where there are just so many resources and so many areas of development.

By the way, my account name on TheHelper.net is xombie.

#### Bribe

Code Moderator
Level 48
I'm not sure what you mean about the development, but ok. Member since 2006? I just signed up there XD

In 2006 I was dicking around in the Battle.net forums discussing strategy under the alias CollectiveFury. I actually bought this game 1 month after it came out, but only picked up modding it last August.

I did a bit of modding for StarCraft's editor in 2001 or something; I was trying to make "billiards" with it but that GUI interface was just dust in the wind, baby. When I opened World Editor for the first time, I really freaked out because they added a third option to the trigger interface and I gave up without asking questions.

#### Berb

Level 18
The forum for Warcraft III modding is a lot smaller than a forum like this one or WC3 Campaigns. I don't really use forums to post things, other than random crap that I happen to script on a whiff, the other stuff is just vaulted into maps that I will likely not play much of, or will continue later.

I have been modding Warcraft III for... about 5 years.

#### D4RK_G4ND4LF

Level 19
Well the alternative is to use `IsTerrainPathable`, which is only going to take a single point; this would present far more of a problem when the passages that units are being knocked into are small.

the alternative would be SetUnitPosition or making a function which will find the next pathable point within a very big region so one can knockback a unit without having to care about terrain (which is much more realistic anyway) and then on ariving at the goal move it to some pathable point
also checking the target point in a triangular shape might be an idea but it's not nice enough for me
maybe there is a way (changing some mpq value so items have bigger collision size or something )

This problem will only occur when a unit is placed in the midst of one of these zones that you are describing. Since knock-back must be applied to a unit, the item will never be placed in a zone as you are describing unless the unit is already there.

I spend the last half hour finding a case where this would happen despite what you said and I found one
BRIDGES!!!! (there is no space between the end and the water)
and it might happen if the speed is rather high as well

and I just got a new idea
it might be best to check the path before the knockback even starts so it will be faster if the speed is less then 32 because you don't have to check the points between this and the problem with high speed won't occure

#### Berb

Level 18
the alternative would be SetUnitPosition or making a function which will find the next pathable point within a very big region so one can knockback a unit without having to care about terrain (which is much more realistic anyway) and then on ariving at the goal move it to some pathable point

I don't really know what you're saying here.

it might be best to check the path before the knockback even starts so it will be faster if the speed is less then 32 because you don't have to check the points between this and the problem with high speed won't occure

The problem with high speed occurs when a unit is moving fast enough to move "past" unpathable objects because both the current position of the unit and the next position of the unit are both perfectly valid positions, in terms of pathability - it is a point in between that is the problem.

This library (found here) performs all of the necessary checks to determine the pathability of a point. It uses an item, however, which would not solve the little problem regarding units being pushed back into places that are too small for them to fit. I don't know if it would better to hard-code it into the system or simply use that library.

#### musk

Level 2
JASS:
``````       set iX = GetWidgetX(checkItem) - x
set iY = GetWidgetY(checkItem) - y
if iX*iX + iY*iY <= 32) then
call SetUnitX(kb.subject, x)
call SetUnitY(kb.subject, y)
endif``````

#### Bribe

Code Moderator
Level 48
This requires some explaination which I do not have time for at the moment; it is basically the lightest knockback system one can have.

JASS:
``````library Knockback requires DequeueStruct

globals
//*********************
//* Configuration
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
private constant real       LOOP_REF        = 0.03125
//*
//*
//*****************************************************************************
endglobals

globals
private keyword allocate
private keyword deallocate
private real    g_x         = 0.
private real    g_y         = 0.
private item    g_item      = null
private timer   g_timer     = CreateTimer()
endglobals

struct knockback extends array

implement DequeueStruct

private     real    rotationCos
private     real    rotationSin
private     real    time

private static method onRef takes nothing returns nothing
local thistype kb = 0
local unit u
local real x
local real y
local real iX
local real iY
local real vel
loop
set kb = kb.next()
exitwhen kb == 0
set vel= kb.velocity
set u  = kb.subject
set x  = GetUnitX(u) + vel * kb.rotationCos
set y  = GetUnitY(u) + vel * kb.rotationSin
//use an item to check the pathability of the new coordinate and
//move the unit if the point is available.
call SetItemPosition(g_item, x, y)
set iX = GetWidgetX(g_item) - x
set iY = GetWidgetY(g_item) - y
if (iX*iX + iY*iY <= 32) then
call SetUnitX(u, x)
call SetUnitY(u, y)
endif

set kb.velocity  = vel + kb.friction
set kb.time = kb.time - LOOP_REF
if (kb.time <= 0.00) then
call kb.deallocate()
if (thistype.getLength() == 0) then
call PauseTimer(g_timer)
endif
endif
endloop
call SetItemPosition(g_item, g_x, g_y)
call SetItemVisible(g_item, false)
set u = null
endmethod

static method create takes unit u, real angle, real distance, real time returns thistype
local thistype kb   = thistype.allocate()
set kb.subject      = u
set kb.rotationCos  = Cos(angle)
set kb.rotationSin  = Sin(angle)
set kb.time         = time

set kb.velocity = (2 * distance/time) * LOOP_REF
set kb.friction = (-kb.velocity/time) * LOOP_REF * LOOP_REF
if (thistype.getLength() == 1) then
call TimerStart(g_timer, LOOP_REF, true, function thistype.onRef)
endif
return kb
endmethod

private static method onInit takes nothing returns nothing
//the item will be have maintained invisibility as to not interfere with
//in-game actions, such as a unit picking the item up.
set g_x = GetRectMaxX(bj_mapInitialPlayableArea)
set g_y = GetRectMaxY(bj_mapInitialPlayableArea)
set g_item = CreateItem('afac', g_x, g_y)
call SetItemVisible(g_item, false)
endmethod

endstruct

endlibrary``````

#### Starraver

Level 1
Hey Guys i have a problem :[
i know there up is a tutorial / libary with all but i want to try it myself so..
I want to test a simple system why knocks back a target here is the code:

globals
integer KB_Counter
real KB_Distance
unit KB_Attacker
unit KB_Defender
location KB_DefLoc
location KB_AtkLoc
timer KB_Timer
endglobals

function KB_A1 takes nothing returns nothing
call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS, 10.00, "Knockback Started!")
set KB_Counter = 1
set KB_Distance = 10.00
set KB_Attacker = GetAttacker()
set KB_Defender = GetAttackedUnitBJ()
set KB_AtkLoc = GetUnitLoc(GetAttacker())
set KB_DefLoc = GetUnitLoc(GetAttackedUnitBJ())
call StartTimerBJ(KB_Timer, true, 0.05)
endfunction

function KB_A2 takes nothing returns nothing
if KB_Counter != 50 then
set KB_Counter = (KB_Counter + 1)
set KB_Distance = (KB_Distance + 10)
call SetUnitPositionLoc(KB_Defender, PolarProjectionBJ(KB_AtkLoc, KB_Distance, AngleBetweenPoints(KB_AtkLoc, KB_DefLoc)))
else
call PauseTimerBJ(true, KB_Timer)
endif
endfunction

function InitTrig_KB takes nothing returns nothing
local trigger KB_M1 = CreateTrigger()
local trigger KB_M2 = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(KB_M1, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerRegisterTimerExpireEventBJ(KB_M2, KB_Timer)
endfunction

but it happens nothing ;O what is wrong??

#### Bribe

Code Moderator
Level 48
I've made some suggestions how to make this much more efficient, so this is back to the submissions forum. In fact, the suggestions I have aren't even that high-quality and could be put to better use with a system like T32 even.

Replies
14
Views
3K
Replies
13
Views
1K
Replies
39
Views
6K
[vJASS] Aabb
Replies
3
Views
2K
[vJASS] UserCamera
Replies
24
Views
4K