hedgewars/uGearsHandlersMess.pas
branchsdl2transition
changeset 9798 f2b18754742f
parent 9769 5814e0c47c99
child 9809 1e32628eb167
--- a/hedgewars/uGearsHandlersMess.pas	Sat Dec 14 21:16:20 2013 +0400
+++ b/hedgewars/uGearsHandlersMess.pas	Tue Dec 17 00:02:52 2013 +0400
@@ -208,7 +208,7 @@
         if (gi^.Kind = gtHedgehog) then
             begin
             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
-            if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
+            if (d > 1) and ((gi^.Hedgehog^.Effects[heInvulnerable] = 0)) and (GetRandom(2) = 0) then
                 begin
                 if (CurrentHedgehog^.Gear = gi) then
                     PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
@@ -281,15 +281,18 @@
     isFalling: boolean;
     //tmp: QWord;
     tX, tdX, tdY: hwFloat;
-    collV, collH: LongInt;
-    land: word;
+    collV, collH, gX, gY: LongInt;
+    land, xland: word;
+    boing: PVisualGear;
 begin
     tX:= Gear^.X;
+    gX:= hwRound(Gear^.X);
+    gY:= hwRound(Gear^.Y);
     if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.AdvBounce <> 0) and
-      (TestCollisionXwithGear(Gear, 1) or TestCollisionXwithGear(Gear, -1))  then
+      ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0))  then
         begin
         Gear^.X:= tX;
-        Gear^.dX.isNegative:= (hwRound(tX) > leftX+Gear^.Radius*2)
+        Gear^.dX.isNegative:= (gX > leftX+Gear^.Radius*2)
         end;
 
     // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
@@ -298,7 +301,7 @@
     if Gear^.dY.Round > 2 then
         Gear^.dY.QWordValue:= 8589934592;
 
-    if (Gear^.State and gstSubmersible <> 0) and (hwRound(Gear^.Y) > cWaterLine) then
+    if (Gear^.State and gstSubmersible <> 0) and (gY > cWaterLine) then
         begin
         Gear^.dX:= Gear^.dX * _0_999;
         Gear^.dY:= Gear^.dY * _0_999
@@ -311,8 +314,8 @@
     tdY := Gear^.dY;
 
 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
-    if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
-    or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
+    if (gX < min(LAND_WIDTH div -2, -2048))
+    or (gX > max(LAND_WIDTH * 3 div 2, 6144)) then
         Gear^.State := Gear^.State or gstCollision;
 
     if Gear^.dY.isNegative then
@@ -323,15 +326,20 @@
             begin
             collV := -1;
             if land and lfIce <> 0 then
-                Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
-            else
-                Gear^.dX := Gear^.dX * Gear^.Friction;
-
-            Gear^.dY := - Gear^.dY * Gear^.Elasticity;
-            Gear^.State := Gear^.State or gstCollision
+                 Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
+            else Gear^.dX := Gear^.dX * Gear^.Friction;
+            if (Gear^.AdvBounce = 0) or (land and lfBouncy = 0) then
+                 begin
+                 Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+                 Gear^.State := Gear^.State or gstCollision
+                 end
+            else Gear^.dY := - Gear^.dY * cElastic
             end
-        else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
-            collV := 1;
+        else if Gear^.AdvBounce = 1 then
+            begin
+            land:= TestCollisionYwithGear(Gear, 1);
+            if land <> 0 then collV := 1
+            end
         end
     else
         begin // Gear^.dY.isNegative is false
@@ -345,34 +353,63 @@
             else
                 Gear^.dX := Gear^.dX * Gear^.Friction;
 
-            Gear^.dY := - Gear^.dY * Gear^.Elasticity;
-            Gear^.State := Gear^.State or gstCollision
+            if (Gear^.AdvBounce = 0) or (land and lfBouncy = 0) then
+                 begin
+                 Gear^.dY := - Gear^.dY * Gear^.Elasticity;
+                 Gear^.State := Gear^.State or gstCollision
+                 end
+            else Gear^.dY := - Gear^.dY * cElastic
             end
         else
             begin
             isFalling := true;
