hedgewars/GSHandlers.inc
changeset 4578 f3cf226fad16
parent 4473 b6487d2c15ad
child 4582 85e92b6e5ad4
--- a/hedgewars/GSHandlers.inc	Mon Dec 20 02:00:22 2010 +0100
+++ b/hedgewars/GSHandlers.inc	Sun Dec 19 21:06:34 2010 -0500
@@ -28,32 +28,32 @@
 
     // Gear is still on the same Pixel it was before
     if steps < 1 then
-    begin
+        begin
         if onlyCheckIfChanged then
-        begin
+            begin
             Gear^.X := Gear^.X + dX;
             Gear^.Y := Gear^.Y + dY;
             EXIT;
-        end
+            end
         else
             steps := 1;
-    end;
+        end;
 
     if steps > 1 then
-    begin
+        begin
         sX:= dX / steps;
         sY:= dY / steps;
-    end
+        end
     else
-    begin
+        begin
         sX:= dX;
         sY:= dY;
-    end;
+        end;
 
     caller:= Gear^.doStep;
 
     for i:= 1 to steps do
-    begin
+        begin
         Gear^.X := Gear^.X + sX;
         Gear^.Y := Gear^.Y + sY;
         step(Gear);
@@ -61,7 +61,7 @@
         or ((Gear^.State and gstCollision) <> 0)
         or ((Gear^.State and gstMoving) = 0) then
             break;
-    end;
+        end;
 end;
 
 procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
@@ -71,27 +71,27 @@
 begin
     gi := GearsList;
     while gi <> nil do
-    begin
+        begin
         if (gi^.Kind = gtHedgehog) then
-        begin
+            begin
             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
             if (d > 1) and not gi^.Invulnerable and (GetRandom(2) = 0) then
-            begin
+                begin
                 if (CurrentHedgehog^.Gear = gi) then
                     PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack)
                 else
-                begin
+                    begin
                     if (gi^.State and gstMoving) = 0 then
                         gi^.State := gi^.State or gstLoser;
                     if d > r div 2 then
                         PlaySound(sndNooo, gi^.Hedgehog^.Team^.voicepack)
                     else
                         PlaySound(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
+                    end;
                 end;
             end;
+        gi := gi^.NextGear
         end;
-        gi := gi^.NextGear
-    end;
 end;
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepDrowningGear(Gear: PGear);
@@ -107,28 +107,29 @@
     isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
     // probably needs tweaking. might need to be in a case statement based upon gear type
     if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then
-    begin
+        begin
         skipSpeed := _0_25;
         skipAngle := _1_9;
         skipDecay := _0_87;
         // this could perhaps be a tiny bit higher.
         if  (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed) and
            (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
-        begin
+            begin
             Gear^.dY.isNegative := true;
             Gear^.dY := Gear^.dY * skipDecay;
             Gear^.dX := Gear^.dX * skipDecay;
             CheckGearDrowning := false;
             PlaySound(sndSkip)
-        end
+            end
         else
-        begin
+            begin
             if not isSubmersible then
-            begin
+                begin
                 CheckGearDrowning := true;
                 Gear^.State := gstDrowning;
                 Gear^.RenderTimer := false;
-                if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
+                if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and 
+                   (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
                     if Gear^.Kind = gtHedgehog then 
                         begin
                         if Gear^.Hedgehog^.Effects[heResurrectable] then
@@ -152,21 +153,21 @@
         if ((cReducedQuality and rqPlainSplash) = 0) and 
            (((not isSubmersible) and (hwRound(Gear^.Y) < cWaterLine + 64 + Gear^.Radius)) or
              (isSubmersible and (hwRound(Gear^.Y) < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0) and (CurAmmoGear^.dY < _0_01)))) then
-        begin
+            begin
             AddVisualGear(hwRound(Gear^.X), cWaterLine, vgtSplash);
 
             maxDrops := (Gear^.Radius div 2) + hwRound(Gear^.dX * Gear^.Radius * 2) + hwRound(Gear^.
                         dY * Gear^.Radius * 2);
             for i:= max(maxDrops div 3, min(32, Random(maxDrops))) downto 0 do
-            begin
+                begin
                 particle := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), cWaterLine, vgtDroplet);
                 if particle <> nil then
