Fix AI collision detection with crates and overlapping hedgehogs. Remove duplicating code
authorjaree@jaree-VirtualBox
Thu, 04 Apr 2013 10:44:03 +0300
changeset 8845 8cf1ed3bae45
parent 8842 21c4ed977d0e
child 8848 e9ebd63f8a03
Fix AI collision detection with crates and overlapping hedgehogs. Remove duplicating code
hedgewars/uAIMisc.pas
--- a/hedgewars/uAIMisc.pas	Wed Apr 03 22:05:11 2013 -0400
+++ b/hedgewars/uAIMisc.pas	Thu Apr 04 10:44:03 2013 +0300
@@ -256,6 +256,72 @@
     RatePlace:= rate;
 end;
 
+function CheckBounds(x, y, r: Longint): boolean; inline;
+begin
+    CheckBounds := (((x-r) and LAND_WIDTH_MASK) = 0) and
+        (((x+r) and LAND_WIDTH_MASK) = 0) and
+        (((y-r) and LAND_HEIGHT_MASK) = 0) and
+        (((y+r) and LAND_HEIGHT_MASK) = 0);
+end;
+
+
+function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
+begin
+    if not CheckBounds(x, y, r) then
+        exit(false);
+
+    if (Land[y-r, x-r] <> 0) or    
+       (Land[y+r, x-r] <> 0) or 
+       (Land[y-r, x+r] <> 0) or
+       (Land[y+r, x+r] <> 0) then
+       exit(true);
+
+    TestCollWithEverything := false;
+end;
+
+function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
+begin
+    if not CheckBounds(x, y, r) then
+        exit(false);
+
+    if (Land[y-r, x-r] > lfAllObjMask) or
+       (Land[y+r, x-r] > lfAllObjMask) or 
+       (Land[y-r, x+r] > lfAllObjMask) or
+       (Land[y+r, x+r] > lfAllObjMask) then
+       exit(true);
+
+    TestCollExcludingObjects:= false;
+end;
+
+function TestColl(x, y, r: LongInt): boolean; inline;
+begin
+    if not CheckBounds(x, y, r) then
+        exit(false);
+
+    if (Land[y-r, x-r] and lfNotCurrentMask <> 0) or
+       (Land[y+r, x-r] and lfNotCurrentMask <> 0) or 
+       (Land[y-r, x+r] and lfNotCurrentMask <> 0) or
+       (Land[y+r, x+r] and lfNotCurrentMask <> 0) then
+       exit(true);
+    
+    TestColl:= false;
+end;
+
+function TestCollWithLand(x, y, r: LongInt): boolean; inline;
+begin
+    if not CheckBounds(x, y, r) then
+        exit(false);
+
+    if (Land[y-r, x-r] > lfAllObjMask) or
+       (Land[y+r, x-r] > lfAllObjMask) or 
+       (Land[y-r, x+r] > lfAllObjMask) or
+       (Land[y+r, x+r] > lfAllObjMask) then
+       exit(true);
+    
+    TestCollWithLand:= false;
+end;
+
+
 // Wrapper to test various approaches.  If it works reasonably, will just replace.
 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
@@ -266,77 +332,13 @@
         MeX:= hwRound(Me^.X);
         MeY:= hwRound(Me^.Y);
         // We are still inside the hog. Skip radius test
-        if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and (Land[y, x] <= lfAllObjMask) and ((Land[y, x] and lfObjMask) < 2) then
+        if ((sqr(x-MeX) + sqr(y-MeY)) < 256) and (Land[y, x] and lfObjMask = 0) then
             exit(false);
     end;
-    TestCollExcludingMe:= TestColl(x, y, r)
-end;
-
-function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
-var b: boolean;
-begin
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > lfAllObjMask);
-    if b then
-        exit(true);
-    
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > lfAllObjMask);
-    if b then
-        exit(true);
-    
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > lfAllObjMask);
-    if b then
-        exit(true);
-    
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > lfAllObjMask);
-    if b then
-        exit(true);
-    
-    TestCollExcludingObjects:= false;
+    TestCollExcludingMe:= TestCollWithEverything(x, y, r)
 end;
 
-function TestColl(x, y, r: LongInt): boolean; inline;
-var b: boolean;
-begin
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] and lfNotCurrentMask <> 0);
-    if b then
-        exit(true);
-    
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] and lfNotCurrentMask <> 0);
-    if b then
-        exit(true);
-    
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] and lfNotCurrentMask <> 0);
-    if b then
-        exit(true);
-    
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] and lfNotCurrentMask <> 0);
-    if b then
-        exit(true);
-    
-    TestColl:= false;
-end;
 
-function TestCollWithLand(x, y, r: LongInt): boolean; inline;
-var b: boolean;
-begin
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > lfAllObjMask);
-    if b then
-        exit(true);
-        
-    b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > lfAllObjMask);
-    if b then
-        exit(true);
-        
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > lfAllObjMask);
-    if b then
-        exit(true);
-        
-    b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > lfAllObjMask);
-    if b then
-        exit(true);
-
-    TestCollWithLand:= false;
-end;
 
 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt;
 var skipLandCheck: boolean;