-            if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, -1) <> 0) then
-                collV := -1
+            if Gear^.AdvBounce = 1 then
+                begin
+                land:= TestCollisionYwithGear(Gear, -1);
+                if land <> 0 then collV := -1
+                end
             end
         end;
 
 
-    if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+    xland:= TestCollisionXwithGear(Gear, hwSign(Gear^.dX));
+    if xland <> 0 then
         begin
         collH := hwSign(Gear^.dX);
-        Gear^.dX := - Gear^.dX * Gear^.Elasticity;
-        Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
-        Gear^.State := Gear^.State or gstCollision
+        if (Gear^.AdvBounce = 0) or (xland and lfBouncy = 0) then
+            begin
+            Gear^.dX := - Gear^.dX * Gear^.Elasticity;
+            Gear^.dY :=   Gear^.dY * Gear^.Elasticity;
+            Gear^.State := Gear^.State or gstCollision
+            end
+        else
+            begin
+            Gear^.dX := - Gear^.dX * cElastic;
+            Gear^.dY :=   Gear^.dY * cElastic
+            end
         end
-    else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
-        collH := -hwSign(Gear^.dX);
+    else if Gear^.AdvBounce = 1 then
+        begin
+        xland:= TestCollisionXwithGear(Gear, -hwSign(Gear^.dX));
+        if xland <> 0 then collH := -hwSign(Gear^.dX)
+        end;
     //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
-        Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
-        Gear^.dY := tdX*Gear^.Elasticity;
-        //*Gear^.Friction;
+    if (collV <> 0) and (collH <> 0) and 
+       (((Gear^.AdvBounce=1) and ((collV=-1) or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)))) then
+ //or ((xland or land) and lfBouncy <> 0)) then
+        begin
+        if (xland or land) and lfBouncy = 0 then
+            begin
+            Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction;
+            Gear^.dY := tdX*Gear^.Elasticity;
+            Gear^.State := Gear^.State or gstCollision
+            end
+        else
+            begin
+            Gear^.dX := tdY*cElastic*Gear^.Friction;
+            Gear^.dY := tdX*cElastic
+            end;
+
         Gear^.dY.isNegative := not tdY.isNegative;
         isFalling := false;
         Gear^.AdvBounce := 10;
@@ -397,7 +434,28 @@
     else
         Gear^.State := Gear^.State or gstMoving;
 
