# HG changeset patch # User nemo # Date 1367808617 14400 # Node ID 9780e79619ed468a5b8ccc056a240edac5754eab # Parent b157302674cf3c4afba4dfeacc71d6531b1de723 So. This at least should make the math more accurate, even if it still doesn't appear to resolve prob w/ AI attacks diff -r b157302674cf -r 9780e79619ed hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sat May 04 21:58:42 2013 -0400 +++ b/hedgewars/GSHandlers.inc Sun May 05 22:50:17 2013 -0400 @@ -1427,7 +1427,7 @@ if (Gear^.Health = 0) then begin dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY); - if (dxdy > _0_3) and + if (dxdy > _0_35) and ((TestCollisionYwithGear(Gear, 1) <> 0) or TestCollisionXwithGear(Gear, 1) or (TestCollisionYwithGear(Gear, -1) <> 0) or @@ -1566,11 +1566,6 @@ /////////////////////////////////////////////////////////////////////////////// -(* -TODO -Increase damage as barrel smokes? -Try tweaking friction some more -*) procedure doStepRollingBarrel(Gear: PGear); var i: LongInt; @@ -1587,7 +1582,7 @@ DeleteCI(Gear); AllInactive := false; dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY); - if (dxdy > _0_3) then + if (dxdy > _0_35) then begin if (TestCollisionYwithGear(Gear, 1) <> 0) then begin @@ -1676,7 +1671,10 @@ begin //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then - Gear^.doStep := @doStepRollingBarrel + begin + Gear^.doStep := @doStepRollingBarrel; + exit; + end else Gear^.dX:= _0; if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then diff -r b157302674cf -r 9780e79619ed hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Sat May 04 21:58:42 2013 -0400 +++ b/hedgewars/uAIMisc.pas Sun May 05 22:50:17 2013 -0400 @@ -30,9 +30,10 @@ BadTurn = Low(LongInt) div 4; -type TTarget = record +type TTarget = record // starting to look more and more like a gear Point: TPoint; - Score: LongInt; + Score, Radius: LongInt; + Flags: LongWord; Density: real; skip, matters, dead: boolean; Kind: TGearType; @@ -123,7 +124,7 @@ Gear:= GearsList; while Gear <> nil do begin - if ((Gear^.Kind = gtHedgehog) and + if (((Gear^.Kind = gtHedgehog) and (Gear <> ThinkingHH) and (Gear^.Health > Gear^.Damage) and not(Gear^.Hedgehog^.Team^.hasgone)) or @@ -135,7 +136,7 @@ ((Gear^.Health > 0) and (cMineDudPercent > 95) and (cMinesTime < 3000)) - ) and + )) and (Targets.Count < 256) then begin with Targets.ar[Targets.Count] do @@ -143,6 +144,8 @@ skip:= false; dead:= false; Kind:= Gear^.Kind; + Radius:= Gear^.Radius; + Flags:= Gear^.State; matters:= (Gear^.AIHints and aihDoesntMatter) = 0; Point.X:= hwRound(Gear^.X); @@ -366,21 +369,17 @@ -function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Kind: TGearType): LongInt; +function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Target: TTarget): LongInt; var skipLandCheck: boolean; - rCorner, dxdy: real; - dmg, radius: LongInt; + rCorner, dxdy, odX, odY: real; + dmg: LongInt; begin + odX:= dX; + odY:= dY; 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 @@ -388,41 +387,46 @@ 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), 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 - else + if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), Target.Radius) then + with Target do begin - dxdy:= abs(dX)+abs(dY); -// so we don't know at present if a barrel is already rolling. Would need to add that to target info I guess -// a barrel oriented vertically only considers dY. however, AI doesn't know to use hammer, and could only bat vertically w/ bat, so probably shouldn't matter - if (dxdy > 0.3) then + if (Kind = gtHedgehog) and (0.4 < dY) then + begin + dmg := 1 + trunc((abs(dY) - 0.4) * 70); + if dmg >= 1 then exit(dmg) + end + else begin - dmg := 1 + trunc(dxdy * 25); - exit(dmg) - end - end; + dxdy:= abs(dX)+abs(dY); + if ((Kind = gtMine) and (dxdy > 0.35)) or + ((Kind = gtExplosives) and + (((Flags and gstTmpFlag <> 0) and (dxdy > 0.35)) or + ((Flags and gstTmpFlag <> 0) and + ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and + (abs(odX) > 0.02))) and (dxdy > 0.35)))) then + begin + dmg := 1 + trunc(dxdy * 25); + exit(dmg) + end + else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then + begin + dmg := 1 + trunc(dy * 70); + exit(dmg) + end + end; exit(0) end; if (y > cWaterLine) or (x > leftX) or (x < rightX) then exit(-1) end end; -function TraceShoveFall(var x, y: Real; dX, dY: Real; Kind: TGearType): LongInt; -var dmg, radius: LongInt; - dxdy: real; +function TraceShoveFall(var x, y: Real; dX, dY: Real; Target: TTarget): LongInt; +var dmg: LongInt; + dxdy, odX, odY: real; begin + odX:= dX; + odY:= dY; //v:= random($FFFFFFFF); - if Kind = gtHedgehog then - radius:= cHHRadius - else if Kind = gtExplosives then - radius:= 16 - else if Kind = gtMine then - radius:= 2; while true do begin x:= x + dX; @@ -435,27 +439,34 @@ UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true); end;} - - // consider adding dX/dY calc here for fall damage - if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then - begin - if (Kind = gtHedgehog) and (0.4 < dY) then + if TestCollExcludingObjects(trunc(x), trunc(y), Target.Radius) then + with Target do begin - dmg := 1 + trunc((abs(dY) - 0.4) * 70); - if dmg >= 1 then - exit(dmg); - end - else - begin - dxdy:= abs(dX)+abs(dY); -// so we don't know at present if a barrel is already rolling. Would need to add that to target info I guess -// a barrel oriented vertically only considers dY. however, AI doesn't know to use hammer, and could only bat vertically w/ bat, so probably shouldn't matter - if (dxdy > 0.3) then + if (Kind = gtHedgehog) and (0.4 < dY) then + begin + dmg := 1 + trunc((abs(dY) - 0.4) * 70); + if dmg >= 1 then + exit(dmg); + end + else begin - dmg := 1 + trunc(dxdy * 25); - exit(dmg) - end - end; + dxdy:= abs(dX)+abs(dY); + if ((Kind = gtMine) and (dxdy > 0.35)) or + ((Kind = gtExplosives) and + (((Flags and gstTmpFlag <> 0) and (dxdy > 0.35)) or + ((Flags and gstTmpFlag <> 0) and + ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and + (abs(odX) > 0.02))) and (dxdy > 0.35)))) then + begin + dmg := 1 + trunc(dxdy * 25); + exit(dmg) + end + else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then + begin + dmg := 1 + trunc(dy * 70); + exit(dmg) + end + end; exit(0) end; if (y > cWaterLine) or (x > leftX) or (x < rightX) then @@ -515,6 +526,7 @@ begin pX:= Point.x; pY:= Point.y; + fallDmg:= 0; if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then begin dX:= (0.005 * dmg + 0.01) / Density; @@ -525,8 +537,8 @@ dX:= 0; 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, Kind) * dmgMod) - else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod) + fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Targets.ar[i]) * dmgMod) + else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Targets.ar[i]) * dmgMod) end; if Kind = gtHedgehog then begin @@ -557,8 +569,7 @@ else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024) end end -// FIXME - need to make TraceFall calculate damage for barrels/mines correctly - else if (Kind <> gtHedgehog) and (FallDmg >= 0) and ((dmg+fallDmg) >= Score) then + else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then begin dead:= true; Targets.reset:= true; @@ -598,9 +609,10 @@ begin pX:= Point.x; pY:= Point.y-2; + fallDmg:= 0; if (Flags and afSetSkip <> 0) then skip:= true; if (Flags and afTrackFall <> 0) and (Score > 0) then - fallDmg:= trunc(TraceShoveFall(pX, pY, dX, dY, Kind) * dmgMod); + fallDmg:= trunc(TraceShoveFall(pX, pY, dX, dY, Targets.ar[i]) * 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 @@ -632,8 +644,7 @@ dec(rate, (power+fallDmg) * friendlyfactor div 100) end end -// FIXME - need to make TraceFall calculate damage for barrels/mines correctly - else if (Kind <> gtHedgehog) and (fallDmg >= 0) and ((power+fallDmg) >= Score) then + else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then begin dead:= true; Targets.reset:= true; @@ -696,8 +707,8 @@ 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, Kind) * dmgMod) - else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod); + fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Targets.ar[i]) * dmgMod) + else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Targets.ar[i]) * 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 @@ -725,8 +736,7 @@ inc(rate, dmg+fallDmg) else dec(rate, (dmg+fallDmg) * friendlyfactor div 100) end -// FIXME - need to make TraceFall calculate damage for barrels/mines correctly - else if (Kind <> gtHedgehog) and (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then + else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then begin dead:= true; Targets.reset:= true;