hedgewars/GSHandlers.inc
changeset 7374 514138949c76
parent 7370 d50b874e7ee8
child 7389 15c3fb4882df
--- a/hedgewars/GSHandlers.inc	Tue Jul 10 11:08:35 2012 +0200
+++ b/hedgewars/GSHandlers.inc	Tue Jul 10 11:09:38 2012 +0200
@@ -2120,15 +2120,14 @@
    voices. Reinforcements voices is heard for active team, not team-to-be.  Either that or change crate spawn from end of turn to start, although that
    has its own complexities. *)
             // Abuse a couple of gear values to track origin
-            Gear^.Angle:= hwRound(Gear^.X);
-            Gear^.Power:= hwRound(Gear^.Y);
+            Gear^.Angle:= hwRound(Gear^.Y);
             Gear^.Tag:= random(2);
             inc(Gear^.Timer)
             end;
         if Gear^.Timer < 1833 then inc(Gear^.Timer);
         if Gear^.Timer = 1000 then
             begin
-            sparkles:= AddVisualGear(Gear^.Angle, Gear^.Power, vgtDust, 1);
+            sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1);
             if sparkles <> nil then
                 begin
                 sparkles^.dX:= 0;
@@ -2751,16 +2750,17 @@
 procedure doStepSwitcherWork(Gear: PGear);
 var 
     HHGear: PGear;
+    hedgehog: PHedgehog;
     State: Longword;
 begin
     AllInactive := false;
 
     if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then
         begin
-        HHGear := Gear^.Hedgehog^.Gear;
+        hedgehog := Gear^.Hedgehog;
         //Msg := Gear^.Message and (not gmSwitch);
         DeleteGear(Gear);
-        ApplyAmmoChanges(HHGear^.Hedgehog^);
+        ApplyAmmoChanges(hedgehog^);
 
         HHGear := CurrentHedgehog^.Gear;
         ApplyAmmoChanges(HHGear^.Hedgehog^);
@@ -3054,20 +3054,10 @@
 end;
 
 
-procedure PrevAngle(Gear: PGear; dA: LongInt);
-begin
-    Gear^.Angle := (LongInt(Gear^.Angle) + 4 - dA) mod 4
-end;
-
-procedure NextAngle(Gear: PGear; dA: LongInt);
-begin
-    Gear^.Angle := (LongInt(Gear^.Angle) + 4 + dA) mod 4
-end;
-
 procedure doStepCakeWork(Gear: PGear);
 
 const dirs: array[0..3] of TPoint =   ((X: 0; Y: -1), (X: 1; Y: 0),(X: 0; Y: 1),(X: -1; Y: 0));
-var 
+var
     xx, yy, xxn, yyn: LongInt;
     dA: LongInt;
     tdx, tdy: hwFloat;
@@ -3078,39 +3068,7 @@
     if Gear^.Tag < 7 then
         exit;
 
-    dA := hwSign(Gear^.dX);
-    xx := dirs[Gear^.Angle].x;
-    yy := dirs[Gear^.Angle].y;
-    xxn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x;
-    yyn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y;
-
-    if (xx = 0) then
-        if TestCollisionYwithGear(Gear, yy) <> 0 then
-            PrevAngle(Gear, dA)
-    else
-        begin
-        Gear^.Tag := 0;
-        Gear^.Y := Gear^.Y + int2hwFloat(yy);
-        if not TestCollisionXwithGear(Gear, xxn) then
-            begin
-            Gear^.X := Gear^.X + int2hwFloat(xxn);
-            NextAngle(Gear, dA)
-            end;
-        end;
-
-    if (yy = 0) then
-        if TestCollisionXwithGear(Gear, xx) then
-            PrevAngle(Gear, dA)
-    else
-        begin
-        Gear^.Tag := 0;
-        Gear^.X := Gear^.X + int2hwFloat(xx);
-        if TestCollisionYwithGear(Gear, yyn) = 0 then
-            begin
-            Gear^.Y := Gear^.Y + int2hwFloat(yyn);
-            NextAngle(Gear, dA)
-            end;
-        end;
+    cakeStep(Gear);
 
     if Gear^.Tag = 0 then
         begin
@@ -3193,23 +3151,22 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepSeductionWork(Gear: PGear);
 var i: LongInt;
-    hogs: TPGearArray;
+    hogs: PGearArrayS;
 begin
     AllInactive := false;
     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
-    if Length(hogs) > 0 then
-        begin
-        for i:= 0 to Length(hogs) - 1 do
-            begin
-            if hogs[i] <> CurrentHedgehog^.Gear then
+    if hogs.size > 0 then
+        begin
+        for i:= 0 to hogs.size - 1 do
+            with hogs.ar^[i]^ do
                 begin
-                //d:= Distance(Gear^.X - hogs[i]^.X, Gear^.Y - hogs[i]^.Y);
-                hogs[i]^.dX:= _50 * cGravity * (Gear^.X - hogs[i]^.X) / _25;
-                //if Gear^.X < hogs[i]^.X then hogs[i]^.dX.isNegative:= true;
-                hogs[i]^.dY:= -_450 * cGravity;
-                hogs[i]^.Active:= true;
-                end
-            end;
+                if hogs.ar^[i] <> CurrentHedgehog^.Gear then
+                    begin
+                    dX:= _50 * cGravity * (Gear^.X - X) / _25;
+                    dY:= -_450 * cGravity;
+                    Active:= true;
+                    end
+                end;
         end ;
         AfterAttack;
         DeleteGear(Gear);
@@ -3331,10 +3288,10 @@
         if (Gear^.Timer mod 30) = 0 then
             AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust);
         if (CheckGearDrowning(Gear)) then