-    if (Gear^.nImpactSounds > 0) and
+    if ((xland or land) and lfBouncy <> 0) and (Gear^.dX.QWordValue < _0_15.QWordValue) and (Gear^.dY.QWordValue < _0_15.QWordValue) then
+        Gear^.State := Gear^.State or gstCollision;
+    
+    if ((xland or land) and lfBouncy <> 0) and (Gear^.Radius >= 3) and
+       ((Gear^.dX.QWordValue > _0_15.QWordValue) or (Gear^.dY.QWordValue > _0_15.QWordValue)) then
+        begin
+        boing:= AddVisualGear(gX, gY, vgtStraightShot, 0, false, 1);
+        if boing <> nil then
+            with boing^ do
+                begin
+                Angle:= random(360);
+                dx:= 0;
+                dy:= 0;
+                FrameTicks:= 200;
+                tX:= _0;
+                tX.QWordValue:= Gear^.dY.QWordValue + Gear^.dX.QWordValue;
+                Scale:= hwFloat2Float(Gear^.Density * tX) / 1.5;
+                State:= ord(sprBoing)
+                end;
+        PlaySound(sndMelonImpact, true)
+        end
+    else if (Gear^.nImpactSounds > 0) and
         (Gear^.State and gstCollision <> 0) and
         (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
         (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
@@ -871,11 +929,11 @@
     AllInactive := false;
 
     if Gear^.dY.isNegative then
-        if TestCollisionY(Gear, -1) then
+        if TestCollisionY(Gear, -1) <> 0 then
             Gear^.dY := _0;
 
     if not Gear^.dY.isNegative then
-        if TestCollisionY(Gear, 1) then
+        if TestCollisionY(Gear, 1) <> 0 then
         begin
             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
             if Gear^.dY > - _1div1024 then
@@ -931,13 +989,24 @@
 
 
     if Gear^.Timer = 0 then
-        Gear^.RenderTimer:= false
+        begin
+        // no "fuel"? just fall
+        doStepFallingGear(Gear);
+        // if drowning, stop bee sound
+        if (Gear^.State and gstDrowning) <> 0 then
+            StopSoundChan(Gear^.SoundChannel);
+        end
     else
         begin
         if (GameTicks and $F) = 0 then
             begin
             if (GameTicks and $30) = 0 then
-                AddVisualGear(gX, gY, vgtBeeTrace);
+                begin
+                if nuw then
+                    AddVisualGear(gX, gY, vgtBubble)
+                else
+                    AddVisualGear(gX, gY, vgtBeeTrace);
+                end;
             Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
             Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
             // make sure new speed isn't higher than original one (which we stored in Friction variable)
@@ -978,17 +1047,15 @@
     end;
 
     if (Gear^.Timer > 0) then
-        dec(Gear^.Timer)
-    else
-        begin
-        Gear^.State:= Gear^.State and not gstSubmersible;
-        if nuw then
-           begin
-            StopSoundChan(Gear^.SoundChannel);
-            CheckGearDrowning(Gear);
-            end
-        else
-            doStepFallingGear(Gear);
+        begin
+        dec(Gear^.Timer);
+        if Gear^.Timer = 0 then
+            begin
+            // no need to display remaining time anymore
+            Gear^.RenderTimer:= false;
+            // bee can drown when timer reached 0
+            Gear^.State:= Gear^.State and not gstSubmersible;
+            end;
         end;
 end;
 
@@ -1656,12 +1723,14 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepSMine(Gear: PGear);
+    var land: Word;
 begin
     // TODO: do real calculation?
-    if TestCollisionXwithGear(Gear, 2)
-    or (TestCollisionYwithGear(Gear, -2) <> 0)
-    or TestCollisionXwithGear(Gear, -2)
-    or (TestCollisionYwithGear(Gear, 2) <> 0) then
+    land:= TestCollisionXwithGear(Gear, 2);
+    if land = 0 then land:= TestCollisionYwithGear(Gear,-2);
+    if land = 0 then land:= TestCollisionXwithGear(Gear,-2);
+    if land = 0 then land:= TestCollisionYwithGear(Gear, 2);
+    if (land <> 0) and (land and lfBouncy = 0) then
         begin
         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
             begin
@@ -1688,24 +1757,23 @@
                     Gear^.State := Gear^.State or gstAttacking
             end
         else // gstAttacking <> 0
-        begin
+            begin
             AllInactive := false;
             if Gear^.Timer = 0 then
                 begin
                 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
                 DeleteGear(Gear);
                 exit
-            end else
+                end
+            else
                 if (Gear^.Timer and $FF) = 0 then
                     PlaySound(sndMineTick);
-
-            dec(Gear^.Timer);
+                dec(Gear^.Timer);
                 end
-        end
+            end
     else // gsttmpFlag = 0
-        if (TurnTimeLeft = 0)
-        or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
-        or (Gear^.Hedgehog^.Gear = nil) then
+        if ((GameFlags and gfInfAttack = 0) and ((TurnTimeLeft = 0) or (Gear^.Hedgehog^.Gear = nil))) 
+        or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) then
             Gear^.State := Gear^.State or gsttmpFlag;
 end;
 
@@ -1969,7 +2037,11 @@
 procedure doStepTarget(Gear: PGear);
 begin
     if (Gear^.Timer = 0) and (Gear^.Tag = 0) then
+        begin
         PlaySound(sndWarp);
+        // workaround: save spawn Y for doStepCase (which is a mess atm)
+        Gear^.Angle:= hwRound(Gear^.Y);
+        end;
 
     if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then
         inc(Gear^.Timer)
@@ -2027,6 +2099,7 @@
 
     for i:= 0 to 3 do
         begin
+        AddVisualGear(hwRound(Gear^.X) + hwSign(Gear^.dX) * (10 + 6 * i), hwRound(Gear^.Y) + 12 + Random(6), vgtDust);
         AmmoShove(Gear, 30, 25);
         Gear^.X := Gear^.X + Gear^.dX * 5
         end;
@@ -2297,7 +2370,7 @@
         HHGear^.Y := HHGear^.Y + cGravity * 40;
 
     // don't drift into obstacles
-    if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
+    if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) <> 0 then
         HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX));
     HHGear^.Y := HHGear^.Y + cGravity * 100;
     Gear^.X := HHGear^.X;
