| 07-06-2008, 04:29 AM | #1 |
Gets a unit's collision size maybe? Information:
Standalone://******************************************************** //* GetUnitCollisionSize (Standalone version) //* -------------------- //* If you need it, use it. //* //* To implement it just create a custom text 'trigger' //* called GetUnitCollisionSize, and paste this there. //* //* To copy from one map to another just copy the trigger //* holding this code to the target map. //* //********************************************************* //======================================================== library_once GetUnitCollisionSize globals private constant integer ITERATIONS = 10 //too much, slow, too short "innacurate", let it be bigger than 0... //I *think* 10 is enough... public constant real MAX_COLLISION_SIZE = 300.0 //should be THE max collision size in the map, //well, not really, just make sure it is greater than it //few maps should have collision sizes bigger than 300.0... endglobals //======================================================== function GetUnitCollisionSize takes unit u returns real local integer i=0 local real x=GetUnitX(u) local real y=GetUnitY(u) local real hi local real lo local real mid set hi=MAX_COLLISION_SIZE set lo=0.0 loop set mid=(lo+hi)/2.0 exitwhen (i==ITERATIONS) if (IsUnitInRangeXY(u,x+mid,y,0)) then set lo=mid else set hi=mid endif set i=i+1 endloop return mid endfunction endlibrary CSSafeCache version:library_once GetUnitCollisionSize requires CSSafeCache //******************************************************** //* GetUnitCollisionSize (CSCache version) //* -------------------- //* If you need it, use it. //* //* To implement it just create a custom text 'trigger' //* called GetUnitCollisionSize, and paste this there. //* //* To copy from one map to another just copy the trigger //* holding this code to the target map. //* //********************************************************* //========================================================= globals private constant integer ITERATIONS = 10 //too much, slow, too short "innacurate", let it be bigger than 0... //I *think* 10 is enough... public constant real MAX_COLLISION_SIZE = 300.0 //should be THE max collision size in the map, //well, not really, just make sure it is greater than it //few maps should have collision sizes bigger than 300.0... endglobals //============================================================================= function GetUnitCollisionSize takes unit u returns real local integer i=0 local real x=GetUnitX(u) local real y=GetUnitY(u) local string ktyp=I2S(GetUnitTypeId(u)) local real hi local real lo local real mid if (HaveSetField("[GetUnitCollisionSize]",ktyp,bj_GAMECACHE_REAL)) then return GetTableReal("[GetUnitCollisionSize]",ktyp) endif set hi=MAX_COLLISION_SIZE set lo=0.0 loop set mid=(lo+hi)/2.0 exitwhen (i==ITERATIONS) if (IsUnitInRangeXY(u,x+mid,y,0)) then set lo=mid else set hi=mid endif set i=i+1 endloop call SetTableReal("[GetUnitCollisionSize]",ktyp,mid) return mid endfunction endlibrary Table version:library_once GetUnitCollisionSize initializer init requires Table //******************************************************** //* GetUnitCollisionSize (Table version) //* -------------------- //* If you need it, use it. //* //* To implement it just create a custom text 'trigger' //* called GetUnitCollisionSize, and paste this there. //* //* To copy from one map to another just copy the trigger //* holding this code to the target map. //* //********************************************************* //========================================================= globals private constant integer ITERATIONS = 10 //too much, slow, too short "innacurate", let it be bigger than 0... //I *think* 10 is enough... public constant real MAX_COLLISION_SIZE = 300.0 //should be THE max collision size in the map, //well, not really, just make sure it is greater than it //few maps should have collision sizes bigger than 300.0... private Table memo endglobals //============================================================================= function GetUnitCollisionSize takes unit u returns real local integer i=0 local real x=GetUnitX(u) local real y=GetUnitY(u) local integer typ=GetUnitTypeId(u) local real hi local real lo local real mid if (memo.exists(typ) ) then return I2R(memo[typ]) endif set hi=MAX_COLLISION_SIZE set lo=0.0 loop set mid=(lo+hi)/2.0 exitwhen (i==ITERATIONS) if (IsUnitInRangeXY(u,x+mid,y,0)) then set lo=mid else set hi=mid endif set i=i+1 endloop set memo[typ]=R2I(mid+0.500000001) return mid endfunction private function init takes nothing returns nothing set memo=Table.create() endfunction endlibrary |
| 07-06-2008, 06:06 AM | #2 |
I once extended this method to create a library which pre-caches the collision size of each unittype as it enters the map, then attaches it to each individual unit using the 0x100000 method, allowing you to set/retrieve individual unit collision sizes (i.e. if you make a unit grow or shrink you can update it) with simple inlined function calls. This means it is extremely speedy, and suitable for collision detection operations. I will post it if anyone actually wants it, but it sits gathering dust because I figured no one will ever use such a thing. |
| 01-02-2009, 10:21 PM | #3 |
Typo in Table-version: JASS:function GetUnitCollisionSize takes unit u returns real local integer i=0 local real x=GetUnitX(u) local real y=GetUnitY(u) local integer typ=GetUnitTypeId(u) local real hi local real lo local real mid if (memo.exists(ktyp) ) then return I2R(memo[ktyp]) endif set hi=MAX_COLLISION_SIZE set lo=0.0 loop set mid=(lo+hi)/2.0 exitwhen (i==ITERATIONS) if (IsUnitInRangeXY(u,x+mid,y,0)) then set lo=mid else set hi=mid endif set i=i+1 endloop set memo[ktyp]=R2I(mid+0.500000001) return mid endfunction |
| 01-02-2009, 11:10 PM | #4 |
all right. |
| 07-24-2009, 03:06 AM | #5 |
Wouldn't moving the GetUnitX/Y calls below the memo.exists check optimize the code somewhat? Not sure how significant the two calls are relative to the GC (soon to be handletable) call plus the cost of calling the function in the first place, but even if not that significant, not initializing unneeded values is the right thing to do. |