-                begin
+                    begin
                     particle^.dX := particle^.dX - (Gear^.dX.QWordValue / 42949672960);
                     particle^.dY := particle^.dY - (Gear^.dY.QWordValue / 21474836480)
+                    end
                 end
-            end
-        end;
+            end;
         if isSubmersible and (CurAmmoGear^.Pos = 0) then CurAmmoGear^.Pos := 1000
     end
     else
@@ -188,17 +189,16 @@
     particle: PVisualGear;
 begin
     if _0_4 < Gear^.dY then
-    begin
+        begin
         dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
         PlaySound(sndBump);
         if dmg < 1 then exit;
 
         for i:= min(12, (3 + dmg div 10)) downto 0 do
-        begin
-            particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,
-                        vgtDust);
+            begin
+            particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
             if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
-        end;
+            end;
 
         if (Gear^.Invulnerable) then exit;
 
@@ -267,53 +267,53 @@
     if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then Gear^.State := Gear^.State or gstCollision;
 
     if Gear^.dY.isNegative then
-    begin
+        begin
         isFalling := true;
         if TestCollisionYwithGear(Gear, -1) then
-        begin
+            begin
             collV := -1;
             Gear^.dX :=   Gear^.dX * Gear^.Friction;
             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
             Gear^.State := Gear^.State or gstCollision
-        end
+            end
         else if (Gear^.AdvBounce=1) and TestCollisionYwithGear(Gear, 1) then collV := 1;
-    end
+        end
     else if TestCollisionYwithGear(Gear, 1) then
         begin
-            collV := 1;
-            isFalling := false;
-            Gear^.dX :=   Gear^.dX * Gear^.Friction;
-            Gear^.dY := - Gear^.dY * Gear^.Elasticity;
-            Gear^.State := Gear^.State or gstCollision
+        collV := 1;
+        isFalling := false;
+        Gear^.dX :=   Gear^.dX * Gear^.Friction;
+        Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+        Gear^.State := Gear^.State or gstCollision
         end
     else
-    begin
+        begin
         isFalling := true;
         if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and TestCollisionYwithGear(Gear, -1) then
             collV := -1;
-    end;
+        end;
 
 
     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
-    begin
+        begin
         collH := hwSign(Gear^.dX);
         Gear^.dX := - Gear^.dX * Gear^.Elasticity;
         Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
         Gear^.State := Gear^.State or gstCollision
-    end
+        end
     else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then 
         collH := -hwSign(Gear^.dX); 
     //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
     if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) or ((tdX.QWordValue +
        tdY.QWordValue) > _0_2.QWordValue)) then
-    begin
+        begin
         Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
         Gear^.dY := tdX*Gear^.Elasticity;
         //*Gear^.Friction;
         Gear^.dY.isNegative := not tdY.isNegative;
         isFalling := false;
         Gear^.AdvBounce := 10;
-    end;
+        end;
 
     if Gear^.AdvBounce > 1 then dec(Gear^.AdvBounce);
 
@@ -519,16 +519,46 @@
     if (GameFlags and gfMoreWind) = 0 then Gear^.dX := Gear^.dX + cWindSpeed;
     doStepFallingGear(Gear);
     if (Gear^.State and gstCollision) <> 0 then
-    begin
+        begin
         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound);
         DeleteGear(Gear);
         exit
-    end;
+        end;
     if (GameTicks and $3F) = 0 then
         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
+procedure doStepSnowball(Gear: PGear);
+var kick, i: LongInt;
+    particle: PVisualGear;
+begin
+    AllInactive := false;
+    if (GameFlags and gfMoreWind) = 0 then Gear^.dX := Gear^.dX + cWindSpeed;
+    doStepFallingGear(Gear);
+    CalcRotationDirAngle(Gear);
+    if (Gear^.State and gstCollision) <> 0 then
+        begin
+        kick:= hwRound((hwAbs(Gear^.dX)+hwAbs(Gear^.dY)) * _20);
+        Gear^.dY.isNegative:= not Gear^.dY.isNegative;
+        Gear^.dX.isNegative:= not Gear^.dX.isNegative;
+        AmmoShove(Gear, 1, kick);
+        for i:= 15 + kick div 10 downto 0 do
+            begin
+            particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust);
+            if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+            end;
+        DeleteGear(Gear);
+        exit
+        end;
+    if ((GameTicks and $1F) = 0) and (Random(3) = 0) then
+        begin
+        AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust);
+        if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+        end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
 procedure doStepGrave(Gear: PGear);
 begin
     AllInactive := false;
