# HG changeset patch # User Wuzzy # Date 1591652258 -7200 # Node ID d9c62f196fe034f98c850f78b3ee93ed7a8e0f5f # Parent 39a353e8ef3df6422231f1f794e1b155623e2cb3 Teach AI to use air mines diff -r 39a353e8ef3d -r d9c62f196fe0 ChangeLog.txt --- a/ChangeLog.txt Mon Jun 08 21:53:45 2020 +0200 +++ b/ChangeLog.txt Mon Jun 08 23:37:38 2020 +0200 @@ -12,9 +12,9 @@ + New taunt chat commands: /bubble, /happy + Teach computer players how to ... + - drop mines from a cliff - + - use drill strike and piano strike + + - use drill strike, piano strike, air mine + - use mine strike (0 seconds only) - + - use RC plane (very basic, no bombs) + + - use RC plane (very basic) * Racer: Resize waypoints in custom-sized drawn maps * Mutant: Fix impossible to become mutant after mutant is gone * A Classic Fairytale: Mission 1: Fix possibility of getting stuck in “Leap of Faith” section diff -r 39a353e8ef3d -r d9c62f196fe0 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Mon Jun 08 21:53:45 2020 +0200 +++ b/hedgewars/uAIAmmoTests.pas Mon Jun 08 23:37:38 2020 +0200 @@ -62,6 +62,7 @@ function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +function TestAirMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; TAmmoTest = record @@ -129,7 +130,7 @@ (proc: nil; flags: 0), // amIceGun (proc: nil; flags: 0), // amKnife (proc: nil; flags: 0), // amRubber - (proc: nil; flags: 0), // amAirMine + (proc: @TestAirMine; flags: 0), // amAirMine (proc: nil; flags: 0), // amCreeper (proc: @TestShotgun; flags: 0) // amMinigun ); @@ -1911,4 +1912,74 @@ TestMine:= valueResult end; +function TestAirMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +const + MIN_RANGE = 160; + MAX_RANGE = 2612; +var Vx, Vy, meX, meY, x, y, r: real; + rx, ry, valueResult: LongInt; + range, maxRange: integer; +begin +Flags:= Flags; // avoid compiler hint +maxRange:= MAX_RANGE - ((Level - 1) * 300); +TestAirMine:= BadTurn; +ap.ExplR:= 60; +ap.Time:= 0; +meX:= hwFloat2Float(Me^.X); +meY:= hwFloat2Float(Me^.Y); +x:= meX; +y:= meY; + +// Rough first range check +range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y); +if ( range < MIN_RANGE ) or ( range > maxRange ) then + exit(BadTurn); + +Vx:= (Targ.Point.X - x) * 1 / 1024; +Vy:= (Targ.Point.Y - y) * 1 / 1024; +ap.Angle:= DxDy2AttackAnglef(Vx, -Vy); +repeat + x:= x + vX; + y:= y + vY; + rx:= trunc(x); + ry:= trunc(y); + if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 8)) or + ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 8)) then + begin + x:= x + vX * 8; + y:= y + vY * 8; + + if Level = 1 then + valueResult:= RateExplosion(Me, rx, ry, 61, afTrackFall) + else + valueResult:= RateExplosion(Me, rx, ry, 61); + + // Precise range calculation required to calculate power; + // The air mine is very sensitive to small changes in power. + r:= sqr(meX - rx) + sqr(meY - ry); + range:= trunc(sqrt(r)); + + if ( range < MIN_RANGE ) or ( range > maxRange ) then + exit(BadTurn); + ap.Power:= ((range + cHHRadius*2) * cMaxPower) div MAX_RANGE; + + // Apply inaccuracy + inc(ap.Power, (random(93*(Level-1)) - 31*(Level-1))); // Level 1 spread: -124 .. 248 + if (not cLaserSighting) then + inc(ap.Angle, + AIrndSign(random((Level - 1) * 10))); + + if (valueResult <= 0) then + valueResult:= BadTurn; + exit(valueResult) + end +until (abs(Targ.Point.X - trunc(x)) + abs(Targ.Point.Y - trunc(y)) < 4) + or (x < 0) + or (y < 0) + or (trunc(x) > LAND_WIDTH) + or (trunc(y) > LAND_HEIGHT); + +TestAirMine := BadTurn +end; + + end.