diff -r 2af2309207b0 -r 56bd029245fc hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Sat Jul 05 18:51:45 2014 +0200 +++ b/hedgewars/uGearsHandlersMess.pas Sat Jul 05 20:15:56 2014 +0200 @@ -259,9 +259,33 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepDrowningGear(Gear: PGear); begin - AllInactive := false; + if Gear^.Timer = 0 then + begin + if (FollowGear = Gear) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then + FollowGear:= CurrentHedgehog^.Gear; + end + else if Gear^.Timer > 0 then + begin + AllInactive := false; + dec(Gear^.Timer); + end; + Gear^.Y := Gear^.Y + cDrownSpeed; - Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; + + if cWaterLine > hwRound(Gear^.Y) + Gear^.Radius then + begin + if leftX > hwRound(Gear^.X) - Gear^.Radius then + Gear^.X := Gear^.X - cDrownSpeed + else + Gear^.X := Gear^.X + cDrownSpeed; + end + else + Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; + + if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then + else + Gear^.Y := Gear^.Y + Gear^.dY * cDrownSpeed; + // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) if ((not SuddenDeathDmg and (WaterOpacity < $FF)) or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then @@ -301,7 +325,7 @@ if Gear^.dY.Round > 1 then Gear^.dY.QWordValue:= 8589934592; - if (Gear^.State and gstSubmersible <> 0) and (gY > cWaterLine) then + if (Gear^.State and gstSubmersible <> 0) and CheckCoordInWater(gX, gY) then begin Gear^.dX:= Gear^.dX * _0_999; Gear^.dY:= Gear^.dY * _0_999 @@ -787,7 +811,7 @@ end; *) // move back to cloud layer - if yy > cWaterLine then + if CheckCoordInWater(xx, yy) then move:= true else if (xx > snowRight) or (xx < snowLeft) then move:=true @@ -956,16 +980,19 @@ gX := hwRound(Gear^.X); gY := hwRound(Gear^.Y); uw := (Gear^.Tag <> 0); // was bee underwater last tick? - nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now? + nuw := CheckCoordInWater(gx, gy + Gear^.Radius); // is bee underwater now? // if water entered or left if nuw <> uw then begin - AddVisualGear(gX, cWaterLine, vgtSplash); - AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); - AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); - AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); - AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); + if (gX > leftX) and (gY < rightX) then + begin + AddVisualGear(gX, cWaterLine, vgtSplash); + AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); + AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); + AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); + AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); + end; StopSoundChan(Gear^.SoundChannel); if nuw then begin @@ -1178,7 +1205,7 @@ if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then // only extend if not under water - if hwRound(Bullet^.Y) < cWaterLine then + if not CheckCoordInWater(hwRound(Bullet^.X), hwRound(Bullet^.Y)) then begin VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X); VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y); @@ -2153,11 +2180,13 @@ Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640; Gear^.Y := Gear^.Y + Gear^.dY; - if (hwRound(Gear^.Y) > cWaterLine) then + gX := hwRound(Gear^.X); + gY := hwRound(Gear^.Y); + + if CheckCoordInWater(gX, gY) then begin - gX := hwRound(Gear^.X); for i:= 0 to 3 do - AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam); + AddVisualGear(gX - 8 + Random(16), gY - 8 + Random(16), vgtSteam); PlaySound(sndVaporize); DeleteGear(Gear); exit @@ -2170,8 +2199,7 @@ Gear^.Y:= Gear^.Y+_6; if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then begin - gX := hwRound(Gear^.X); - gY := hwRound(Gear^.Y)-6; + gY := gy-6; DrawExplosion(gX, gY, 4); PlaySound(sndVaporize); AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSteam); @@ -2201,8 +2229,6 @@ end else begin - gX := hwRound(Gear^.X); - gY := hwRound(Gear^.Y); // Standard fire if not sticky then begin @@ -2252,8 +2278,6 @@ end; if Gear^.Health = 0 then begin - gX := hwRound(Gear^.X); - gY := hwRound(Gear^.Y); if not sticky then begin if ((GameTicks and $3) = 0) and (Random(1) = 0) then @@ -2799,6 +2823,14 @@ HHGear^.X := Gear^.X; HHGear^.Y := Gear^.Y; + // check for drowning + if CheckGearDrowning(HHGear) then + begin + AfterAttack; + DeleteGear(Gear); + exit; + end; + inc(Gear^.Damage, 2); // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) @@ -3167,6 +3199,18 @@ else exit; + if playWidth > cMinPlayWidth then + begin + inc(leftX); + dec(rightX); + dec(playWidth, 2); + for i:= 0 to LAND_HEIGHT - 1 do + begin + Land[i, leftX] := 0; + Land[i, rightX] := 0; + end; + end; + if cWaterLine > 0 then begin dec(cWaterLine); @@ -3508,7 +3552,7 @@ isUnderwater: Boolean; bubble: PVisualGear; begin - isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius; + isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius); if Gear^.Pos > 0 then dec(Gear^.Pos); AllInactive := false; @@ -3614,6 +3658,7 @@ if // (Gear^.Health = 0) (HHGear^.Damage <> 0) //or CheckGearDrowning(HHGear) + // drown if too deep under water or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y)) or (TurnTimeLeft = 0) // allow brief ground touches - to be fair on this, might need another counter @@ -3929,7 +3974,7 @@ if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask) or (Gear^.Timer < 1) or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) - or (hwRound(Gear^.Y) > cWaterLine) then + or CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then begin deleteGear(Gear); EXIT; @@ -4318,7 +4363,7 @@ loadNewPortalBall(Gear, true); end - else if (y > cWaterLine) + else if CheckCoordInWater(x, y) or (y < -max(LAND_WIDTH,4096)) or (x > 2*max(LAND_WIDTH,4096)) or (x < -max(LAND_WIDTH,4096)) then @@ -4558,7 +4603,7 @@ end else begin - if (rY <= cWaterLine) or (y <= cWaterLine) then + if CheckCoordInWater(rX, rY) or CheckCoordInWater(x, y) then begin if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then @@ -4945,7 +4990,7 @@ begin //Gear^.dY := Gear^.dY + cGravity; //Gear^.Y := Gear^.Y + Gear^.dY; - if hwRound(Gear^.Y) > cWaterLine then + if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then Gear^.Timer := 1 end;