Add gear gtDuck: rubber duck
authorWuzzy <almikes@aol.com>
Sat, 08 Apr 2017 18:36:12 +0200
changeset 12197 de9144250c37
parent 12196 5c6e7fd5af29
child 12198 71c47122fbc0
Add gear gtDuck: rubber duck Properties: - Falls straight down - Swims on water and follows wind direction - Follows Sea world edge - Explodes on collision or after 9s - Timer resets when hitting water
hedgewars/uGears.pas
hedgewars/uGearsHandlersMess.pas
hedgewars/uGearsList.pas
hedgewars/uGearsRender.pas
hedgewars/uTypes.pas
hedgewars/uVariables.pas
--- a/hedgewars/uGears.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uGears.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -1224,7 +1224,8 @@
             @doStepIceGun,
             @doStepAddAmmo,
             @doStepGenericFaller,
-            @doStepKnife);
+            @doStepKnife,
+            @doStepDuck);
 begin
     doStepHandlers:= handlers;
 
--- a/hedgewars/uGearsHandlersMess.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uGearsHandlersMess.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -138,6 +138,7 @@
 procedure doStepGenericFaller(Gear: PGear);
 //procedure doStepCreeper(Gear: PGear);
 procedure doStepKnife(Gear: PGear);
+procedure doStepDuck(Gear: PGear);
 
 var
     upd: Longword;
@@ -6345,6 +6346,89 @@
         and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving;
         end
 end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepDuck(Gear: PGear);
+begin
+    // Mirror duck on bounce world edge, even turn around later
+    if WorldWrap(Gear) and (WorldEdge = weBounce) then
+        begin
+        Gear^.Tag:= Gear^.Tag * -1;
+        if Gear^.Pos = 2 then
+            Gear^.Pos:= 1
+        else if Gear^.Pos = 1 then
+            Gear^.Pos:= 2;
+        end;
+
+    AllInactive := false;
+
+    // Duck falls (Pos = 0)
+    if Gear^.Pos = 0 then
+        begin
+        doStepFallingGear(Gear);
+        // Karma is distance from water
+        if cWaterLine <= hwRound(Gear^.Y) + Gear^.Karma then
+            begin
+            Gear^.Pos:= 1;
+            Gear^.Timer:= Gear^.WDTimer;
+            Gear^.dY:= _0;
+            Gear^.State:= Gear^.State or gstNoGravity;
+            end;
+        end
+
+    // Manual speed handling when duck is on water (Pos <> 0)
+    else
+        begin
+        Gear^.X:= Gear^.X + Gear^.dX;
+        Gear^.Y:= Gear^.Y + Gear^.dY;
+        end;
+
+    // Mirrored duck
+    // Pos 1 or 2: Duck is on water (not Sea world edge)
+    if Gear^.Pos = 1 then
+        Gear^.dX:= cWindSpeed * 500
+    else if Gear^.Pos = 2 then
+        Gear^.dX:= -cWindSpeed * 500;
+    
+    // Rotate duck and change direction when reaching Sea world edge (Pos 3 or 4)
+    if WorldEdge = weSea then
+        begin
+        // Left edge
+        if (LeftX >= hwRound(Gear^.X) - Gear^.Karma) and (Gear^.Pos < 3) then
+            begin
+            Gear^.Pos:= 3;
+            if Gear^.Tag = 1 then
+                Gear^.Angle:= 90 
+            else
+                Gear^.Angle:= 270;
+            Gear^.dY:= Gear^.dX;
+            Gear^.dX:= _0;
+            end
+        // Right edge
+        else if (RightX <= hwRound(Gear^.X) + Gear^.Karma) and (Gear^.Pos < 3) then
+            begin
+            Gear^.Pos:= 4;
+        if Gear^.Tag = 1 then
+                Gear^.Angle:= 270
+            else
+                Gear^.Angle:= 90;
+            Gear^.dY:= -Gear^.dX;
+            Gear^.dX:= _0;
+            end;
+        end;
+
+    // Explode duck
+    CheckCollision(Gear);
+    if (Gear^.Timer = 0) or ((Gear^.State and gstCollision) <> 0) then
+        begin
+        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound);
+        DeleteGear(Gear);
+        exit;
+        end;
+
+    dec(Gear^.Timer);
+end;
+
 (*
  This didn't end up getting used, but, who knows, might be reasonable for javellin or something
 // Make the knife initial angle based on the hog attack angle, or is that too hard?
--- a/hedgewars/uGearsList.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uGearsList.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -105,6 +105,7 @@
 (*        gtAddAmmo *) , amNothing
 (*  gtGenericFaller *) , amNothing
 (*          gtKnife *) , amKnife
+(*           gtDuck *) , amNothing // TODO: Add ammo type
     );
 
 
