# HG changeset patch # User nemo # Date 1331691943 14400 # Node ID 8d9160b85bdb52563737d03ed3605b74f22fa582 # Parent 33009ac4de8056fc10302afab3070f9e47d7d695 Add fall damage diff -r 33009ac4de80 -r 8d9160b85bdb hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Tue Mar 13 21:51:50 2012 -0400 +++ b/hedgewars/uAIAmmoTests.pas Tue Mar 13 22:25:43 2012 -0400 @@ -579,10 +579,11 @@ end; function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; -var Vx, Vy, x, y, t: real; +var Vx, Vy, x, y, t, dmgMod: real; d: Longword; - valueResult: LongInt; + fallDmg, valueResult: LongInt; begin +dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; Level:= Level; // avoid compiler hint ap.ExplR:= 0; ap.Time:= 0; @@ -612,9 +613,10 @@ if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 3 then begin - if TraceShoveDrown(Me, Targ.X, Targ.Y, vX * 0.005 * 20, vY * 0.005 * 20) then + fallDmg:= TraceShoveFall(Me, Targ.X, Targ.Y, vX * 0.005 * 20, vY * 0.005 * 20); + if fallDmg < 0 then valueResult:= 204800 - else valueResult:= Max(0, (4 - d div 50) * 7 * 1024) + else valueResult:= Max(0, (4 - d div 50) * trunc((7+fallDmg)*dmgMod) * 1024) end else valueResult:= BadTurn; diff -r 33009ac4de80 -r 8d9160b85bdb hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Tue Mar 13 21:51:50 2012 -0400 +++ b/hedgewars/uAIMisc.pas Tue Mar 13 22:25:43 2012 -0400 @@ -53,7 +53,7 @@ function RatePlace(Gear: PGear): LongInt; function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; function TestColl(x, y, r: LongInt): boolean; inline; -function TraceShoveDrown(Me: PGear; x, y, dX, dY: Real): boolean; +function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; @@ -260,9 +260,10 @@ TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) end; -function TraceDrown(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): boolean; +function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt; var skipLandCheck: boolean; rCorner: real; + dmg: LongInt; begin skipLandCheck:= true; if x - eX < 0 then dX:= -dX; @@ -275,13 +276,21 @@ 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)); - // consider adding dX/dY calc here for fall damage - if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false); - if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); + if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then + begin + if 0.4 < dY then + begin + dmg := 1 + trunc((abs(dY) - 0.4) * 70); + if dmg >= 1 then exit(dmg) + end; + exit(0) + end; + if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine end; end; -function TraceShoveDrown(Me: PGear; x, y, dX, dY: Real): boolean; +function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; +var dmg: LongInt; begin while true do begin @@ -289,16 +298,25 @@ y:= y + dY; dY:= dY + cGravityf; // consider adding dX/dY calc here for fall damage - if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then exit(false); - if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true); + if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then + begin + if 0.4 < dY then + begin + dmg := 1 + trunc((abs(dY) - 0.4) * 70); + if dmg >= 1 then exit(dmg) + end; + exit(0) + end; + if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine end; end; // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt; -var i, dmg, dmgBase, rate, erasure: LongInt; +var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt; dX, dY, dmgMod: real; begin +fallDmg:= 0; dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; rate:= 0; // add our virtual position @@ -325,31 +343,33 @@ begin dX:= 0.005 * dmg + 0.01; dY:= dX; + fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); end; - if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then + if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI if Score > 0 then inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings else dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs - else if dmg >= abs(Score) then + else if (dmg+fallDmg) >= abs(Score) then if Score > 0 then inc(rate, KillScore) else dec(rate, KillScore * friendlyfactor div 100) else if Score > 0 then - inc(rate, dmg) + inc(rate, dmg+fallDmg) else - dec(rate, dmg * friendlyfactor div 100) + dec(rate, (dmg+fallDmg) * friendlyfactor div 100) end; end; RateExplosion:= rate * 1024; end; function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; -var i, dmg, rate: LongInt; +var i, fallDmg, dmg, rate: LongInt; dX, dY, dmgMod: real; begin +fallDmg:= 0; dX:= gdX * 0.005 * kick; dY:= gdY * 0.005 * kick; dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; @@ -365,28 +385,30 @@ end; if dmg > 0 then begin - if (Flags and 1 <> 0) and TraceShoveDrown(Me, Point.x, Point.y-2, dX, dY) then + if (Flags and 1 <> 0) then + fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y-2, dX, dY) * dmgMod); + if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI if Score > 0 then inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings else dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs - else if power >= abs(Score) then + else if power+fallDmg >= abs(Score) then if Score > 0 then inc(rate, KillScore) else dec(rate, KillScore * friendlyfactor div 100) else if Score > 0 then - inc(rate, power) + inc(rate, power+fallDmg) else - dec(rate, power * friendlyfactor div 100) + dec(rate, (power+fallDmg) * friendlyfactor div 100) end; end; RateShove:= rate * 1024 end; function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; -var i, dmg, baseDmg, rate, erasure: LongInt; +var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt; dX, dY, dmgMod: real; begin dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent; @@ -419,17 +441,22 @@ dY:= gdY * dmg; if dX < 0 then dX:= dX - 0.01 else dX:= dX + 0.01; - if TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then + fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); + if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI if Score > 0 then inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings else dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs - else if dmg >= abs(Score) then - dmg := KillScore; - if Score > 0 then - inc(rate, dmg) + else if (dmg+fallDmg) >= abs(Score) then + if Score > 0 then + inc(rate, KillScore) + else + dec(rate, KillScore * friendlyfactor div 100) else - dec(rate, dmg * friendlyfactor div 100); + if Score > 0 then + inc(rate, dmg+fallDmg) + else + dec(rate, (dmg+fallDmg) * friendlyfactor div 100) end; end; RateShotgun:= rate * 1024;