# HG changeset patch # User nemo # Date 1367631361 14400 # Node ID a6ee1e7310fbeadb4fcd5e2a8f5d48ace5403c0d # Parent 95dd846caf5d1e6e14ed696a1246d4222c684c49 trying to make AI aware of mine/explosive break point. also remove redundant test. diff -r 95dd846caf5d -r a6ee1e7310fb hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Fri May 03 07:52:57 2013 -0400 +++ b/hedgewars/GSHandlers.inc Fri May 03 21:36:01 2013 -0400 @@ -1425,13 +1425,13 @@ doStepFallingGear(Gear); if (Gear^.Health = 0) then begin - if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then + if (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then inc(Gear^.Damage, hwRound(Gear^.dY * _70)) - else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then + else if (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then inc(Gear^.Damage, hwRound(Gear^.dX * _70)) - else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then + else if (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) - else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then + else if (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then @@ -1585,7 +1585,7 @@ begin DeleteCI(Gear); AllInactive := false; - if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then + if (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then begin Gear^.State := Gear^.State or gsttmpFlag; inc(Gear^.Damage, hwRound(Gear^.dY * _70)); @@ -1596,13 +1596,13 @@ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) end end - else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then + else if (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then inc(Gear^.Damage, hwRound(Gear^.dX * _70)) - else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then + else if (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) - else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then + else if (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); doStepFallingGear(Gear); diff -r 95dd846caf5d -r a6ee1e7310fb hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Fri May 03 07:52:57 2013 -0400 +++ b/hedgewars/uAIAmmoTests.pas Fri May 03 21:36:01 2013 -0400 @@ -686,7 +686,7 @@ if Level > 4 then exit(BadTurn); dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; Level:= Level; // avoid compiler hint -ap.ExplR:= 0; +ap.ExplR:= 1; ap.Time:= 0; ap.Power:= 1; @@ -716,14 +716,8 @@ 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; + valueResult:= RateShove(Me, Targ.X, Targ.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall) +else valueResult:= BadTurn; TestDesertEagle:= valueResult end; @@ -766,15 +760,8 @@ 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 + TestSniperRifle:= RateShove(Me, Targ.X, Targ.Y, 1, trunc(dmg), 20, vX*0.166, vY*0.166, afTrackFall) +else TestSniperRifle:= BadTurn; end; diff -r 95dd846caf5d -r a6ee1e7310fb hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Fri May 03 07:52:57 2013 -0400 +++ b/hedgewars/uAIMisc.pas Fri May 03 21:36:01 2013 -0400 @@ -33,6 +33,7 @@ type TTarget = record Point: TPoint; Score: LongInt; + Density: real; skip, matters, dead: boolean; Kind: TGearType; end; @@ -66,7 +67,7 @@ function TestColl(x, y, r: LongInt): boolean; inline; function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline; function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; -function TraceShoveFall(x, y, dX, dY: Real): LongInt; +function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt; function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; @@ -144,6 +145,7 @@ Point.X:= hwRound(iter^.X); Point.Y:= hwRound(iter^.Y); if (iter^.Kind = gtHedgehog) then + begin if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then begin Score:= iter^.Damage - iter^.Health; @@ -153,9 +155,19 @@ begin Score:= iter^.Health - iter^.Damage; inc(e) - end - else if iter^.Kind = gtExplosives then Score:= iter^.Health - iter^.Damage - else if iter^.Kind = gtMine then Score:= max(0,35-iter^.Damage) + end; + Density:= 1; + end + else if iter^.Kind = gtExplosives then + begin + Score:= iter^.Health - iter^.Damage; + Density:= 2 + end + else if iter^.Kind = gtMine then + begin + Score:= max(0,35-iter^.Damage); + Density:= 1/3 + end end; inc(Targets.Count) end; @@ -351,38 +363,60 @@ -function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord): LongInt; +function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Kind: TGearType): LongInt; var skipLandCheck: boolean; rCorner: real; - dmg: LongInt; + dmg, radius: LongInt; begin skipLandCheck:= true; if x - eX < 0 then dX:= -dX; if y - eY < 0 then dY:= -dY; // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map + if Kind = gtHedgehog then + radius:= cHHRadius + else if Kind = gtExplosives then + radius:= 16 + else if Kind = gtMine then + radius:= 2; rCorner:= r * 0.75; while true do - begin + begin x:= x + dX; y:= y + dY; dY:= dY + cGravityf; skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); - if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then - begin - if 0.4 < dY then + if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), radius) then begin + if (Kind = gtHedgehog) and (0.4 < dY) then + begin dmg := 1 + trunc((abs(dY) - 0.4) * 70); - if dmg >= 1 then - exit(dmg); - end; + if dmg >= 1 then exit(dmg) + end +// so. the problem w/ explosives is it only uses dX or dY depending on impact, and we don't know which we hit. Maybe we didn't even hit, given TestColl check corners. + else + begin + if ((dY > 0.2) and (Land[trunc(y)+radius, trunc(x)] > lfAllObjMask)) or + ((dY < -0.2) and (Land[trunc(y)-radius, trunc(x)] > lfAllObjMask)) then + begin + dmg := 1 + trunc(abs(dY) * 70); + if dmg >= 1 then exit(dmg) + end +// so we don't know at present if a barrel is already rolling. Would need to add that to target info I guess + else if ((Kind = gtMine) or (abs(dX) > 0.15) or ((abs(dY) > 0.15) and (abs(dX) > 0.02))) and + (((dX > 0.2) and (Land[trunc(y), trunc(x)+radius] > lfAllObjMask)) or + ((dX < -0.2) and (Land[trunc(y), trunc(x)-radius] > lfAllObjMask))) then + begin + dmg := 1 + trunc(abs(dX) * 70); + if dmg >= 1 then exit(dmg) + end + end; exit(0) - end; - if (y > cWaterLine) or (x > 4096) or (x < 0) then - exit(-1); - end; + end; + if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1) + end end; -function TraceShoveFall(x, y, dX, dY: Real): LongInt; +function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt; var dmg: LongInt; begin //v:= random($FFFFFFFF); @@ -467,12 +501,12 @@ pY:= Point.y; if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then begin - dX:= 0.005 * dmg + 0.01; + dX:= 0.005 * dmg + 0.01 * Density; dY:= dX; if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then - fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) - else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod) + fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod) + else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod) end; if Kind = gtHedgehog then begin @@ -546,7 +580,7 @@ pY:= Point.y; if (Flags and afSetSkip <> 0) then skip:= true; if (Flags and afTrackFall <> 0) and (Score > 0) then - fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY) * dmgMod); + fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY, Kind) * dmgMod); if Kind = gtHedgehog then begin if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI @@ -634,14 +668,14 @@ begin pX:= Point.x; pY:= Point.y; - dX:= gdX * dmg; - dY:= gdY * dmg; + dX:= gdX * dmg * Density; + dY:= gdY * dmg * Density; if dX < 0 then dX:= dX - 0.01 else dX:= dX + 0.01; if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then - fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) - else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod); + fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod) + else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod); if Kind = gtHedgehog then begin if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI