hedgewars/GSHandlers.inc
changeset 6081 537bbd5c1a62
parent 6011 519f8a58c021
child 6092 fd602b5838ab
equal deleted inserted replaced
6080:ce02ddfe8aa1 6081:537bbd5c1a62
   217         CheckGearDrowning := false;
   217         CheckGearDrowning := false;
   218 end;
   218 end;
   219 
   219 
   220 procedure CheckCollision(Gear: PGear); inline;
   220 procedure CheckCollision(Gear: PGear); inline;
   221 begin
   221 begin
   222     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or TestCollisionYwithGear(Gear, hwSign(Gear^.dY)
   222     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0)
   223        )
       
   224         then Gear^.State := Gear^.State or      gstCollision
   223         then Gear^.State := Gear^.State or      gstCollision
   225     else Gear^.State := Gear^.State and not gstCollision
   224     else Gear^.State := Gear^.State and not gstCollision
   226 end;
   225 end;
   227 
   226 
   228 procedure CheckCollisionWithLand(Gear: PGear); inline;
   227 procedure CheckCollisionWithLand(Gear: PGear); inline;
   301 var 
   300 var 
   302     isFalling: boolean;
   301     isFalling: boolean;
   303     //tmp: QWord;
   302     //tmp: QWord;
   304     tdX, tdY: hwFloat;
   303     tdX, tdY: hwFloat;
   305     collV, collH: LongInt;
   304     collV, collH: LongInt;
       
   305     land: word;
   306 begin
   306 begin
   307     // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems.
   307     // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems.
   308     if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
   308     if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
   309     if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
   309     if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
   310     Gear^.State := Gear^.State and not gstCollision;
   310     Gear^.State := Gear^.State and not gstCollision;
   318     if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then Gear^.State := Gear^.State or gstCollision;
   318     if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then Gear^.State := Gear^.State or gstCollision;
   319 
   319 
   320     if Gear^.dY.isNegative then
   320     if Gear^.dY.isNegative then
   321         begin
   321         begin
   322         isFalling := true;
   322         isFalling := true;
   323         if TestCollisionYwithGear(Gear, -1) then
   323         land:= TestCollisionYwithGear(Gear, -1);
       
   324         if land <> 0 then
   324             begin
   325             begin
   325             collV := -1;
   326             collV := -1;
   326             Gear^.dX :=   Gear^.dX * Gear^.Friction;
   327             if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_1 - (_1 - Gear^.Friction) / _10)
       
   328             else Gear^.dX := Gear^.dX * Gear^.Friction;
       
   329 
   327             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   330             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   328             Gear^.State := Gear^.State or gstCollision
   331             Gear^.State := Gear^.State or gstCollision
   329             end
   332             end
   330         else if (Gear^.AdvBounce=1) and TestCollisionYwithGear(Gear, 1) then collV := 1;
   333         else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then collV := 1;
   331         end
   334         end
   332     else if TestCollisionYwithGear(Gear, 1) then
   335     else 
   333         begin
   336         begin
   334         collV := 1;
   337         land:= TestCollisionYwithGear(Gear, 1);
   335         isFalling := false;
   338         if land <> 0 then
   336         Gear^.dX :=   Gear^.dX * Gear^.Friction;
   339             begin
   337         Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   340             collV := 1;
   338         Gear^.State := Gear^.State or gstCollision
   341             isFalling := false;
   339         end
   342             if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_1 - (_1 - Gear^.Friction) / _10)
   340     else
   343             else Gear^.dX := Gear^.dX * Gear^.Friction;
   341         begin
   344 
   342         isFalling := true;
   345             Gear^.dY := - Gear^.dY * Gear^.Elasticity;
   343         if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and TestCollisionYwithGear(Gear, -1) then
   346             Gear^.State := Gear^.State or gstCollision
   344             collV := -1;
   347             end
       
   348         else
       
   349             begin
       
   350             isFalling := true;
       
   351             if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and (TestCollisionYwithGear(Gear, -1) <> 0) then
       
   352                 collV := -1
       
   353             end
   345         end;
   354         end;
   346 
   355 
   347 
   356 
   348     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   357     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
   349         begin
   358         begin
  1258             Gear^.X := Gear^.X + Gear^.dX;
  1267             Gear^.X := Gear^.X + Gear^.dX;
  1259             Gear^.Y := Gear^.Y + _1_9;
  1268             Gear^.Y := Gear^.Y + _1_9;
  1260             end;
  1269             end;
  1261         SetAllHHToActive;
  1270         SetAllHHToActive;
  1262         end;
  1271         end;
  1263     if TestCollisionYwithGear(Gear, 1) then
  1272     if TestCollisionYwithGear(Gear, 1) <> 0 then
  1264         begin
  1273         begin
  1265         Gear^.dY := _0;
  1274         Gear^.dY := _0;
  1266         SetLittle(HHGear^.dX);
  1275         SetLittle(HHGear^.dX);
  1267         HHGear^.dY := _0;
  1276         HHGear^.dY := _0;
  1268         end
  1277         end
  1427     HHGear: PGear;
  1436     HHGear: PGear;
  1428 begin
  1437 begin
  1429     HHGear := Gear^.Hedgehog^.Gear;
  1438     HHGear := Gear^.Hedgehog^.Gear;
  1430     if ((HHGear^.State and gstHHDriven) = 0)
  1439     if ((HHGear^.State and gstHHDriven) = 0)
  1431        or (CheckGearDrowning(HHGear))
  1440        or (CheckGearDrowning(HHGear))
  1432        or TestCollisionYwithGear(HHGear, 1) then
  1441        or (TestCollisionYwithGear(HHGear, 1) <> 0) then
  1433     begin
  1442     begin
  1434         DeleteGear(Gear);
  1443         DeleteGear(Gear);
  1435         isCursorVisible := false;
  1444         isCursorVisible := false;
  1436         ApplyAmmoChanges(HHGear^.Hedgehog^);
  1445         ApplyAmmoChanges(HHGear^.Hedgehog^);
  1437         exit
  1446         exit
  1439 
  1448 
  1440     HedgehogChAngle(HHGear);
  1449     HedgehogChAngle(HHGear);
  1441 
  1450 
  1442     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1451     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1443 
  1452 
  1444     if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0;
  1453     if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then HHGear^.dY := _0;
  1445     HHGear^.X := HHGear^.X + HHGear^.dX;
  1454     HHGear^.X := HHGear^.X + HHGear^.dX;
  1446     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1455     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1447     HHGear^.dY := HHGear^.dY + cGravity;
  1456     HHGear^.dY := HHGear^.dY + cGravity;
  1448     if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
  1457     if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
  1449 
  1458 
  1512 
  1521 
  1513     // vector between hedgehog and rope attaching point
  1522     // vector between hedgehog and rope attaching point
  1514     ropeDx := HHGear^.X - Gear^.X;
  1523     ropeDx := HHGear^.X - Gear^.X;
  1515     ropeDy := HHGear^.Y - Gear^.Y;
  1524     ropeDy := HHGear^.Y - Gear^.Y;
  1516 
  1525 
  1517     if not TestCollisionYwithGear(HHGear, 1) then
  1526     if TestCollisionYwithGear(HHGear, 1) = 0 then
  1518         begin
  1527         begin
  1519 
  1528 
  1520         // depending on the rope vector we know which X-side to check for collision
  1529         // depending on the rope vector we know which X-side to check for collision
  1521         // in order to find out if the hog can still be moved by gravity
  1530         // in order to find out if the hog can still be moved by gravity
  1522         if ropeDx.isNegative = RopeDy.IsNegative then
  1531         if ropeDx.isNegative = RopeDy.IsNegative then
  1549     tx := HHGear^.X;
  1558     tx := HHGear^.X;
  1550     ty := HHGear^.Y;
  1559     ty := HHGear^.Y;
  1551 
  1560 
  1552     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
  1561     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
  1553         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
  1562         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
  1554            or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then
  1563            or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then
  1555             Gear^.Elasticity := Gear^.Elasticity + _0_3;
  1564             Gear^.Elasticity := Gear^.Elasticity + _0_3;
  1556 
  1565 
  1557     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
  1566     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
  1558         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
  1567         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
  1559            or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then
  1568            or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then
  1560             Gear^.Elasticity := Gear^.Elasticity - _0_3;
  1569             Gear^.Elasticity := Gear^.Elasticity - _0_3;
  1561 
  1570 
  1562     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
  1571     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
  1563     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
  1572     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
  1564 
  1573 
  1646     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1655     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1647         begin
  1656         begin
  1648         HHGear^.dX := -_0_6 * HHGear^.dX;
  1657         HHGear^.dX := -_0_6 * HHGear^.dX;
  1649         haveCollision := true
  1658         haveCollision := true
  1650         end;
  1659         end;
  1651     if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then
  1660     if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0 then
  1652         begin
  1661         begin
  1653         HHGear^.dY := -_0_6 * HHGear^.dY;
  1662         HHGear^.dY := -_0_6 * HHGear^.dY;
  1654         haveCollision := true
  1663         haveCollision := true
  1655         end;
  1664         end;
  1656 
  1665 
  1748     DeleteCI(HHGear);
  1757     DeleteCI(HHGear);
  1749 
  1758 
  1750     if (HHGear^.State and gstMoving) <> 0 then
  1759     if (HHGear^.State and gstMoving) <> 0 then
  1751         begin
  1760         begin
  1752         if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1761         if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX);
  1753         if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0;
  1762         if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then HHGear^.dY := _0;
  1754 
  1763 
  1755         HHGear^.X := HHGear^.X + HHGear^.dX;
  1764         HHGear^.X := HHGear^.X + HHGear^.dX;
  1756         Gear^.X := Gear^.X + HHGear^.dX;
  1765         Gear^.X := Gear^.X + HHGear^.dX;
  1757 
  1766 
  1758         if TestCollisionYwithGear(HHGear, 1) then
  1767         if TestCollisionYwithGear(HHGear, 1) <> 0 then
  1759             begin
  1768             begin
  1760             CheckHHDamage(HHGear);
  1769             CheckHHDamage(HHGear);
  1761             HHGear^.dY := _0
  1770             HHGear^.dY := _0
  1762             //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
  1771             //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
  1763             end
  1772             end
  1861     else
  1870     else
  1862         if ((GameTicks and $3F) = 25) then
  1871         if ((GameTicks and $3F) = 25) then
  1863             doStepFallingGear(Gear);
  1872             doStepFallingGear(Gear);
  1864     if (Gear^.Health = 0) then
  1873     if (Gear^.Health = 0) then
  1865         begin
  1874         begin
  1866             if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and TestCollisionYwithGear(Gear, 1) then
  1875             if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
  1867                 inc(Gear^.Damage, hwRound(Gear^.dY * _70))
  1876                 inc(Gear^.Damage, hwRound(Gear^.dY * _70))
  1868             else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1877             else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1869                  inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1878                  inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1870             else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and TestCollisionYwithGear(Gear, -1) then
  1879             else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1871                  inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1880                  inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1872             else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1881             else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
  1873                  inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1882                  inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  1874         
  1883         
  1875         if (Gear^.Damage > random(30)) and ((GameTicks and $FF) = 0) then
  1884         if (Gear^.Damage > random(30)) and ((GameTicks and $FF) = 0) then
  1925 
  1934 
  1926 ////////////////////////////////////////////////////////////////////////////////
  1935 ////////////////////////////////////////////////////////////////////////////////
  1927 procedure doStepSMine(Gear: PGear);
  1936 procedure doStepSMine(Gear: PGear);
  1928 begin
  1937 begin
  1929     // TODO: do real calculation?
  1938     // TODO: do real calculation?
  1930     if TestCollisionXwithGear(Gear, 2) or TestCollisionYwithGear(Gear, -2) or TestCollisionXwithGear(Gear, -2) or TestCollisionYwithGear(Gear, 2) then
  1939     if TestCollisionXwithGear(Gear, 2) or (TestCollisionYwithGear(Gear, -2) <> 0) or TestCollisionXwithGear(Gear, -2) or (TestCollisionYwithGear(Gear, 2) <> 0) then
  1931     begin
  1940     begin
  1932         if (hwAbs(Gear^.dX) > _0) or (hwAbs(Gear^.dY) > _0) then
  1941         if (hwAbs(Gear^.dX) > _0) or (hwAbs(Gear^.dY) > _0) then
  1933         begin
  1942         begin
  1934             PlaySound(sndRopeAttach);
  1943             PlaySound(sndRopeAttach);
  1935             Gear^.dX:= _0;
  1944             Gear^.dX:= _0;
  1997 procedure doStepRollingBarrel(Gear: PGear);
  2006 procedure doStepRollingBarrel(Gear: PGear);
  1998 var 
  2007 var 
  1999     i: LongInt;
  2008     i: LongInt;
  2000     particle: PVisualGear;
  2009     particle: PVisualGear;
  2001 begin
  2010 begin
  2002     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and not TestCollisionYwithGear(Gear, 1) then SetLittle(Gear^.dY);
  2011     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then SetLittle(Gear^.dY);
  2003     Gear^.State := Gear^.State or gstAnimation;
  2012     Gear^.State := Gear^.State or gstAnimation;
  2004     if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0))  then
  2013     if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0))  then
  2005     begin
  2014     begin
  2006         DeleteCI(Gear);
  2015         DeleteCI(Gear);
  2007         AllInactive := false;
  2016         AllInactive := false;
  2008         if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and TestCollisionYwithGear(Gear, 1) then
  2017         if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
  2009         begin
  2018         begin
  2010             Gear^.State := Gear^.State or gsttmpFlag;
  2019             Gear^.State := Gear^.State or gsttmpFlag;
  2011             inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  2020             inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  2012             for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  2021             for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  2013             begin
  2022             begin
  2017             end
  2026             end
  2018         end
  2027         end
  2019         else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1)
  2028         else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1)
  2020                  then
  2029                  then
  2021                  inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  2030                  inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  2022         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and TestCollisionYwithGear(Gear, -1)
  2031         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0)
  2023                  then
  2032                  then
  2024                  inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  2033                  inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  2025         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1)
  2034         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1)
  2026                  then
  2035                  then
  2027                  inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  2036                  inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
  2050                 Gear^.dX:= _0_08;
  2059                 Gear^.dX:= _0_08;
  2051             end;
  2060             end;
  2052     if Gear^.dX.QWordValue = 0 then AddGearCI(Gear)
  2061     if Gear^.dX.QWordValue = 0 then AddGearCI(Gear)
  2053     end; *)
  2062     end; *)
  2054 
  2063 
  2055     if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and TestCollisionYwithGear(Gear, 1) then Gear
  2064     if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then Gear
  2056         ^.dY := _0;
  2065         ^.dY := _0;
  2057     if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0;
  2066     if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0;
  2058 
  2067 
  2059     if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
  2068     if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
  2060         if (cBarrelHealth div Gear^.Health) > 2 then
  2069         if (cBarrelHealth div Gear^.Health) > 2 then
  2134                 end
  2143                 end
  2135             end;
  2144             end;
  2136         exit
  2145         exit
  2137     end;
  2146     end;
  2138 
  2147 
  2139     if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then
  2148     if (Gear^.dY.QWordValue <> 0) or (TestCollisionYwithGear(Gear, 1) = 0) then
  2140     begin
  2149     begin
  2141         AllInactive := false;
  2150         AllInactive := false;
  2142         Gear^.dY := Gear^.dY + cGravity;
  2151         Gear^.dY := Gear^.dY + cGravity;
  2143         Gear^.Y := Gear^.Y + Gear^.dY;
  2152         Gear^.Y := Gear^.Y + Gear^.dY;
  2144         if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive;
  2153         if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive;
  2145         if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY := _0;
  2154         if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then Gear^.dY := _0;
  2146         if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then
  2155         if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
  2147         begin
  2156         begin
  2148             if (Gear^.dY > _0_2) and (k = gtExplosives) then
  2157             if (Gear^.dY > _0_2) and (k = gtExplosives) then
  2149                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  2158                 inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  2150 
  2159 
  2151             if Gear^.dY > _0_2 then
  2160             if Gear^.dY > _0_2 then
  2247     tdX,tdY: HWFloat;
  2256     tdX,tdY: HWFloat;
  2248 begin
  2257 begin
  2249     sticky:= (Gear^.State and gsttmpFlag) <> 0;
  2258     sticky:= (Gear^.State and gsttmpFlag) <> 0;
  2250     if not sticky then AllInactive := false;
  2259     if not sticky then AllInactive := false;
  2251 
  2260 
  2252     if not TestCollisionYwithGear(Gear, 1) then
  2261     if TestCollisionYwithGear(Gear, 1) = 0 then
  2253     begin
  2262     begin
  2254         AllInactive := false;
  2263         AllInactive := false;
  2255 
  2264 
  2256         if ((GameTicks mod 100) = 0) then
  2265         if ((GameTicks mod 100) = 0) then
  2257             begin
  2266             begin
  2445 begin
  2454 begin
  2446     HHGear := Gear^.Hedgehog^.Gear;
  2455     HHGear := Gear^.Hedgehog^.Gear;
  2447 
  2456 
  2448     inc(Gear^.Timer);
  2457     inc(Gear^.Timer);
  2449 
  2458 
  2450     if TestCollisionYwithGear(HHGear, 1)
  2459     if (TestCollisionYwithGear(HHGear, 1) <> 0)
  2451        or ((HHGear^.State and gstHHDriven) = 0)
  2460        or ((HHGear^.State and gstHHDriven) = 0)
  2452        or CheckGearDrowning(HHGear)
  2461        or CheckGearDrowning(HHGear)
  2453        or ((Gear^.Message and gmAttack) <> 0) then
  2462        or ((Gear^.Message and gmAttack) <> 0) then
  2454     begin
  2463     begin
  2455         with HHGear^ do
  2464         with HHGear^ do
  2631     HHGear := Gear^.Hedgehog^.Gear;
  2640     HHGear := Gear^.Hedgehog^.Gear;
  2632     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  2641     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  2633     HHGear^.X := HHGear^.X + HHGear^.dX;
  2642     HHGear^.X := HHGear^.X + HHGear^.dX;
  2634     // hedgehog falling to collect cases
  2643     // hedgehog falling to collect cases
  2635     HHGear^.dY := HHGear^.dY + cGravity;
  2644     HHGear^.dY := HHGear^.dY + cGravity;
  2636     if TestCollisionYwithGear(HHGear, 1)
  2645     if (TestCollisionYwithGear(HHGear, 1) <> 0)
  2637        or CheckGearDrowning(HHGear) then
  2646        or CheckGearDrowning(HHGear) then
  2638     begin
  2647     begin
  2639         DeleteGear(Gear);
  2648         DeleteGear(Gear);
  2640         AfterAttack
  2649         AfterAttack
  2641     end
  2650     end
  3004     yy := dirs[Gear^.Angle].y;
  3013     yy := dirs[Gear^.Angle].y;
  3005     xxn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x;
  3014     xxn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x;
  3006     yyn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y;
  3015     yyn := dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y;
  3007 
  3016 
  3008     if (xx = 0) then
  3017     if (xx = 0) then
  3009         if TestCollisionYwithGear(Gear, yy) then
  3018         if TestCollisionYwithGear(Gear, yy) <> 0 then
  3010             PrevAngle
  3019             PrevAngle
  3011     else
  3020     else
  3012     begin
  3021     begin
  3013         Gear^.Tag := 0;
  3022         Gear^.Tag := 0;
  3014         Gear^.Y := Gear^.Y + int2hwFloat(yy);
  3023         Gear^.Y := Gear^.Y + int2hwFloat(yy);
  3081 procedure doStepCakeFall(Gear: PGear);
  3090 procedure doStepCakeFall(Gear: PGear);
  3082 begin
  3091 begin
  3083     AllInactive := false;
  3092     AllInactive := false;
  3084 
  3093 
  3085     Gear^.dY := Gear^.dY + cGravity;
  3094     Gear^.dY := Gear^.dY + cGravity;
  3086     if TestCollisionYwithGear(Gear, 1) then
  3095     if TestCollisionYwithGear(Gear, 1) <> 0 then Gear^.doStep := @doStepCakeUp
  3087         Gear^.doStep := @doStepCakeUp
       
  3088     else
  3096     else
  3089     begin
  3097         begin
  3090         Gear^.Y := Gear^.Y + Gear^.dY;
  3098         Gear^.Y := Gear^.Y + Gear^.dY;
  3091         if CheckGearDrowning(Gear) then AfterAttack
  3099         if CheckGearDrowning(Gear) then AfterAttack
  3092     end
  3100         end
  3093 end;
  3101 end;
  3094 
  3102 
  3095 procedure doStepCake(Gear: PGear);
  3103 procedure doStepCake(Gear: PGear);
  3096 var 
  3104 var 
  3097     HHGear: PGear;
  3105     HHGear: PGear;
  3252         end
  3260         end
  3253     end;
  3261     end;
  3254 
  3262 
  3255     t := CheckGearsCollision(Gear);
  3263     t := CheckGearsCollision(Gear);
  3256     //fixes drill not exploding when touching HH bug
  3264     //fixes drill not exploding when touching HH bug
  3257     if (Gear^.Timer = 0)
  3265     if (Gear^.Timer = 0) or (t^.Count <> 0) or 
  3258        or (t^.Count <> 0)
  3266        ( ((Gear^.State and gsttmpFlag) = 0) and
  3259        or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY))
  3267          (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0)
  3260        and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))
  3268          and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
  3261        and ((Gear^.State and gsttmpFlag) = 0)) 
       
  3262 // CheckLandValue returns true if the type isn't matched
  3269 // CheckLandValue returns true if the type isn't matched
  3263        or not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible) then
  3270        or not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible) then
  3264         begin
  3271         begin
  3265         //out of time or exited ground
  3272         //out of time or exited ground
  3266         StopSound(Gear^.SoundChannel);
  3273         StopSound(Gear^.SoundChannel);
  3269         else
  3276         else
  3270             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  3277             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  3271         DeleteGear(Gear);
  3278         DeleteGear(Gear);
  3272         exit
  3279         exit
  3273         end
  3280         end
  3274     else if not TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) then
  3281     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) then
  3275         begin
  3282         begin
  3276         StopSound(Gear^.SoundChannel);
  3283         StopSound(Gear^.SoundChannel);
  3277         Gear^.Tag := 1;
  3284         Gear^.Tag := 1;
  3278         Gear^.doStep := @doStepDrill
  3285         Gear^.doStep := @doStepDrill
  3279         end;
  3286         end;
  3623         (HHGear^.Damage <> 0)
  3630         (HHGear^.Damage <> 0)
  3624         //or CheckGearDrowning(HHGear)
  3631         //or CheckGearDrowning(HHGear)
  3625         or (cWaterLine + 512 < hwRound(HHGear^.Y))
  3632         or (cWaterLine + 512 < hwRound(HHGear^.Y))
  3626         or (TurnTimeLeft = 0)
  3633         or (TurnTimeLeft = 0)
  3627         // allow brief ground touches - to be fair on this, might need another counter
  3634         // allow brief ground touches - to be fair on this, might need another counter
  3628         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3635         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3629         HHGear, 1))
       
  3630         or ((Gear^.Message and gmAttack) <> 0) then
  3636         or ((Gear^.Message and gmAttack) <> 0) then
  3631         begin
  3637         begin
  3632         with HHGear^ do
  3638         with HHGear^ do
  3633             begin
  3639             begin
  3634             Message := 0;
  3640             Message := 0;
  3748     if  (Gear^.Health = 0)
  3754     if  (Gear^.Health = 0)
  3749        or (HHGear^.Damage <> 0)
  3755        or (HHGear^.Damage <> 0)
  3750        or CheckGearDrowning(HHGear)
  3756        or CheckGearDrowning(HHGear)
  3751        or (TurnTimeLeft = 0)
  3757        or (TurnTimeLeft = 0)
  3752        // allow brief ground touches - to be fair on this, might need another counter
  3758        // allow brief ground touches - to be fair on this, might need another counter
  3753        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3759        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3754        HHGear, 1))
       
  3755        or ((Gear^.Message and gmAttack) <> 0) then
  3760        or ((Gear^.Message and gmAttack) <> 0) then
  3756         begin
  3761         begin
  3757         with HHGear^ do
  3762         with HHGear^ do
  3758             begin
  3763             begin
  3759             Message := 0;
  3764             Message := 0;
  4822             begin
  4827             begin
  4823             Gear^.X := Gear^.X + Gear^.dX;
  4828             Gear^.X := Gear^.X + Gear^.dX;
  4824             Gear^.Y := Gear^.Y + _1_9;
  4829             Gear^.Y := Gear^.Y + _1_9;
  4825             end;
  4830             end;
  4826         end;
  4831         end;
  4827     if TestCollisionYwithGear(Gear, 1) then
  4832     if TestCollisionYwithGear(Gear, 1) <> 0 then
  4828         begin
  4833         begin
  4829         Gear^.dY := _0;
  4834         Gear^.dY := _0;
  4830         SetLittle(HitGear^.dX);
  4835         SetLittle(HitGear^.dX);
  4831         HitGear^.dY := _0;
  4836         HitGear^.dY := _0;
  4832         end
  4837         end
  4897     else if (GameTicks and $1FF) <> 0 then exit;
  4902     else if (GameTicks and $1FF) <> 0 then exit;
  4898 
  4903 
  4899     if Gear^.Power < 45 then 
  4904     if Gear^.Power < 45 then 
  4900         begin
  4905         begin
  4901         inc(Gear^.Power);
  4906         inc(Gear^.Power);
  4902         if not TestCollisionYwithGear(hh^.Gear, -1) then hh^.Gear^.Y := hh^.Gear^.Y - _1;
  4907         if TestCollisionYwithGear(hh^.Gear, -1) = 0 then hh^.Gear^.Y := hh^.Gear^.Y - _1;
  4903         end;
  4908         end;
  4904 
  4909 
  4905     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
  4910     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
  4906 
  4911 
  4907     if Length(graves) = 0 then 
  4912     if Length(graves) = 0 then