--- a/hedgewars/uAIAmmoTests.pas Fri Jul 13 16:39:20 2012 +0400
+++ b/hedgewars/uAIAmmoTests.pas Thu Jul 26 21:56:47 2012 +0400
@@ -50,6 +50,7 @@
function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
TAmmoTest = record
@@ -84,7 +85,7 @@
(proc: nil; flags: 0), // amSwitch
(proc: @TestMortar; flags: 0), // amMortar
(proc: nil; flags: 0), // amKamikaze
- (proc: nil; flags: 0), // amCake
+ (proc: @TestCake; flags: amtest_OnTurn or amtest_NoTarget), // amCake
(proc: nil; flags: 0), // amSeduction
(proc: @TestWatermelon; flags: 0), // amWatermelon
(proc: nil; flags: 0), // amHellishBomb
@@ -121,7 +122,7 @@
const BadTurn = Low(LongInt) div 4;
implementation
-uses uAIMisc, uVariables, uUtils;
+uses uAIMisc, uVariables, uUtils, uGearsHandlers, uCollisions;
function Metric(x1, y1, x2, y2: LongInt): LongInt; inline;
begin
@@ -708,19 +709,19 @@
x:= hwRound(Me^.X);
y:= hwRound(Me^.Y);
- a:= 0;
+ a:= cMaxAngle div 2;
valueResult:= 0;
- while a <= cMaxAngle div 2 do
+ while a >= 0 do
begin
dx:= sin(a / cMaxAngle * pi) * 0.5;
dy:= cos(a / cMaxAngle * pi) * 0.5;
- v1:= RateShove(Me, x - 10, y
- , 33, 30, 115
+ v1:= RateShove(Me, x - 10, y + 2
+ , 32, 30, 115
, -dx, -dy, trackFall);
- v2:= RateShove(Me, x + 10, y
- , 33, 30, 115
+ v2:= RateShove(Me, x + 10, y + 2
+ , 32, 30, 115
, dx, -dy, trackFall);
if (v1 > valueResult) or (v2 > valueResult) then
if (v2 > v1)
@@ -735,7 +736,7 @@
valueResult:= v1
end;
- a:= a + 15 + random(cMaxAngle div 16)
+ a:= a - 15 - random(cMaxAngle div 16)
end;
if valueResult <= 0 then
@@ -755,17 +756,17 @@
ap.Time:= 0;
ap.Power:= 1;
x:= hwRound(Me^.X);
- y:= hwRound(Me^.Y);
+ y:= hwRound(Me^.Y) + 4;
v1:= 0;
for i:= 0 to 8 do
begin
- v1:= v1 + RateShove(Me, x - 10, y - 10 * i
- , 18, 30, 40
+ v1:= v1 + RateShove(Me, x - 5, y - 10 * i
+ , 19, 30, 40
, -0.45, -0.9, trackFall or afSetSkip);
end;
- v1:= v1 + RateShove(Me, x - 10, y - 90
- , 18, 30, 40
+ v1:= v1 + RateShove(Me, x - 5, y - 90
+ , 19, 30, 40
, -0.45, -0.9, trackFall);
@@ -773,12 +774,12 @@
v2:= 0;
for i:= 0 to 8 do
begin
- v2:= v2 + RateShove(Me, x + 10, y - 10 * i
- , 18, 30, 40
+ v2:= v2 + RateShove(Me, x + 5, y - 10 * i
+ , 19, 30, 40
, 0.45, -0.9, trackFall or afSetSkip);
end;
- v2:= v2 + RateShove(Me, x + 10, y - 90
- , 18, 30, 40
+ v2:= v2 + RateShove(Me, x + 5, y - 90
+ , 19, 30, 40
, 0.45, -0.9, trackFall);
if (v2 > v1)
@@ -817,7 +818,7 @@
{first RateShove checks farthermost of two whip's AmmoShove attacks
to encourage distant attacks (damaged hog is excluded from view of second
RateShove call)}
- v1:= RateShove(Me, x - 15, y
+ v1:= RateShove(Me, x - 13, y
, 30, 30, 25
, -1, -0.8, trackFall or afSetSkip);
v1:= v1 +
@@ -825,7 +826,7 @@
, 30, 30, 25
, -1, -0.8, trackFall);
// now try opposite direction
- v2:= RateShove(Me, x + 15, y
+ v2:= RateShove(Me, x + 13, y
, 30, 30, 25
, 1, -0.8, trackFall or afSetSkip);
v2:= v2 +
@@ -981,4 +982,74 @@
end;
end;
+
+procedure checkCakeWalk(Me, Gear: PGear; var ap: TAttackParams);
+var i: Longword;
+ v: LongInt;
+begin
+while (not TestColl(hwRound(Gear^.X), hwRound(Gear^.Y), 6)) and (Gear^.Y.Round < LAND_HEIGHT) do
+ Gear^.Y:= Gear^.Y + _1;
+
+for i:= 0 to 2040 do
+ begin
+ cakeStep(Gear);
+ v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall);
+ if v > ap.Power then
+ begin
+ ap.ExplX:= hwRound(Gear^.X);
+ ap.ExplY:= hwRound(Gear^.Y);
+ ap.Power:= v
+ end
+ end;
+end;
+
+function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+var valueResult, v1, v2: LongInt;
+ x, y, trackFall: LongInt;
+ cake: TGear;
+begin
+ Level:= Level; // avoid compiler hint
+ ap.ExplR:= 0;
+ ap.Time:= 0;
+ ap.Power:= BadTurn; // use it as max score value in checkCakeWalk
+
+ FillChar(cake, sizeof(cake), 0);
+ cake.Radius:= 7;
+ cake.CollisionMask:= $FF7F;
+
+ // check left direction
+ cake.Angle:= 3;
+ cake.dX.isNegative:= true;
+ cake.X:= Me^.X - _3;
+ cake.Y:= Me^.Y;
+ checkCakeWalk(Me, @cake, ap);
+ v1:= ap.Power;
+
+ // now try opposite direction
+ cake.Angle:= 1;
+ cake.dX.isNegative:= false;
+ cake.X:= Me^.X + _3;
+ cake.Y:= Me^.Y;
+ checkCakeWalk(Me, @cake, ap);
+ v2:= ap.Power;
+
+ ap.Power:= 1;
+
+ if (v2 > v1) then
+ begin
+ ap.Angle:= 1;
+ valueResult:= v2
+ end
+ else
+ begin
+ ap.Angle:= -1;
+ valueResult:= v1
+ end;
+
+ if valueResult <= 0 then
+ valueResult:= BadTurn;
+
+ TestCake:= valueResult;
+end;
+
end.