--- a/hedgewars/uGearsHandlersMess.pas Thu May 12 19:45:26 2016 +0200
+++ b/hedgewars/uGearsHandlersMess.pas Fri May 13 00:08:09 2016 +0200
@@ -6361,73 +6361,133 @@
if Gear^.Pos = 2 then
Gear^.Pos:= 1
else if Gear^.Pos = 1 then
- Gear^.Pos:= 2;
+ Gear^.Pos:= 2
+ else if Gear^.Pos = 5 then
+ Gear^.Pos:= 6
+ else if Gear^.Pos = 5 then
+ Gear^.Pos:= 5;
end;
AllInactive := false;
// Duck falls (Pos = 0)
if Gear^.Pos = 0 then
- begin
doStepFallingGear(Gear);
- (* Check if duck is near water surface
+
+ (* Check if duck is near water surface
(Karma is distance from water) *)
- if cWaterLine <= hwRound(Gear^.Y) + Gear^.Karma then
+ if (Gear^.Pos in [0, 5, 6]) and (cWaterLine <= hwRound(Gear^.Y) + Gear^.Karma) then
+ begin
+ if cWaterLine = hwRound(Gear^.Y) + Gear^.Karma then
begin
PlaySound(sndDroplet2);
if Gear^.dY > _0_4 then
PlaySound(sndDuckWater);
Gear^.Pos:= 1;
Gear^.dY:= _0;
- end;
- end
-
- // Manual speed handling when duck is on water (Pos <> 0)
- else
+ end
+ else if Gear^.Pos = 0 then
+ Gear^.Pos:= 5;
+ end;
+
+ // Manual speed handling when duck is on water
+ if Gear^.Pos <> 0 then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.Y:= Gear^.Y + Gear^.dY;
end;
// Handle speed
+ // 1-4: On water: Let's swim!
if Gear^.Pos = 1 then
+ // On water (normal)
Gear^.dX:= cWindSpeed * Gear^.Damage
else if Gear^.Pos = 2 then
- // Mirrored duck (after bounce edge bounce)
+ // On water, mirrored (after bounce edge bounce)
Gear^.dX:= -cWindSpeed * Gear^.Damage
else if Gear^.Pos = 3 then
+ // On left Sea edge
Gear^.dY:= cWindSpeed * Gear^.Damage
else if Gear^.Pos = 4 then
- Gear^.dY:= -cWindSpeed * Gear^.Damage;
+ // On right Sea edge
+ Gear^.dY:= -cWindSpeed * Gear^.Damage
+ // 5-8: Underwater: Slowly rise to the surface and slightly follow wind
+ else if Gear^.Pos = 5 then
+ // Underwater (normal)
+ begin
+ Gear^.dX:= (cWindSpeed / 4) * Gear^.Damage;
+ Gear^.dY:= -_0_07;
+ end
+ else if Gear^.Pos = 6 then
+ // Underwater, mirrored duck (after bounce edge bounce)
+ begin
+ Gear^.dX:= -(cWindSpeed / 4) * Gear^.Damage;
+ Gear^.dY:= -_0_07;
+ end
+ else if Gear^.Pos = 7 then
+ // Inside left Sea edge
+ begin
+ Gear^.dX:= _0_07;
+ Gear^.dY:= (cWindSpeed / 4) * Gear^.Damage;
+ end
+ else if Gear^.Pos = 8 then
+ // Inside right Sea edge
+ begin
+ Gear^.dX:= -_0_07;
+ Gear^.dY:= -(cWindSpeed / 4) * Gear^.Damage;
+ end;
+
// Rotate duck and change direction when reaching Sea world edge (Pos 3 or 4)
- if WorldEdge = weSea then
- begin
+ if (WorldEdge = weSea) and (not (Gear^.Pos in [3,4])) then
// Left edge
- if (LeftX >= hwRound(Gear^.X) - Gear^.Karma) and (Gear^.Pos < 3) then
- begin
- PlaySound(sndDuckWater);
- Gear^.Pos:= 3;
- if Gear^.Tag = 1 then
- Gear^.Angle:= 90
- else
- Gear^.Angle:= 270;
- Gear^.dY:= cWindSpeed * Gear^.Damage;
- Gear^.dX:= _0;
+ if (LeftX >= hwRound(Gear^.X) - Gear^.Karma) then
+ begin
+ // Turn duck when reaching edge the first time
+ if not (Gear^.Pos in [3,7]) then
+ begin
+ if Gear^.Tag = 1 then
+ Gear^.Angle:= 90
+ else
+ Gear^.Angle:= 270;
+ end;
+
+ // Reaching the edge surface
+ if (LeftX = hwRound(Gear^.X) - Gear^.Karma) and (Gear^.Pos <> 3) then
+ // We are coming from the horizontal side
+ begin
+ PlaySound(sndDuckWater);
+ Gear^.dX:= _0;
+ Gear^.Pos:= 3;
+ end
+ else
+ // We are coming from inside the Sea, go into “surfacing” mode
+ Gear^.Pos:= 7;
+
end
- // Right edge
- else if (RightX <= hwRound(Gear^.X) + Gear^.Karma) and (Gear^.Pos < 3) then
- begin
- PlaySound(sndDuckWater);
- Gear^.Pos:= 4;
- if Gear^.Tag = 1 then
- Gear^.Angle:= 270
- else
- Gear^.Angle:= 90;
- Gear^.dY:= -cWindspeed * Gear^.Damage;
- Gear^.dX:= _0;
+
+ // Right edge (similar to left edge)
+ else if (RightX <= hwRound(Gear^.X) + Gear^.Karma) then
+ begin
+ if not (Gear^.Pos in [4,8]) then
+ begin
+ if Gear^.Tag = 1 then
+ Gear^.Angle:= 270
+ else
+ Gear^.Angle:= 90;
+ end;
+
+ if (RightX = hwRound(Gear^.X) + Gear^.Karma) and (Gear^.Pos <> 4) then
+ begin
+ PlaySound(sndDuckWater);
+ Gear^.dX:= _0;
+ Gear^.Pos:= 4;
+ end
+ else
+ Gear^.Pos:= 8;
+
end;
- end;
+
if Gear^.Pos <> 0 then
// Manual collision check required because we don't use onStepFallingGear in this case
--- a/hedgewars/uGearsList.pas Thu May 12 19:45:26 2016 +0200
+++ b/hedgewars/uGearsList.pas Fri May 13 00:08:09 2016 +0200
@@ -720,15 +720,18 @@
gear^.Radius:= 8;
end;
gtDuck: begin
- gear^.Pos:= 0; // 0: in air, 1-4: on water,
+ gear^.Pos:= 0; // 0: in air, 1-4: on water, 5-8: underwater
// 1: bottom, 2: bottom (mirrored),
// 3: left Sea edge, 4: right Sea edge
+ // 6: bottom, 7: bottom (mirrored)
+ // 7: left Sea edge, 8: right Sea edge
gear^.Tag:= 1; // 1: facing right, -1: facing left
if gear^.Timer = 0 then
gear^.Timer:= 15000; // Explosion timer to avoid duck existing forever
gear^.Radius:= 9; // Collision radius (with landscape)
gear^.Karma:= 24; // Distance from water when swimming
gear^.Damage:= 500; // Speed factor when swimming on water (multiplied with wind speed)
+ gear^.State:= gear^.State or gstSubmersible;
gear^.Elasticity:= _0_6;
gear^.Friction:= _0_8;
gear^.Density:= _0_5;