# HG changeset patch # User Wuzzy # Date 1491669372 -7200 # Node ID de9144250c37230b0b6153e1a1349e3465990cc2 # Parent 5c6e7fd5af2962db460e00423ab0d8a5a493202d 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 diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uGears.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; diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uGearsHandlersMess.pas --- 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? diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uGearsList.pas --- 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; diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uGearsRender.pas --- 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 diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uTypes.pas --- 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, diff -r 5c6e7fd5af29 -r de9144250c37 hedgewars/uVariables.pas --- 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