@@ -2413,6 +2486,7 @@
     HHGear: PGear;
     x, y, tx, ty: hwFloat;
     rx: LongInt;
+    LandFlags: Word;
 begin
     AllInactive := false;
 
@@ -2423,12 +2497,16 @@
     y := HHGear^.Y;
     rx:= hwRound(x);
 
+    LandFlags:= 0;
+    if cIce then LandFlags:= lfIce
+    else if Gear^.AmmoType = amRubber then LandFlags:= lfBouncy;
+
     if ((Distance(tx - x, ty - y) > _256) and ((WorldEdge <> weWrap) or 
             (
             (Distance(tx - int2hwFloat(rightX+(rx-leftX)), ty - y) > _256) and
             (Distance(tx - int2hwFloat(leftX-(rightX-rx)), ty - y) > _256)
             )))
-    or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then
+    or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Width div 2, Gear^.Target.Y - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Height div 2, Ammoz[Gear^.AmmoType].PosSprite, Gear^.State, true, false, LandFlags)) then
         begin
         PlaySound(sndDenied);
         HHGear^.Message := HHGear^.Message and (not gmAttack);
@@ -2826,7 +2904,7 @@
                     dmg:= dmgBase - max(hwRound(Distance(tdX, tdY)),gi^.Radius);
                 if (dmg > 1) then dmg:= ModifyDamage(min(dmg div 2, cakeDmg), gi);
                 if (dmg > 1) then
-                    if (CurrentHedgehog^.Gear = gi) and (not gi^.Invulnerable) then
+                    if (CurrentHedgehog^.Gear = gi) and ((gi^.Hedgehog^.Effects[heInvulnerable] = 0)) then
                         gi^.State := gi^.State or gstLoser
                     else
                         gi^.State := gi^.State or gstWinner;
@@ -3077,14 +3155,14 @@
 
     tempColl:= Gear^.CollisionMask;
     Gear^.CollisionMask:= $007F;
-    if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
+    if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) <> 0) or (GameTicks > Gear^.FlightTime) then
         t := CheckGearsCollision(Gear)
     else t := nil;
     Gear^.CollisionMask:= tempColl;
     //fixes drill not exploding when touching HH bug
 
     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
-    or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
+    or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) = 0))
 // CheckLandValue returns true if the type isn't matched
     or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
         begin
@@ -3098,7 +3176,7 @@
         exit
         end
 
-    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
+    else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) = 0) then
         begin
         StopSoundChan(Gear^.SoundChannel);
         Gear^.Tag := 1;
@@ -3555,7 +3633,13 @@
     HHGear := Gear^.Hedgehog^.Gear;
     if HHGear = nil then
         begin
-        DeleteGear(Gear);
+        Gear^.Timer := 0;
+        Gear^.State := Gear^.State or gstAnimation or gstTmpFlag;
+        Gear^.Timer := 0;
+        Gear^.doStep := @doStepBirdyDisappear;
+        CurAmmoGear := nil;
+        isCursorVisible := false;
+        AfterAttack;
         exit
         end;
 
@@ -3657,14 +3741,21 @@
     HHGear: PGear;
 begin
     if Gear^.Timer > 0 then
-        dec(Gear^.Timer, 1)
-    else if Gear^.Hedgehog^.Gear = nil then
-        begin
-        DeleteGear(Gear);
+        dec(Gear^.Timer, 1);
+
+    HHGear := Gear^.Hedgehog^.Gear;
+    if HHGear = nil then
+        begin
+        Gear^.Timer := 0;
+        Gear^.State := Gear^.State or gstAnimation or gstTmpFlag;
+        Gear^.Timer := 0;
+        Gear^.doStep := @doStepBirdyDisappear;
+        CurAmmoGear := nil;
+        isCursorVisible := false;
         AfterAttack;
         exit
         end;