-           begin
+            begin
             StopSoundChan(Gear^.SoundChannel);
             exit
-    end
+        end
     end;
 
     if GameTicks > Gear^.FlightTime then
@@ -3425,8 +3382,9 @@
         end
     else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
         begin
-        if Gear^.Timer > 0 then dec(Gear^.Timer);
-        if Gear^.Timer = 0 then
+        if Gear^.Timer > 0 then 
+            dec(Gear^.Timer)
+        else
             begin
             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
             DeleteGear(Gear);
@@ -3437,7 +3395,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepBallgunWork(Gear: PGear);
 var 
-    HHGear: PGear;
+    HHGear, ball: PGear;
     rx, ry: hwFloat;
     gX, gY: LongInt;
 begin
@@ -3452,7 +3410,8 @@
         rx := rndSign(getRandomf * _0_1);
         ry := rndSign(getRandomf * _0_1);
 
-        AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
+        ball:= AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
+        ball^.CollisionMask:= $FF7F;
 
         PlaySound(sndGun);
         end;
@@ -4415,7 +4374,8 @@
         Gear^.State := Gear^.State or gstCollision;
         Gear^.State := Gear^.State and (not gstMoving);
         
-        if not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
+        if (Land[y, x] and lfBouncy <> 0)
+        or not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
         or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
             begin
             loadNewPortalBall(Gear, true);
@@ -5059,7 +5019,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepResurrectorWork(Gear: PGear);
 var
-    graves: TPGearArray;
+    graves: PGearArrayS;
     resgear: PGear;
     hh: PHedgehog;
     i: LongInt;
@@ -5094,7 +5054,7 @@
 
     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
 
-    if Length(graves) = 0 then
+    if graves.size = 0 then
         begin
         StopSoundChan(Gear^.SoundChannel);
         Gear^.Timer := 250;
@@ -5104,12 +5064,12 @@
 
     if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
         begin
-        if Length(graves) <= Gear^.Tag then Gear^.Tag:= 0;
+        if graves.size <= Gear^.Tag then Gear^.Tag:= 0;
         dec(hh^.Gear^.Health);
         if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
             hh^.Gear^.Damage:= 1;
         RenderHealth(hh^);
-        inc(graves[Gear^.Tag]^.Health);
+        inc(graves.ar^[Gear^.Tag]^.Health);
         inc(Gear^.Tag)
 {-for i:= 0 to High(graves) do begin
             if hh^.Gear^.Health > 0 then begin
@@ -5121,14 +5081,14 @@
     else 
         begin
         // now really resurrect the hogs with the hp saved in the graves
-        for i:= 0 to Length(graves) - 1 do
-            if graves[i]^.Health > 0 then
+        for i:= 0 to graves.size - 1 do
+            if graves.ar^[i]^.Health > 0 then
                 begin
-                resgear := AddGear(hwRound(graves[i]^.X), hwRound(graves[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
-                resgear^.Hedgehog := graves[i]^.Hedgehog;
-                resgear^.Health := graves[i]^.Health;
-                PHedgehog(graves[i]^.Hedgehog)^.Gear := resgear;
-                DeleteGear(graves[i]);
+                resgear := AddGear(hwRound(graves.ar^[i]^.X), hwRound(graves.ar^[i]^.Y), gtHedgehog, gstWait, _0, _0, 0);
+                resgear^.Hedgehog := graves.ar^[i]^.Hedgehog;
+                resgear^.Health := graves.ar^[i]^.Health;
+                PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := resgear;
+                DeleteGear(graves.ar^[i]);
                 RenderHealth(resgear^.Hedgehog^);
                 RecountTeamHealth(resgear^.Hedgehog^.Team);
                 resgear^.Hedgehog^.Effects[heResurrected]:= 1;
@@ -5150,18 +5110,18 @@
 
 procedure doStepResurrector(Gear: PGear);
 var
-    graves: TPGearArray;
+    graves: PGearArrayS;
     i: LongInt;
 begin
     AllInactive := false;
     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
 
-    if Length(graves) > 0 then
-        begin
-        for i:= 0 to Length(graves) - 1 do
+    if graves.size > 0 then
+        begin
+        for i:= 0 to graves.size - 1 do
             begin
-            PHedgehog(graves[i]^.Hedgehog)^.Gear := nil;
-            graves[i]^.Health := 0;
+            PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
+            graves.ar^[i]^.Health := 0;
             end;
         Gear^.doStep := @doStepResurrectorWork;
         end 
@@ -5376,7 +5336,7 @@
         end;
     Gear^.Pos:= 4;
     // This condition might need tweaking
-    Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime
+    Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount*2)+cHedgehogTurnTime*2
     end;
 
 if (Gear^.Pos = 4) then
@@ -5480,7 +5440,7 @@
     HHGear, iter: PGear;
     ndX, ndY: hwFloat;
     i, t, gX, gY: LongInt;
-    hogs: TPGearArray;
+    hogs: PGearArrayS;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
     if (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
@@ -5544,9 +5504,9 @@
 // freeze nearby hogs
                 if GameTicks mod 10 = 0 then dec(Gear^.Health);
                 hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
-                if Length(hogs) > 0 then
-                    for i:= 0 to Length(hogs) - 1 do
-                        if hogs[i] <> HHGear then
+                if hogs.size > 0 then
+                    for i:= 0 to hogs.size - 1 do
+                        if hogs.ar^[i] <> HHGear then
                             begin
                             //if Gear^.Hedgehog^.Effects[heFrozen]:= 0;
                             end;