@@ -263,6 +264,7 @@
                     else Gear^.Boom := 3;
     gtPoisonCloud: Gear^.Boom := 20;
           gtKnife: Gear^.Boom := 40000; // arbitrary scaling factor since impact-based
+           gtDuck: Gear^.Boom := 40;
     end;
 
 case Kind of
@@ -717,6 +719,19 @@
                 gear^.Health:= 1000;
                 gear^.Radius:= 8;
                 end;
+        gtDuck: begin
+                gear^.Pos:= 0;               // 0: falling/in air, 1-4: on water
+                gear^.Tag:= 1;               // 1: facing right, -1: facing left
+                if gear^.Timer = 0 then      
+                    gear^.Timer:= 9000;      // Explosion timer to avoid duck existing forever
+                gear^.WDTimer:= gear^.Timer; // For restoring the timer, timer is reset when hitting water
+                gear^.Radius:= 9;            // Collision radius (with landscape)
+                gear^.Karma:= 24;            // Distance from water when swimming
+                gear^.Elasticity:= _0_6;
+                gear^.Friction:= _0_03;
+                gear^.Density:= _0_5;
+                gear^.AdvBounce:= 1;
+                end;
 gtGenericFaller:begin
                 gear^.AdvBounce:= 1;
                 gear^.Radius:= 1;
--- a/hedgewars/uGearsRender.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uGearsRender.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -1325,7 +1325,7 @@
                     end;
         gtDynamite: begin
                     DrawSprite(sprDynamite, x - 16, y - 25, Gear^.Tag and 1, Gear^.Tag shr 1);
-                    if (random(3) = 0) and ((Gear^.State and gstDrowning) = 0) then
+                    if (random(3) = 0) then
                         begin
                         vg:= AddVisualGear(hwRound(Gear^.X)+12-(Gear^.Tag shr 1), hwRound(Gear^.Y)-16, vgtStraightShot);
                         if vg <> nil then
@@ -1528,6 +1528,7 @@
                                 end
                           end
                       end;
+            gtDuck: DrawSpriteRotatedF(sprDuck, x, y, 1, Gear^.Tag, Gear^.Angle);
             gtGenericFaller: DrawCircle(x, y, 3, 3, $FF, $00, $00, $FF);  // debug
          end;
       if Gear^.RenderTimer and (Gear^.Tex <> nil) then
--- a/hedgewars/uTypes.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uTypes.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -90,7 +90,7 @@
             sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis,
             sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun,
             sprFrozenHog, sprAmRubber, sprBoing, sprCustom1, sprCustom2, sprAirMine, sprHandAirMine,
-            sprFlakeL, sprSDFlakeL, sprCloudL, sprSDCloudL
+            sprFlakeL, sprSDFlakeL, sprCloudL, sprSDCloudL, sprDuck
             );
 
     // Gears that interact with other Gears and/or Land
@@ -108,7 +108,7 @@
             gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 51
             gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 56
             gtNapalmBomb, gtSnowball, gtFlake, {gtStructure,} gtLandGun, gtTardis, // 61
-            gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife); // 65
+            gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife, gtDuck); // 66
 
     // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
     TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire,
@@ -454,7 +454,8 @@
             sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb,
             sidSineGun, sidFlamethrower,sidSMine, sidHammer, sidResurrector,
             sidDrillStrike, sidSnowball, sidNothing, sidTardis,
-            {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber, sidAirMine);
+            {sidStructure,} sidLandGun, sidIceGun, sidKnife, sidRubber, sidAirMine,
+            sidDuck);
 
     TMsgStrId = (sidLoading, sidDraw, sidWinner, sidVolume, sidPaused,
             sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync,
--- a/hedgewars/uVariables.pas	Sat Apr 08 18:26:25 2017 +0200
+++ b/hedgewars/uVariables.pas	Sat Apr 08 18:36:12 2017 +0200
@@ -746,7 +746,9 @@
             (FileName:     'CloudsL'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
             Width: 256; Height:128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true),// sprCloudL
             (FileName:     'SDCloudsL'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
-            Width: 256; Height:128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true)// sprSDCloudL
+            Width: 256; Height:128; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpHigh; getDimensions: false; getImageDimensions: true),// sprSDCloudL
+            (FileName:     'Duck'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprDuck
             );
 
 const