# HG changeset patch # User Wuzzy # Date 1463090889 -7200 # Node ID 668ee6e388bd109794eefd3c274f2e977268946d # Parent fb2dea5c98f16839a8dc520d70f928961fe20ff1 Make duck rise to surface when spawning underwater diff -r fb2dea5c98f1 -r 668ee6e388bd hedgewars/uGearsHandlersMess.pas --- 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 diff -r fb2dea5c98f1 -r 668ee6e388bd hedgewars/uGearsList.pas --- 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;