• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System]BoundSentinelEx

I found out Vexorian's Bound Sentinel somewhat slow and use TriggerAddAction.
So i coded my own version from it.

Credits to Vexorian.
JASS:
/************************************************************************
*
*
*    Bound Sentinel
*
*        by: Almia
*
*    - Keeps all units exceeding the map bounds
*      inside the playable map area.
*
*    - Not guaranteed to keep units that are created
*      outside the map bounds.
*
*
************************************************************************
*
*     Credits
*
*     Vexorian for the Bound Sentinel Lib.
*
************************************************************************/
library BoundSentinelEx

    globals
	
	    private real minX
		private real minY
		private real maxX
		private real maxY
    
	endglobals
	
	/**************************************************
	*
	*    On Leave
	*
	*    - this function maintains the units
	*      inside the map.
	*
	*    - Run via TriggerRegisterLeaveRegion event.
	*
	**************************************************/
	
	private function OnLeave takes nothing returns boolean
	
	    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
		
		return false
		
	endfunction

    private module Init
	    static method onInit takes nothing returns nothing
            call init()
		endmethod
	endmodule
	
	/**************************************************
	*
	*    BSInit
	*
    *    - struct for initialization
	*
	*    - the init method initializes the
	*      the LeaveRegion event and the
	*      map bounds.
	*
	**************************************************/
	
	private struct BSInit extends array
	    static method init takes nothing returns nothing
			local trigger t = CreateTrigger()
			local region r = CreateRegion()
			
			set minX = GetRectMinX(bj_mapInitialPlayableArea)
			set minY = GetRectMinY(bj_mapInitialPlayableArea)
			set maxX = GetRectMaxX(bj_mapInitialPlayableArea)
			set maxY = GetRectMaxY(bj_mapInitialPlayableArea)
			
			call RegionAddRect(r, bj_mapInitialPlayableArea)
			
			call TriggerRegisterLeaveRegion(t, r, null)
            call TriggerAddCondition(t, Filter(function OnLeave))
			
			set t = null
			set r = null
		endmethod
		
		implement Init
	endstruct
endlibrary

Vexorian's original BoundSentinel ( see comparison)
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
 
Level 19
Joined
Jan 3, 2022
Messages
320
I looked at both (original) and Almia's rework (this) made me realize that neither library will work correctly for maps that change their playable area. It would only work for static maps, because they check the size once and save it:
JASS:
set minX = GetRectMinX(bj_mapInitialPlayableArea)
I didn't find any events related to world/map size change. This means it's impossible to have this library track playable area size dynamically without a performance penalty / updating saved values by map author from triggers.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
I looked at both (original) and Almia's rework (this) made me realize that neither library will work correctly for maps that change their playable area. It would only work for static maps, because they check the size once and save it:
JASS:
set minX = GetRectMinX(bj_mapInitialPlayableArea)
I didn't find any events related to world/map size change. This means it's impossible to have this library track playable area size dynamically without a performance penalty / updating saved values by map author from triggers.
Dynamic RegionAddRect/RemoveRect could be used in conjunction with hooking functions which change the map playable area
 
Top