@@ -895,7 +925,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepPickHammerWork(Gear: PGear);
 var 
-    i, ei: LongInt;
+    i, ei, x, y: LongInt;
     HHGear: PGear;
 begin
     AllInactive := false;
@@ -903,53 +933,58 @@
     dec(Gear^.Timer);
     if (Gear^.Timer = 0)or((Gear^.Message and gmDestroy) <> 0)or((HHGear^.State and gstHHDriven) =
        0) then
-    begin
+        begin
         StopSound(Gear^.SoundChannel);
         DeleteGear(Gear);
         AfterAttack;
         doStepHedgehogMoving(HHGear);  // for gfInfAttack
         exit
-    end;
-
+        end;
+
+    x:= hwRound(Gear^.X);
+    y:= hwRound(Gear^.Y);
     if (Gear^.Timer mod 33) = 0 then
-    begin
+        begin
         HHGear^.State := HHGear^.State or gstNoDamage;
-        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw);
+        doMakeExplosion(x, y + 7, 6, EXPLDontDraw);
         HHGear^.State := HHGear^.State and not gstNoDamage
-    end;
+        end;
 
     if (Gear^.Timer mod 47) = 0 then
-    begin
-        for i:= 0 to 1 do
-            AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-        i := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
-        ei := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
+        begin
+        // ok. this was an attempt to turn off dust if not actually drilling land.  I have no idea why it isn't working as expected
+        //if ((y + 12 and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y + 12, x] > 255) then 
+            for i:= 0 to 1 do
+                AddVisualGear(x - 5 + Random(10), y + 12, vgtDust);
+
+        i := x - Gear^.Radius - LongInt(GetRandom(2));
+        ei := x + Gear^.Radius + LongInt(GetRandom(2));
         while i <= ei do
-        begin
-            DrawExplosion(i, hwRound(Gear^.Y) + 3, 3);
+            begin
+            DrawExplosion(i, y + 3, 3);
             inc(i, 1)
-        end;
+            end;
 
         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
            , lfIndestructible) then
-        begin
+            begin
             Gear^.X := Gear^.X + Gear^.dX;
             Gear^.Y := Gear^.Y + _1_9;
-        end;
+            end;
         SetAllHHToActive;
-    end;
+        end;
     if TestCollisionYwithGear(Gear, 1) then
-    begin
+        begin
         Gear^.dY := _0;
         SetLittle(HHGear^.dX);
         HHGear^.dY := _0;
-    end
+        end
     else
-    begin
+        begin
         Gear^.dY := Gear^.dY + cGravity;
         Gear^.Y := Gear^.Y + Gear^.dY;
         if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1
-    end;
+        end;
 
     Gear^.X := Gear^.X + HHGear^.dX;
     HHGear^.X := Gear^.X;
@@ -1858,10 +1893,10 @@
     DeleteCI(HHGear);
 
     for i:= 0 to 3 do
-    begin
+        begin
         AmmoShove(Gear, 30, 25);
         Gear^.X := Gear^.X + Gear^.dX * 5
-    end;
+        end;
 
     HHGear^.State := (HHGear^.State and (not gstNoDamage)) or gstMoving;
 
@@ -2688,7 +2723,7 @@
 
     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) then
         if (Land[y, x] <> 0) then
-        begin
+            begin
             Gear^.dX.isNegative := not Gear^.dX.isNegative;
             Gear^.dY.isNegative := not Gear^.dY.isNegative;
             Gear^.dX := Gear^.dX * _1_5;
@@ -2696,13 +2731,13 @@
             AmmoShove(Gear, 0, 40);
             AfterAttack;
             DeleteGear(Gear)
-        end
+            end
+        else
     else
-    else
-    begin
+        begin
         AfterAttack;
         DeleteGear(Gear)
-    end
+        end
 end;
 
 procedure doStepSeductionWear(Gear: PGear);