HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Set Unit XY

08-16-2008, 10:00 PM#1
Av3n
Since I am lazy and want something in return.

Can anyone lead me to a custom script which checks if the unit is going out of map bounds and stop it (Or make it stay at the same place)

This would really improve the user safety of my projectile system.

Thanks in advance

-Av3n
08-16-2008, 10:11 PM#2
Themerion
Doesn't old versions of the caster system do this? Perhaps the latest one do so as well. Check :)
08-16-2008, 10:43 PM#3
Fulla
I think this should do it, just fill it in the blanks where necessary:
Collapse JASS:
globals
    real MapSizeXLow = GetRectMinX(GetWorldBounds()
    real MapSizeXHigh = GetRectMaxX(GetWorldBounds()
    real MapSizeYLow = GetRectMinY(GetWorldBounds()
    real MapSizeYHigh = GetRectMaxY(GetWorldBounds()
endglobals

function SetUnitXY takes unit u returns nothing
    if x > MapSizeXLow and x < MapSizeXHigh and y > MapSizeYLow and y < MapSizeYHigh then
        call SetUnitX(u, x)
        call SetUnitY(u, y)
    else
        //Kill unit ??
    endif
endfunction
08-16-2008, 11:28 PM#4
Anitarf
Hmm... Here's a few variations of Fulla's function, which one you go with depends on the effect you want, you might even need a third variation, whoknows:
Collapse JASS:
globals
    real MapSizeXLow = GetRectMinX(GetWorldBounds()
    real MapSizeXHigh = GetRectMaxX(GetWorldBounds()
    real MapSizeYLow = GetRectMinY(GetWorldBounds()
    real MapSizeYHigh = GetRectMaxY(GetWorldBounds()
endglobals

function SetUnitXYNearest takes unit u returns nothing
    if x < MapSizeXLow then
        set x =MapSizeXLow
    elseif x > MapSizeXHigh then
        set x =MapSizeXHigh
    endif
    if y < MapSizeYLow then
        set y =MapSizeYLow
    elseif y > MapSizeYHigh then
        set y =MapSizeYHigh
    endif
    call SetUnitX(u, x)
    call SetUnitY(u, y)
endfunction

function SetUnitXYCheck takes unit u returns boolean
    if x > MapSizeXLow and x < MapSizeXHigh and y > MapSizeYLow and y < MapSizeYHigh then
        call SetUnitX(u, x)
        call SetUnitY(u, y)
        return true
    endif
    return false
endfunction
08-16-2008, 11:36 PM#5
Av3n
I'll just edit these functions to my liking

Anitarf's one was kinda what i was looking for.
Mainly since its a projectile system, i'm aiming to stop it before it reaches the bounds etc.

For example if it reaches out of the playable map area set it to the max/min x/y then stop it before it crashes

-Av3n
08-17-2008, 02:39 AM#6
moyack
Let's do a test:

Collapse JASS:
function Trig_Crash_game_Actions takes nothing returns nothing
    local unit u = CreateUnit(GetLocalPlayer(), 'hpeo', 0,0,0)
    local rect r = GetWorldBounds()
    call UnitApplyTimedLife(u, GetUnitTypeId(u),2.)
    call SetUnitX(u, GetRectMaxX(r)+1000.) // WTF!!! what are you doing!!!
    call SetUnitY(u, GetRectMaxY(r)+1000.) // are you insane???!!!11one
    call RemoveRect(r)
    set r = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Crash_game takes nothing returns nothing
    set gg_trg_Crash_game = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_Crash_game, Player(0), "-crash", true )
    call TriggerAddAction( gg_trg_Crash_game, function Trig_Crash_game_Actions )
endfunction

You'll notice that WC3 doesn't crash.... the only answer is because Blizzard has heard indirectly the voice of our calling and has fixed this horrible bug for us.

Let's put a candle to Blizzard.
08-17-2008, 03:27 AM#7
Strilanc
It still crashes if you go outside the bounds sometimes. It seems like they just extended the allowed range; if you go too far it still crashes.
08-17-2008, 03:29 AM#8
moyack
tested with bounds limit +1000 and it doesn't crash.... unless wine do miracles in my test map.

EDIT: confirmed: +1000 in exceeding boundaries and nil problem.
08-17-2008, 05:50 AM#9
Strilanc
I know for a fact that going out of range, or something related to it, causes crashes.

I know it because I had to fix my spell olympics spell after a unit flew off the map and caused a crash.

Maybe it's GetLocationZ or some similar function that does it.
08-17-2008, 06:55 AM#10
saw792
That's odd... in a knockback that I coded for one of my olympics spells setting the distance to 1000 and knocking air units into the map bounds just causes them to bounce off...

It does get a bit odd though when I set the distance to 99999... The knocked units disappeared completely (no longer on the map, at least not within camera bounds).
08-17-2008, 07:20 AM#11
Ammorth
The unit will not crash the map when it exceeds the map bounds, but if you order the unit to move or something, the game crashes. This could be because of the pathing system and it hitting some infinite loop or whatever. It it doesn't crash then they must have patched it in 1.22.
08-17-2008, 10:45 AM#12
Av3n
I know for sure if it keeps moving out of the actual map it will definitely cause a crash

-Av3n
08-17-2008, 10:50 AM#13
Anitarf
Well, I've managed to crash it with a completely triggered unit that wasn't given any orders, just by it reaching the end of the map. Then again, I haven't tested my map in 1.22 yet.
08-17-2008, 12:12 PM#14
Themerion
Collapse Leak test:
    if GetWorldBounds()==GetWorldBounds() then
        call BJDebugMsg("Same")
    else
        call BJDebugMsg("Different")
    endif
output:
Different

So, if we alter the code slightly, we can avoid some unnecessary leaks (leading to increased handle count). Also, I think Vexorian mentioned somewhere that it's better to use an init-function than setting globals directly. I'm not sure though...

Collapse JASS:
library WorldBoundCheck initializer Init

globals
    private real MapSizeXLow
    private real MapSizeXHigh
    private real MapSizeYLow
    private real MapSizeYHigh
endglobals

private function Init takes nothing returns nothing
    local rect r=GetWorldBounds()

    set MapSizeXLow = GetRectMinX(r)
    set MapSizeXHigh = GetRectMaxX(r)
    set MapSizeYLow = GetRectMinY(r)
    set MapSizeYHigh = GetRectMaxY(r)

    call RemoveRect(r)
    set r=null
endfunction

function SetUnitXYNearest takes unit u returns nothing
    if x < MapSizeXLow then
        set x =MapSizeXLow
    elseif x > MapSizeXHigh then
        set x =MapSizeXHigh
    endif
    if y < MapSizeYLow then
        set y =MapSizeYLow
    elseif y > MapSizeYHigh then
        set y =MapSizeYHigh
    endif
    call SetUnitX(u, x)
    call SetUnitY(u, y)
endfunction

function SetUnitXYCheck takes unit u returns boolean
    if x > MapSizeXLow and x < MapSizeXHigh and y > MapSizeYLow and y < MapSizeYHigh then
        call SetUnitX(u, x)
        call SetUnitY(u, y)
        return true
    endif
    return false
endfunction

endlibrary