AI: Fix bad AI collision checks
authorWuzzy <Wuzzy2@mail.ru>
Sun, 19 Jul 2020 11:20:20 +0200
changeset 15750 cc8882e46784
parent 15749 f9c2fd4bfb3e
child 15751 34138bf36c5c
AI: Fix bad AI collision checks
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
--- a/hedgewars/uAIAmmoTests.pas	Sat Jul 18 23:53:14 2020 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Sun Jul 19 11:20:20 2020 +0200
@@ -653,22 +653,26 @@
 
         EX:= trunc(x);
         EY:= trunc(y);
+        range:= Metric(trunc(meX), trunc(meY), EX, EY);
 
-        // Sanity check 1: Make sure we're not too close to impact location
-        range:= Metric(trunc(meX), trunc(meY), EX, EY);
-        if (range < 150) and (Level < 5) then
-            exit(BadTurn);
-
-        // Sanity check 2: If impact location is close, above us and wind blows
+        // Sanity check 1: Make sure we've hit a hedgehog or object
+        if not TestCollHogsOrObjects(EX, EY, 5) then
+            value:= BadTurn
+        // Sanity check 2: Make sure we're not too close to impact location
+        else if (range < 150) and (Level < 5) then
+            value:= BadTurn
+        // Sanity check 3: If impact location is close, above us and wind blows
         // towards us, there's a risk of fire flying towards us, so fail in this case.
-        if (Level < 3) and (range <= 600) and (trunc(meY) >= EX) and
+        else if (Level < 3) and (range <= 600) and (trunc(meY) >= EX) and
             (((ap.Angle < 0) and (aiWindSpeed > 0)) or ((ap.Angle > 0) and (aiWindSpeed < 0))) then
-            exit(BadTurn);
-
-        if t >= -timeLimit then
-            value:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly
+            value:= BadTurn
+        // Timeout
+        else if t < -timeLimit then
+            value:= BadTurn
         else
-            value:= BadTurn;
+        // Valid hit!
+            // Weapon does not actually explode, so this rating is an approximation
+            value:= RateExplosion(Me, EX, EY, 97); // average of 17 attempts, most good, but some failing spectacularly
 
         if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
             value := BadTurn;
--- a/hedgewars/uAIMisc.pas	Sat Jul 18 23:53:14 2020 +0200
+++ b/hedgewars/uAIMisc.pas	Sun Jul 19 11:20:20 2020 +0200
@@ -79,6 +79,7 @@
 function  RatePlace(Gear: PGear): LongInt;
 function  CheckWrap(x: real): real; inline;
 function  TestColl(x, y, r: LongInt): boolean; inline;
+function  TestCollHogsOrObjects(x, y, r: LongInt): boolean; inline;
 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
 
@@ -381,6 +382,7 @@
 end;
 
 
+// Check for collision with anything
 function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
 begin
     if not CheckBounds(x, y, r) then
@@ -395,6 +397,7 @@
     TestCollWithEverything := false;
 end;
 
+// Check for collision with non-objects
 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
 begin
     if not CheckBounds(x, y, r) then
@@ -409,6 +412,7 @@
     TestCollExcludingObjects:= false;
 end;
 
+// Check for collision with something other than current hedgehog or crate
 function TestColl(x, y, r: LongInt): boolean; inline;
 begin
     if not CheckBounds(x, y, r) then
@@ -423,7 +427,22 @@
     TestColl:= false;
 end;
 
+// Check for collision with hedgehog or object
+function TestCollHogsOrObjects(x, y, r: LongInt): boolean; inline;
+begin
+    if not CheckBounds(x, y, r) then
+        exit(false);
 
+    if (Land[y-r, x-r] and lfAllObjMask <> 0) or
+       (Land[y+r, x-r] and lfAllObjMask <> 0) or
+       (Land[y-r, x+r] and lfAllObjMask <> 0) or
+       (Land[y+r, x+r] and lfAllObjMask <> 0) then
+       exit(true);
+
+    TestCollHogsOrObjects:= false;
+end;
+
+// Check for collision with something other than the given "Me" gear.
 // 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;