HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

involuntary motion on offset

06-21-2007, 05:42 PM#1
rednek
Howdy folks
I have little problem now
I have trigger with period every 0.02 seconds of game time in events. Also I have Unit - Move unit to 5 points in Y degress action in this trigger. Everything works as I want, but only for moment when I try to move that unit in point where is blocked patch. Unit will move to the right in X offset, but that's not good for my map. I just want to make unit stop where it can go forth. Is there any way to solve this problem without using laggy condition in this trigger?

Trigger:
Left
Collapse Events
Time - Every 0.02 seconds of game time
Conditions
Collapse Actions
Unit - Move Knight instantly to ((Position of Knight) offset by (0.00, -8.00))
06-21-2007, 07:04 PM#2
Pyrogasm
First of all, this should be Triggers & Scripts; secondly, you can use grim001's CheckPathability function.
Quote:
Originally Posted by grim001
You can use it in conjunction with my function to check pathability and map boundries if you want:

Collapse JASS:
function CheckPathability takes unit u, real x, real y returns boolean
    local real ox = GetUnitX(u)
    local real oy = GetUnitY(u)
    if x > MAX_X then
        return false
    elseif x < MIN_X then
        return false
    if y > MAX_Y then
        return false
    elseif y < MIN_Y then
        return false
    endif
    call SetUnitX(u, -9472.)
    call SetUnitY(u, 9216.)
    call SetUnitPosition(udg_PATHUNIT, x, y)
    set x = GetUnitX(udg_PATHUNIT)-x
    set y = GetUnitY(udg_PATHUNIT)-y
    call SetUnitX(udg_PATHUNIT, -9472.)
    call SetUnitY(udg_PATHUNIT, 9216.)
    call SetUnitX(u, ox)
    call SetUnitY(u, oy)
    return x*x+y*y <= 100.
endfunction

-9472, 9216 is a chosen safespot on my map where units are moved to temporarily during this function and where the PATHUNIT is stored.

MIN_X, MIN_Y and so on are the map boundries. It's best if you actually place the map boundry numbers directly into the function rather than using a variable since it will be slightly faster.

PATHUNIT is a global unit variable containing a ground unit with 32 collision radius and no model. Do not create and destroy a unit because this function is designed to be as speedy as possible and could wind up executing it hundreds of times per second. Also rapidly creating/destroying handles increases WC3's memory usage substantially.

To use this, you'll simply need to create the unit specified, create the global unit "PATHUNIT" (Case-sensitive), insert the numbers for map bounds, change the safespot, and put the function in the map's Custom Script section.

Then do this:
Trigger:
Collapse Events
Time - Every 0.02 seconds of game time
Conditions
Collapse Actions
Set TempPoint = (Position of (Knight))
Set TempPoint2 = (TempPoint offset by (0.00, -8.00))
Custom Script: if CheckPathability(udg_Knight, GetLocationX(udg_TempPoint2), GetLocationY(udg_TempPoint2)) then
Unit - Move Knight instantly to (TempPoint2)
Custom script: endif
Custom script: call RemoveLocation(udg_TempPoint)
Custom script: call RemoveLocation(udg_TempPoint2)
06-21-2007, 07:41 PM#3
aquilla
here's my version :p

Trigger:
Left
Collapse Events
Time - Every 0.02 seconds of game time //You could change this to 0.04 (and distance to -16) without any noticable difference
Conditions
Collapse Actions
Custom script: local real y = GetUnitY(udg_Knight) - 8 //store the position where you want it moved; current position offset by 0, -8
Custom script: call SetUnitPosition(udg_Knight, GetUnitX(udg_Knight), y) //moves the unit to the desired location
Custom script: if IsUnitInRangeXY(udg_Knight, GetUnitX(udg_Knight), y, 5) then //compare the unit's position to where it was supposed to be moved, the 5 is the maximum distance between these two points; like a margin of error, change it if you wish
Unit - Do some stuff
Custom script: endif //end of the if statement

06-21-2007, 07:48 PM#4
Toadcop
Collapse JASS:
    call SetUnitPosition(udg_PATHUNIT, x, y)
// to call this func will be 5x (or more) slower than to call the rest code.
// i don't know it's evil =) i would not use it

Quote:
-9472, 9216 is a chosen safespot on my map where units are moved to temporarily during this function and where the PATHUNIT is stored.
if map is smaller than 160X160 this cords will simple crash war3 so it must be vars. and the value must depend on current map size
06-21-2007, 07:58 PM#5
grim001
maybe you're supposed to type in the numbers you want? and I think you have obviously missed the whole point of this toadcop, so go away.
06-21-2007, 08:11 PM#6
Toadcop
grim001 i don't think so =) yes you check if you is in that position in which it must be but ! i don't know if SetUnitPosition() is the best solusion.

and i don't fully se the logic of this
x*x+y*y <= 100 ? and the summ difference in ^2
for example the diffx = 10 and diffy=2 so 100 and 4 104 == false
but diffx 7 diffy 7 then 49 and 49 = 98 and == true
so your explaination ?
06-21-2007, 08:19 PM#7
Earth-Fury
the presuption is that if you move a unit, the total difference in position will be less then 10 if the area you are moving it to is unobstructed. By using the SetUnitPosition() function, the unit will always move to a pathable area. the only reason to not check for exact position matching is the fact that WC3 sucks balls when it comes to such things.
06-21-2007, 08:23 PM#8
rednek
Thank You all guys <3 hope problem is solved now :)
06-21-2007, 08:41 PM#9
grim001
that function is old and lame now, i don't recommend it to be used...

I haven't tested this but this is probably how I would rewrite it:
Collapse JASS:
function CheckPathability takes unit u, real x, real y returns boolean
 call SetUnitX(u, MinX) //pick your safespot
 call SetUnitY(u, MaxY)
 call SetUnitPosition(PathUnit, x, y)
 return IsUnitInRange(u, x, y, 10.) and x > MaxX and x < MinX and y > MaxY and y < MinY
endfunction
Put it in a library and have it automatically find the map bounds and create the pathunit for you if you want, and add aloc to it. You should replace the vars with numbers directly if you want more speed.

Pros:
Probably many times faster than the old function
Easy to inline

Cons:
You should still inline this if you want the best speed
You now have an aloc unit possibly at any random spot on the map, that may or may not pose problems
You must manually return the unit to its original position if it fails the path check (this should not be a problem in most movement triggers)