-    HHGear := Gear^.Hedgehog^.Gear;
+
     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
         begin
@@ -4030,8 +4121,7 @@
                 iterator^.Radius := iterator^.Radius - 1;
 
             // check front
-            isCollision := TestCollisionY(iterator, sy)
-                        or TestCollisionX(iterator, sx);
+            isCollision := (TestCollisionY(iterator, sy) <> 0) or (TestCollisionX(iterator, sx) <> 0);
 
             if not isCollision then
                 begin
@@ -4039,8 +4129,8 @@
                 // the square check won't check more pixels than we want to)
                 iterator^.Radius := 1 + resetr div 2;
                 rh := resetr div 4;
-                isCollision := TestCollisionYwithXYShift(iterator,       0, -sy * rh, sy, false)
-                            or TestCollisionXwithXYShift(iterator, ox * rh,        0, sx, false);
+                isCollision := (TestCollisionYwithXYShift(iterator,       0, -sy * rh, sy, false) <> 0)
+                            or (TestCollisionXwithXYShift(iterator, ox * rh,        0, sx, false) <> 0);
                 end;
 
             iterator^.Radius := resetr;
@@ -4734,7 +4824,7 @@
         if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
             begin
             //tmp^.State:= tmp^.State or gstFlatened;
-            if not tmp^.Invulnerable then
+            if (tmp^.Hedgehog^.Effects[heInvulnerable] = 0) then
                 ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
             //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
             tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
@@ -5075,7 +5165,7 @@
             while t <> nil do
                 begin
                 if (t^.Kind = gtHedgehog) and (t^.Hedgehog^.Team^.Clan = HH^.Team^.Clan) then
-                    t^.Invulnerable:= true;
+                    t^.Hedgehog^.Effects[heInvulnerable]:= 1;
                 t:= t^.NextGear;
                 end;
             end;
@@ -5629,9 +5719,9 @@
         begin
         tdX:= HHGear^.X-Gear^.X;
         dir:= hwSign(tdX);
-        if not TestCollisionX(Gear, dir) then
+        if TestCollisionX(Gear, dir) = 0 then
             Gear^.X:= Gear^.X + signAs(_1,tdX);
-        if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) then
+        if TestCollisionXwithXYShift(Gear, signAs(_10,tdX), 0, dir) <> 0 then
             begin
             Gear^.dX:= SignAs(_0_15, tdX);
             Gear^.dY:= -_0_3;
@@ -5670,9 +5760,9 @@
         begin
         (*ox:= 0; oy:= 0;
         if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1;
-        if TestCollisionXwithGear(Gear, 1)       then ox:=  1;
-        if TestCollisionXwithGear(Gear, -1)      then ox:= -1;
-        if TestCollisionYwithGear(Gear, 1) <> 0  then oy:=  1;
+        if TestCollisionXwithGear(Gear, 1)  <> 0 then ox:=  1;
+        if TestCollisionXwithGear(Gear, -1) <> 0 then ox:= -1;
+        if TestCollisionYwithGear(Gear, 1)  <> 0 then oy:=  1;
         if Gear^.Health > 0 then
             PlaySound(sndRopeAttach);
 
@@ -5701,9 +5791,9 @@
         end
     else if GameTicks and $3F = 0 then
         begin
-        if  (TestCollisionYwithGear(Gear, -1) = 0)
-        and (not TestCollisionXwithGear(Gear, 1))
-        and (not TestCollisionXwithGear(Gear, -1))
+        if  (TestCollisionYwithGear(Gear,-1) = 0)
+        and (TestCollisionXwithGear(Gear, 1) = 0)
+        and (TestCollisionXwithGear(Gear,-1) = 0)
         and (TestCollisionYwithGear(Gear, 1) = 0) then Gear^.State:= Gear^.State and (not gstCollision) or gstMoving;
         end
 end;