HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

BoundSentinel

09-14-2008, 08:10 PM#1
Vexorian
Moving a unit outside the map's bounds using SetUnitX/Y will STILL crash the game. But I did not want to use a wrapper for SetUnitX/Y that does the bounds checking, an extra function call seems like killing the whole purpose of using SetUnitX/Y... Adding this library to your map (just adding it) will be equivalent to using CS_MoveUnit or another wrapper instead of SetUnitX/Y, but it moves the performance penalty to only the instance in which the unit actually goes out of the bounds... So, I'd say it is useful.
Collapse JASS:
library BoundSentinel initializer init
//*************************************************
//* BoundSentinel
//* -------------
//*  Don't leave your units unsupervised, naughty
//* them may try to get out of the map bounds and
//* crash your game.
//*
//*  To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//*************************************************

//==================================================
   globals
       // High enough so the unit is no longer visible, low enough so the
       // game doesn't crash...
       //
       // I think you need 0.0 or soemthing negative prior to patch 1.22
       //
       private constant real EXTRA = 500.0
   endglobals

   //=========================================================================================
   globals
       private real maxx
       private real maxy
       private real minx
       private real miny
   endglobals

   //=======================================================================
   private function dis takes nothing returns nothing
    local unit u=GetTriggerUnit()
    local real x=GetUnitX(u)
    local real y=GetUnitY(u)

       if(x>maxx) then
           set x=maxx
       elseif(x<minx) then
           set x=minx
       endif
       if(y>maxy) then
           set y=maxy
       elseif(y<miny) then
           set y=miny
       endif
       call SetUnitX(u,x)
       call SetUnitY(u,y)
    set u=null
   endfunction

   private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    local region  r=CreateRegion()
    local rect    rc

       set minx=GetCameraBoundMinX() - EXTRA
       set miny=GetCameraBoundMinY() - EXTRA
       set maxx=GetCameraBoundMaxX() + EXTRA
       set maxy=GetCameraBoundMaxY() + EXTRA
       set rc=Rect(minx,miny,maxx,maxy)
       call RegionAddRect(r, rc)
       call RemoveRect(rc)

       call TriggerRegisterLeaveRegion(t,r, null)
       call TriggerAddAction(t, function dis)

    //this is not necessary but I'll do it anyway:
    set t=null
    set r=null
    set rc=null
   endfunction
endlibrary

Edit: It now removes the Rect.
09-14-2008, 09:24 PM#2
Here-b-Trollz
I would not think that this would work...

If I blatantly do something like SetUnitX(unit,100000000000000000), then this will catch that and prevent a crash?
09-14-2008, 09:45 PM#3
Vexorian
If you did that it won't crash even without BoundSentinel.

Now if you did SetUnitY(unit, - 1000000) it would crash UNLESS you had BoundSentinel.
09-14-2008, 10:44 PM#4
Ammorth
100000000000000000 actually equals 1569325056 with 32 bit signed integers.
09-16-2008, 09:54 PM#5
Vexorian
Quote:
Originally Posted by Vexorian
If you did that it won't crash even without BoundSentinel.

Now if you did SetUnitY(unit, - 1000000) it would crash UNLESS you had BoundSentinel.
Really, been testing:

Left/Right/Top edges do not crash.

Bottom edge crashes: However it doesn't crash at the instant you call SetUnitY, it crashes when the frame is rendered (apparently, could be another thing besides rendering...) so, yep this library really prevents crashes.

There is another thing with edges, regardless of the crash we knew about for so long, if you issue an order to a unit too far from the edges, the game will freeze, yep BoundSentinel prevents that as well.
09-16-2008, 10:36 PM#6
MaD[Lion]
good wrapper
09-17-2008, 02:04 AM#7
Rising_Dusk
I really don't understand how this works to prevent these crashes. You also mention that this impacts the SetUnitX/Y performance when called on areas out of bounds? How is that so?
09-17-2008, 02:34 AM#8
Vexorian
Quote:
I really don't understand how this works to prevent these crashes
If unit leaves map bounds put it back in them.

Quote:
You also mention that this impacts the SetUnitX/Y performance when called on areas out of bounds?
I didn't say that, but after you Move a unit outside the bounds this trigger will fire, so it isa bunch of operations that happen, don't know if the leave event waits for the thread to end before triggering.
09-17-2008, 02:54 AM#9
Rising_Dusk
Ohh, I see. So this intercepts the leaving before the crash? That actually works? Crazy.
09-17-2008, 02:56 AM#10
Here-b-Trollz
Quote:
Originally Posted by Rising_Dusk
Ohh, I see. So this intercepts the leaving before the crash? That actually works? Crazy.
My thoughts exactly. Ignorance is bliss I suppose.
09-17-2008, 12:18 PM#11
Captain Griffen
I'm pretty sure that unit leaves region events interrupt any code that is running, which makes it even more effective.
09-17-2008, 12:46 PM#12
Vestras
Wow, this is really awesome.
09-18-2008, 08:58 PM#13
Vexorian
Apparently it works, but before approval could you please fix the blatant Rect leak? I know it doesn't matter but some people might get annoyed by it.
09-18-2008, 09:01 PM#14
Vexorian
Ok, updated
09-18-2008, 09:04 PM#15
Vexorian
approved