--- a/hedgewars/uAIAmmoTests.pas Thu Apr 04 14:37:19 2013 +0200
+++ b/hedgewars/uAIAmmoTests.pas Tue Jun 04 22:28:12 2013 +0200
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
unit uAIAmmoTests;
interface
-uses SDLh, uConsts, uFloat, uTypes;
+uses SDLh, uConsts, uFloat, uTypes, uAIMisc;
const
amtest_Rare = $00000001; // check only several positions
amtest_NoTarget = $00000002; // each pos, but no targetting
@@ -34,27 +34,27 @@
AttackPutX, AttackPutY: LongInt;
end;
-function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestDrillRocket(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-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;
+function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
-type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
TAmmoTest = record
proc: TAmmoTestProc;
flags: Longword;
@@ -123,14 +123,14 @@
);
implementation
-uses uAIMisc, uVariables, uUtils, uGearsHandlers;
+uses uVariables, uUtils, uGearsHandlers;
function Metric(x1, y1, x2, y2: LongInt): LongInt; inline;
begin
Metric:= abs(x1 - x2) + abs(y1 - y2)
end;
-function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r, mX, mY: real;
rTime: LongInt;
EX, EY: LongInt;
@@ -147,8 +147,8 @@
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - windSpeed * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y + 1 - mY) / rTime;
+ Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - mY) / rTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -164,15 +164,15 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0);
EX:= trunc(x);
EY:= trunc(y);
if Level = 1 then
value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
else value:= RateExplosion(Me, EX, EY, 101);
- if value = 0 then
- value:= 1024 - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ value:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64;
if valueResult <= value then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
@@ -184,12 +184,12 @@
end;
end
//until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning
-until rTime > 4250;
+until rTime > 5050 - Level * 800;
TestBazooka:= valueResult
end;
-function TestDrillRocket(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r, mX, mY: real;
rTime: LongInt;
EX, EY: LongInt;
@@ -210,8 +210,8 @@
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - windSpeed * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y - 35 - mY) / rTime;
+ Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - 35 - mY) / rTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -227,9 +227,9 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (y > cWaterLine);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (y > cWaterLine);
- if TestCollWithLand(trunc(x), trunc(y), 5) and (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) > 21) then
+ if TestCollExcludingObjects(trunc(x), trunc(y), 5) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then
begin
timer := 500;
t2 := 0.5 / sqrt(sqr(dX) + sqr(dY));
@@ -239,16 +239,18 @@
x:= x + dX;
y:= y + dY;
dec(timer);
- until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 22)
+ until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 22)
or (x < 0)
or (y < 0)
or (trunc(x) > LAND_WIDTH)
or (trunc(y) > LAND_HEIGHT)
- or (not TestCollWithLand(trunc(x), trunc(y), 5))
+ or not TestCollExcludingObjects(trunc(x), trunc(y), 5)
or (timer = 0)
end;
EX:= trunc(x);
EY:= trunc(y);
+ // Try to prevent AI from thinking firing into water will cause a drowning
+ if (EY < cWaterLine-5) and (Timer > 0) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then exit(BadTurn);
if Level = 1 then
value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
else value:= RateExplosion(Me, EX, EY, 101);
@@ -262,12 +264,12 @@
valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count
end;
end
- until rTime > 4250;
+ until rTime > 5050 - Level * 800;
TestDrillRocket:= valueResult
end;
-function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r: real;
rTime: LongInt;
EX, EY: LongInt;
@@ -285,8 +287,8 @@
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(1000);
- Vx:= - windSpeed * rTime * 0.5 + ((Targ.X + AIrndSign(2)) - meX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y - meY) / rTime;
+ Vx:= - windSpeed * rTime * 0.5 + ((Targ.Point.X + AIrndSign(2)) - meX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - meY) / rTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -302,14 +304,14 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0);
EX:= trunc(x);
EY:= trunc(y);
- value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
+ value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
// LOL copypasta: this is score for digging with... snowball
//if value = 0 then
- // value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ // value:= - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64;
if valueResult <= value then
begin
@@ -321,11 +323,11 @@
valueResult:= value
end;
end
-until (rTime > 4250);
+until (rTime > 5050 - Level * 800);
TestSnowball:= valueResult
end;
-function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
TestTime: Longword;
@@ -339,8 +341,8 @@
ap.ExplR:= 0;
repeat
inc(TestTime, 300);
- Vx:= (Targ.X - meX) / TestTime;
- Vy:= cGravityf * (TestTime div 2) - Targ.Y - meY / TestTime;
+ Vx:= (Targ.Point.X - meX) / TestTime;
+ Vy:= cGravityf * (TestTime div 2) - Targ.Point.Y - meY / TestTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -354,7 +356,7 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
if t < 50 then
@@ -372,11 +374,11 @@
valueResult:= Score
end;
end
-until (TestTime > 4250);
+until (TestTime > 5050 - Level * 800);
TestMolotov:= valueResult
end;
-function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -391,8 +393,8 @@
meY:= hwFloat2Float(Me^.Y);
repeat
inc(TestTime, 1000);
- Vx:= (Targ.X - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta);
+ Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta);
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -406,7 +408,7 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
if t < 50 then
@@ -418,8 +420,8 @@
if (valueResult < Score) and (Score > 0) then
begin
- ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
- ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
+ ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 3));
+ ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 20);
ap.Time:= TestTime;
ap.ExplR:= 100;
ap.ExplX:= EX;
@@ -428,11 +430,11 @@
end;
end
//until (Score > 204800) or (TestTime > 4000);
-until TestTime > 4000;
+until TestTime > 4500 - Level * 512;
TestGrenade:= valueResult
end;
-function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -448,11 +450,11 @@
repeat
inc(TestTime, 900);
// Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
- if meX<Targ.X then
- Vx:= ((Targ.X+10) - meX) / (TestTime + tDelta)
+ if meX<Targ.Point.X then
+ Vx:= ((Targ.Point.X+10) - meX) / (TestTime + tDelta)
else
- Vx:= ((Targ.X-10) - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
+ Vx:= ((Targ.Point.X-10) - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
r:= sqr(Vx)+sqr(Vy);
if not (r > 1) then
begin
@@ -466,7 +468,7 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
if t < 50 then
@@ -474,9 +476,9 @@
else
Score:= BadTurn;
- if valueResult < Score then
+ if Score > 0 then
begin
- ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
+ ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 2));
ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
ap.Time:= TestTime div 1000 * 1000;
ap.ExplR:= 90;
@@ -489,7 +491,7 @@
TestClusterBomb:= valueResult
end;
-function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -504,8 +506,8 @@
meY:= hwFloat2Float(Me^.Y);
repeat
inc(TestTime, 900);
- Vx:= (Targ.X - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
+ Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
r:= sqr(Vx)+sqr(Vy);
if not (r > 1) then
begin
@@ -519,7 +521,7 @@
dY:= dY + cGravityf;
dec(t)
until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
@@ -565,7 +567,7 @@
Solve:= 0
end;
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
//const tDelta = 24;
var Vx, Vy: real;
Score, EX, EY: LongInt;
@@ -581,13 +583,13 @@
if (Level > 2) then
exit(BadTurn);
- TestTime:= Solve(Targ.X, Targ.Y, trunc(meX), trunc(meY));
+ TestTime:= Solve(Targ.Point.X, Targ.Point.Y, trunc(meX), trunc(meY));
if TestTime = 0 then
exit(BadTurn);
- Vx:= (Targ.X - meX) / TestTime;
- Vy:= cGravityf * (TestTime div 2) - (Targ.Y - meY) / TestTime;
+ Vx:= (Targ.Point.X - meX) / TestTime;
+ Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime;
x:= meX;
y:= meY;
@@ -600,14 +602,14 @@
EX:= trunc(x);
EY:= trunc(y);
until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine);
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, EX, EY, 4))) or (EY > cWaterLine);
if (EY < cWaterLine) and (dY >= 0) then
begin
Score:= RateExplosion(Me, EX, EY, 91);
if (Score = 0) then
- if (dY > 0.15) then
- Score:= - abs(Targ.Y - EY) div 32
+ if (dY > 0.15) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ Score:= - abs(Targ.Point.Y - EY) div 32
else
Score:= BadTurn
else if (Score < 0) then
@@ -616,7 +618,7 @@
else
Score:= BadTurn;
- if BadTurn < Score then
+ if Score > 0 then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
ap.Power:= 1;
@@ -627,7 +629,7 @@
end;
end;
-function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const
MIN_RANGE = 80;
MAX_RANGE = 400;
@@ -641,12 +643,12 @@
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-range:= Metric(trunc(x), trunc(y), Targ.X, Targ.Y);
+range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y);
if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then
exit(BadTurn);
-Vx:= (Targ.X - x) * 1 / 1024;
-Vy:= (Targ.Y - y) * 1 / 1024;
+Vx:= (Targ.Point.X - x) * 1 / 1024;
+Vy:= (Targ.Point.Y - y) * 1 / 1024;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
repeat
x:= x + vX;
@@ -654,20 +656,20 @@
rx:= trunc(x);
ry:= trunc(y);
if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 2)) then
begin
x:= x + vX * 8;
y:= y + vY * 8;
valueResult:= RateShotgun(Me, vX, vY, rx, ry);
- if valueResult = 0 then
- valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64
+ if (valueResult = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64
else
dec(valueResult, Level * 4000);
// 27/20 is reuse bonus
exit(valueResult * 27 div 20)
end
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
+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)
@@ -676,27 +678,26 @@
TestShotgun:= BadTurn
end;
-function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var Vx, Vy, x, y, t, dmgMod: real;
+function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+var Vx, Vy, x, y, t: real;
d: Longword;
fallDmg, valueResult: LongInt;
begin
-if Level > 4 then exit(BadTurn);
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
+if (Level > 4) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn);
Level:= Level; // avoid compiler hint
-ap.ExplR:= 0;
+ap.ExplR:= 1;
ap.Time:= 0;
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 20 then
+if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 20 then
exit(BadTurn);
-t:= 2 / sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y));
-Vx:= (Targ.X - x) * t;
-Vy:= (Targ.Y - y) * t;
+t:= 2 / sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y));
+Vx:= (Targ.Point.X - x) * t;
+Vy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
d:= 0;
@@ -706,47 +707,40 @@
if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0)
and (Land[trunc(y), trunc(x)] <> 0) then
inc(d);
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5)
+until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5)
or (x < 0)
or (y < 0)
or (trunc(x) > LAND_WIDTH)
or (trunc(y) > LAND_HEIGHT)
or (d > 48);
-if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5 then
- begin
- fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00125 * 20, vY * 0.00125 * 20);
- if fallDmg < 0 then
- valueResult:= 204800
- else valueResult:= Max(0, (4 - d div 12) * trunc((7 + fallDmg) * dmgMod) * 1024)
- end
-else
- valueResult:= BadTurn;
+if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5 then
+ valueResult:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall)
+else valueResult:= BadTurn;
TestDesertEagle:= valueResult
end;
-function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var Vx, Vy, x, y, t, dmg, dmgMod: real;
+function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+var Vx, Vy, x, y, t, dmg: real;
d: Longword;
fallDmg: LongInt;
begin
-if Level > 3 then exit(BadTurn);
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
+if (Level > 3) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn);
Level:= Level; // avoid compiler hint
ap.ExplR:= 0;
ap.Time:= 0;
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 40 then
+if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 40 then
exit(BadTurn);
-dmg:= sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y));
+dmg:= sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y));
t:= 1.5 / dmg;
dmg:= dmg * 0.025; // div 40
-Vx:= (Targ.X - x) * t;
-Vy:= (Targ.Y - y) * t;
+Vx:= (Targ.Point.X - x) * t;
+Vy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
d:= 0;
@@ -756,27 +750,20 @@
if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0)
and (Land[trunc(y), trunc(x)] <> 0) then
inc(d);
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
+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)
or (d > 22);
-if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then
- begin
- fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg);
- if fallDmg < 0 then
- TestSniperRifle:= BadTurn
- else
- TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024)
- end
-else
- TestSniperRifle:= BadTurn
+if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4 then
+ TestSniperRifle:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, trunc(dmg), 20, vX*0.166, vY*0.166, afTrackFall)
+else TestSniperRifle:= BadTurn;
end;
-function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, a, v1, v2: LongInt;
x, y, trackFall: LongInt;
dx, dy: real;
@@ -800,10 +787,10 @@
dx:= sin(a / cMaxAngle * pi) * 0.5;
dy:= cos(a / cMaxAngle * pi) * 0.5;
- v1:= RateShove(x - 10, y + 2
+ v1:= RateShove(Me, x - 10, y + 2
, 32, 30, 115
, -dx, -dy, trackFall);
- v2:= RateShove(x + 10, y + 2
+ v2:= RateShove(Me, x + 10, y + 2
, 32, 30, 115
, dx, -dy, trackFall);
if (v1 > valueResult) or (v2 > valueResult) then
@@ -828,7 +815,7 @@
TestBaseballBat:= valueResult;
end;
-function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2, i: LongInt;
x, y, trackFall: LongInt;
begin
@@ -846,11 +833,11 @@
v1:= 0;
for i:= 0 to 8 do
begin
- v1:= v1 + RateShove(x - 5, y - 10 * i
+ v1:= v1 + RateShove(Me, x - 5, y - 10 * i
, 19, 30, 40
, -0.45, -0.9, trackFall or afSetSkip);
end;
- v1:= v1 + RateShove(x - 5, y - 90
+ v1:= v1 + RateShove(Me, x - 5, y - 90
, 19, 30, 40
, -0.45, -0.9, trackFall);
@@ -859,11 +846,11 @@
v2:= 0;
for i:= 0 to 8 do
begin
- v2:= v2 + RateShove(x + 5, y - 10 * i
+ v2:= v2 + RateShove(Me, x + 5, y - 10 * i
, 19, 30, 40
, 0.45, -0.9, trackFall or afSetSkip);
end;
- v2:= v2 + RateShove(x + 5, y - 90
+ v2:= v2 + RateShove(Me, x + 5, y - 90
, 19, 30, 40
, 0.45, -0.9, trackFall);
@@ -886,7 +873,7 @@
end;
-function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2: LongInt;
x, y, trackFall: LongInt;
begin
@@ -905,19 +892,19 @@
{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(x - 13, y
+ v1:= RateShove(Me, x - 13, y
, 30, 30, 25
, -1, -0.8, trackFall or afSetSkip);
v1:= v1 +
- RateShove(x - 2, y
+ RateShove(Me, x - 2, y
, 30, 30, 25
, -1, -0.8, trackFall);
// now try opposite direction
- v2:= RateShove(x + 13, y
+ v2:= RateShove(Me, x + 13, y
, 30, 30, 25
, 1, -0.8, trackFall or afSetSkip);
v2:= v2 +
- RateShove(x + 2, y
+ RateShove(Me, x + 2, y
, 30, 30, 25
, 1, -0.8, trackFall);
@@ -941,7 +928,7 @@
TestWhip:= valueResult;
end;
-function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const step = 8;
var valueResult, i, v, tx: LongInt;
trackFall: LongInt;
@@ -963,7 +950,7 @@
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
- d:= sqrt(sqr(Targ.X - x) + sqr(Targ.Y - y));
+ d:= sqrt(sqr(Targ.Point.X - x) + sqr(Targ.Point.Y - y));
if d < 10 then
begin
dx:= 0;
@@ -973,8 +960,8 @@
else
begin
t:= step / d;
- dx:= (Targ.X - x) * t;
- dy:= (Targ.Y - y) * t;
+ dx:= (Targ.Point.X - x) * t;
+ dy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(dx, -dy)
end;
@@ -984,7 +971,7 @@
for i:= 0 to 512 div step - 2 do
begin
valueResult:= valueResult +
- RateShove(trunc(x), trunc(y)
+ RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall or afSetSkip);
@@ -996,14 +983,14 @@
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
tx:= trunc(x);
- v:= RateShove(tx, trunc(y)
+ v:= RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall);
for i:= 1 to 512 div step - 2 do
begin
y:= y + dy;
v:= v +
- RateShove(tx, trunc(y)
+ RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall or afSetSkip);
end
@@ -1014,7 +1001,7 @@
valueResult:= v
end;
- v:= RateShove(trunc(x), trunc(y)
+ v:= RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall);
valueResult:= valueResult + v - KillScore * friendlyfactor div 100 * 1024;
@@ -1025,7 +1012,7 @@
TestKamikaze:= valueResult;
end;
-function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var rate: LongInt;
begin
Level:= Level; // avoid compiler hint
@@ -1042,7 +1029,7 @@
TestHammer:= rate;
end;
-function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const cShift = 4;
var bombsSpeed, X, Y, dY: real;
b: array[0..9] of boolean;
@@ -1056,12 +1043,12 @@
exit(BadTurn);
ap.Angle:= 0;
-ap.AttackPutX:= Targ.X;
-ap.AttackPutY:= Targ.Y;
+ap.AttackPutX:= Targ.Point.X;
+ap.AttackPutY:= Targ.Point.Y;
bombsSpeed:= hwFloat2Float(cBombsSpeed);
-X:= Targ.X - 135 - cShift; // hh center - cShift
-X:= X - bombsSpeed * sqrt(((Targ.Y + 128) * 2) / cGravityf);
+X:= Targ.Point.X - 135 - cShift; // hh center - cShift
+X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
Y:= -128;
dY:= 0;
@@ -1093,7 +1080,7 @@
for i:= 0 to 5 do inc(valueResult, dmg[i]);
t:= valueResult;
-ap.AttackPutX:= Targ.X - 60;
+ap.AttackPutX:= Targ.Point.X - 60;
for i:= 0 to 3 do
begin
@@ -1102,7 +1089,7 @@
if t > valueResult then
begin
valueResult:= t;
- ap.AttackPutX:= Targ.X - 30 - cShift + i * 30
+ ap.AttackPutX:= Targ.Point.X - 30 - cShift + i * 30
end
end;
@@ -1112,7 +1099,7 @@
end;
-function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var
i, failNum: longword;
maxTop: longword;
@@ -1125,15 +1112,15 @@
begin
if Me^.Health <= 100 then
begin
- maxTop := Targ.Y - cHHRadius * 2;
+ maxTop := Targ.Point.Y - cHHRadius * 2;
- while (not TestColl(Targ.X, maxTop, cHHRadius)) and (maxTop > topY + cHHRadius * 2 + 1) do
+ while not TestColl(Targ.Point.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do
dec(maxTop, cHHRadius*2);
- if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then
+ if not TestColl(Targ.Point.X, maxTop + cHHRadius, cHHRadius) then
begin
- ap.AttackPutX := Targ.X;
+ ap.AttackPutX := Targ.Point.X;
ap.AttackPutY := maxTop + cHHRadius;
- TestTeleport := Targ.Y - maxTop;
+ TestTeleport := Targ.Point.Y - maxTop;
end;
end;
end
@@ -1176,7 +1163,7 @@
end;
end;
-function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2: LongInt;
cake: TGear;
begin