# HG changeset patch # User nemo # Date 1331491416 14400 # Node ID ccbf07b38a4396b2de3a961ed6af41f69ef5e917 # Parent 31ba56a8ec433bb32eb027cb28460147904a0189 First pass at making AI drowning aware. No concerns of performance, only applied to bazooka (not bat/fp etc) diff -r 31ba56a8ec43 -r ccbf07b38a43 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Sun Mar 11 12:19:04 2012 -0400 +++ b/hedgewars/uAIAmmoTests.pas Sun Mar 11 14:43:36 2012 -0400 @@ -158,7 +158,9 @@ EX:= trunc(x); EY:= trunc(y); - value:= RateExplosion(Me, EX, EY, 101); + if Me^.Hedgehog^.BotLevel = 1 then + value:= RateExplosion(Me, EX, EY, 101, 3) + else value:= RateExplosion(Me, EX, EY, 101); if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; if valueResult <= value then diff -r 31ba56a8ec43 -r ccbf07b38a43 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Sun Mar 11 12:19:04 2012 -0400 +++ b/hedgewars/uAIMisc.pas Sun Mar 11 14:43:36 2012 -0400 @@ -49,11 +49,11 @@ procedure FillTargets; procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []); -procedure AwareOfExplosion(x, y, r: LongInt); +procedure AwareOfExplosion(x, y, r: LongInt); inline; function RatePlace(Gear: PGear): LongInt; -function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; -function TestColl(x, y, r: LongInt): boolean; -function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; +function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; +function TestColl(x, y, r: LongInt): boolean; inline; +function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt; function RateShotgun(Me: PGear; x, y: LongInt): LongInt; function RateHammer(Me: PGear): LongInt; @@ -115,7 +115,7 @@ else friendlyfactor:= max(30, 300 - f * 80 div max(1,e)) end; -procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); +procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline; begin bonuses.ar[bonuses.Count].x:= x; bonuses.ar[bonuses.Count].y:= y; @@ -234,8 +234,46 @@ TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) end; -function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; -var i, dmg, dmgBase, rate: LongInt; +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] > 255); +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] > 255); +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] > 255); +if b then + exit(true); + +TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) +end; + +function TraceDrown(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): boolean; +var skipLandCheck: boolean; + rCorner: real; +begin + if x - eX < 0 then dX*=-1; + if y - eY < 0 then dY*=-1; + // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map + rCorner:= r * 0.75; + while true do + begin + x:= x + dX; + y:= y + dY + cGravityf; + skipLandCheck:= (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); + if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false); + if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); + end; +end; + +// Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. +function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; +var i, dmg, dmgBase, rate, erasure: LongInt; + dX, dY: real; begin rate:= 0; // add our virtual position @@ -247,6 +285,8 @@ end; // rate explosion dmgBase:= r + cHHRadius div 2; +if (Flags and 2 <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r +else erasure:= 0; for i:= 0 to Targets.Count do with Targets.ar[i] do begin @@ -256,7 +296,19 @@ if dmg > 0 then begin - if dmg >= abs(Score) then + if Flags and 1 <> 0 then + begin + dX:= 0.005 * dmg + 0.01; + dY:= dX; + end; + if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then + if Score > 0 then + begin + inc(rate, KillScore) + end + else + dec(rate, KillScore * friendlyfactor div 100) + else if dmg >= abs(Score) then if Score > 0 then inc(rate, KillScore) else