diff -r 8c4c6ad6ca99 -r 9643d75baf1e hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Tue Jun 20 20:08:17 2006 +0000 +++ b/hedgewars/uAIMisc.pas Tue Jun 20 21:18:49 2006 +0000 @@ -1,6 +1,6 @@ unit uAIMisc; interface -uses SDLh, uConsts; +uses SDLh, uConsts, uGears; type TTarget = record Point: TPoint; @@ -11,15 +11,33 @@ ar: array[0..cMaxHHIndex*5] of TTarget; end; -procedure FillTargets(var Targets: TTargets); +procedure FillTargets; +procedure FillBonuses; +function CheckBonuses(Gear: PGear): integer; function DxDy2AttackAngle(const _dY, _dX: Extended): integer; function TestColl(x, y, r: integer): boolean; -function NoMyHHNear(x, y, r: integer): boolean; +function RateExplosion(Me: PGear; x, y, r: integer): integer; +function HHGo(Gear: PGear): boolean; + +var ThinkingHH: PGear; + Targets: TTargets; implementation -uses uTeams, uMisc, uLand; +uses uTeams, uMisc, uLand, uCollisions; +const KillScore = 200; + MAXBONUS = 1024; + +type TBonus = record + X, Y: integer; + Radius: Longword; + Score: integer; + end; +var bonuses: record + Count: Longword; + ar: array[0..Pred(MAXBONUS)] of TBonus; + end; -procedure FillTargets(var Targets: TTargets); +procedure FillTargets; var t: PTeam; i: Longword; begin @@ -27,22 +45,61 @@ t:= TeamsList; while t <> nil do begin - if t <> CurrentTeam then - for i:= 0 to cMaxHHIndex do - if t.Hedgehogs[i].Gear <> nil then - begin - with Targets.ar[Targets.Count], t.Hedgehogs[i] do - begin - Point.X:= Round(Gear.X); - Point.Y:= Round(Gear.Y); - Score:= 100 - Gear.Health - end; - inc(Targets.Count) - end; + for i:= 0 to cMaxHHIndex do + if (t.Hedgehogs[i].Gear <> nil) + and (t.Hedgehogs[i].Gear <> ThinkingHH) then + begin + with Targets.ar[Targets.Count], t.Hedgehogs[i] do + begin + Point.X:= Round(Gear.X); + Point.Y:= Round(Gear.Y); + if t <> CurrentTeam then Score:= Gear.Health + else Score:= -Gear.Health + end; + inc(Targets.Count) + end; t:= t.Next end end; +procedure FillBonuses; +var Gear: PGear; + + procedure AddBonus(x, y: integer; r: Longword; s: integer); + begin + bonuses.ar[bonuses.Count].x:= x; + bonuses.ar[bonuses.Count].y:= y; + bonuses.ar[bonuses.Count].Radius:= r; + bonuses.ar[bonuses.Count].Score:= s; + inc(bonuses.Count); + TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) + end; + +begin +bonuses.Count:= 0; +Gear:= GearsList; +while Gear <> nil do + begin + case Gear.Kind of + gtCase: AddBonus(round(Gear.X), round(Gear.Y), 32, 25); + gtMine: AddBonus(round(Gear.X), round(Gear.Y), 45, -50); + gtAmmo_Bomb: AddBonus(round(Gear.X), round(Gear.Y), 50, -100); + gtHedgehog: if Gear.Damage >= Gear.Health then AddBonus(round(Gear.X), round(Gear.Y), 50, -25); + end; + Gear:= Gear.NextGear + end +end; + +function CheckBonuses(Gear: PGear): integer; +var i: integer; +begin +Result:= 0; +for i:= 0 to Pred(bonuses.Count) do + with bonuses.ar[i] do + if sqrt(sqr(Gear.X - X) + sqr(Gear.Y - y)) <= Radius then + inc(Result, Score) +end; + function DxDy2AttackAngle(const _dY, _dX: Extended): integer; const piDIVMaxAngle: Extended = pi/cMaxAngle; asm @@ -67,22 +124,126 @@ Result:=(((x+r) and $FFFFF800) = 0)and(((y+r) and $FFFFFC00) = 0) and (Land[y+r, x+r] <> 0); end; -function NoMyHHNear(x, y, r: integer): boolean; -var i: integer; +function RateExplosion(Me: PGear; x, y, r: integer): integer; +var i, dmg: integer; begin -i:= 0; -r:= sqr(r); -Result:= true; +Result:= 0; +// add our virtual position +with Targets.ar[Targets.Count] do + begin + Point.x:= round(Me.X); + Point.y:= round(Me.Y); + Score:= - ThinkingHH.Health + end; +// rate explosion +for i:= 0 to Targets.Count do + with Targets.ar[i] do + begin + dmg:= r - Round(sqrt(sqr(Point.x - x) + sqr(Point.y - y))); + if dmg > 0 then + begin + dmg:= dmg shr 1; + if dmg > abs(Score) then + if Score > 0 then inc(Result, KillScore) + else dec(Result, KillScore * 3) + else + if Score > 0 then inc(Result, dmg) + else dec(Result, dmg * 3) + end; + end; +end; + +function HHGo(Gear: PGear): boolean; +var pX, pY: integer; +begin +Result:= false; repeat - with CurrentTeam.Hedgehogs[i] do - if Gear <> nil then - if sqr(Gear.X - x) + sqr(Gear.Y - y) <= r then - begin - Result:= false; - exit - end; -inc(i) -until i > cMaxHHIndex +pX:= round(Gear.X); +pY:= round(Gear.Y); +if pY + cHHRadius >= cWaterLine then exit; +if (Gear.State and gstFalling) <> 0 then + begin + Gear.dY:= Gear.dY + cGravity; + if Gear.dY > 0.35 then exit; + Gear.Y:= Gear.Y + Gear.dY; + if TestCollisionYwithGear(Gear, 1) then + begin + Gear.State:= Gear.State and not (gstFalling or gstHHJumping); + Gear.dY:= 0 + end; + continue + end; + {if ((Gear.Message and gm_LJump )<>0) then + begin + Gear.Message:= 0; + if not HHTestCollisionYwithGear(Gear, -1) then + if not TestCollisionXwithXYShift(Gear, 0, -2, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 2 else + if not TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithGear(Gear, Sign(Gear.dX)) + or HHTestCollisionYwithGear(Gear, -1)) then + begin + Gear.dY:= -0.15; + Gear.dX:= Sign(Gear.dX) * 0.15; + Gear.State:= Gear.State or gstFalling or gstHHJumping; + exit + end; + end;} + if (Gear.Message and gm_Left )<>0 then Gear.dX:= -1.0 else + if (Gear.Message and gm_Right )<>0 then Gear.dX:= 1.0 else exit; + if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then + begin + if not (TestCollisionXwithXYShift(Gear, 0, -6, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithXYShift(Gear, 0, -5, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithXYShift(Gear, 0, -4, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithXYShift(Gear, 0, -3, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithXYShift(Gear, 0, -2, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + if not (TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX)) + or TestCollisionYwithGear(Gear, -1)) then Gear.Y:= Gear.Y - 1; + end; + + if not TestCollisionXwithGear(Gear, Sign(Gear.dX)) then Gear.X:= Gear.X + Gear.dX; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y + 1; + if not TestCollisionYwithGear(Gear, 1) then + begin + Gear.Y:= Gear.Y - 6; + Gear.dY:= 0; + Gear.dX:= 0.0000001 * Sign(Gear.dX); + Gear.State:= Gear.State or gstFalling + end + end + end + end + end + end + end; +if (pX <> round(Gear.X))and ((Gear.State and gstFalling) = 0) then + begin + Result:= true; + exit + end; +until (pX = round(Gear.X)) and (pY = round(Gear.Y)) and ((Gear.State and gstFalling) = 0); end; end.