# HG changeset patch # User Wuzzy # Date 1595150420 -7200 # Node ID cc8882e4678427b27741f67ca2b3ffd6dc5c61c0 # Parent f9c2fd4bfb3e3c2fb8bdf05b6da141b1ad5f2a14 AI: Fix bad AI collision checks diff -r f9c2fd4bfb3e -r cc8882e46784 hedgewars/uAIAmmoTests.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; diff -r f9c2fd4bfb3e -r cc8882e46784 hedgewars/uAIMisc.pas --- 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;