hedgewars/GSHandlers.inc
branchwebgl
changeset 9127 e350500c4edb
parent 8850 ae8a957c69fd
parent 9080 9b42757d7e71
child 9160 fc46e75f6b72
equal deleted inserted replaced
8860:bde641cf53c8 9127:e350500c4edb
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
   193     Gear^.State := Gear^.State and (not gstCollision);
   193     Gear^.State := Gear^.State and (not gstCollision);
   194     collV := 0;
   194     collV := 0;
   195     collH := 0;
   195     collH := 0;
   196     tdX := Gear^.dX;
   196     tdX := Gear^.dX;
   197     tdY := Gear^.dY;
   197     tdY := Gear^.dY;
       
   198 
   198 
   199 
   199 
   200 
   200 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
   201 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
   201     if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
   202     if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
   202     or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
   203     or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
   427 
   428 
   428     doStepFallingGear(Gear);
   429     doStepFallingGear(Gear);
   429     CalcRotationDirAngle(Gear);
   430     CalcRotationDirAngle(Gear);
   430 
   431 
   431     // let's add some smoke depending on speed
   432     // let's add some smoke depending on speed
   432     s:= max(32,152 - hwRound(Distance(Gear^.dX,Gear^.dY)*120))+random(10);
   433     s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10);
   433     if (GameTicks mod s) = 0 then
   434     if (GameTicks mod s) = 0 then
   434         begin
   435         begin
   435         // adjust angle to match the texture
   436         // adjust angle to match the texture
   436         if Gear^.dX.isNegative then
   437         if Gear^.dX.isNegative then
   437             i:= 130
   438              i:= 130
   438         else
   439         else i:= 50;
   439             i:= 50;
       
   440 
   440 
   441         smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
   441         smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
   442         if smoke <> nil then
   442         if smoke <> nil then
   443             smoke^.Scale:= 0.75;
   443             smoke^.Scale:= 0.75;
   444         end;
   444         end;
   502 
   502 
   503     if (Gear^.Kind = gtMelonPiece)
   503     if (Gear^.Kind = gtMelonPiece)
   504     or (Gear^.Kind = gtBall) then
   504     or (Gear^.Kind = gtBall) then
   505         CalcRotationDirAngle(Gear)
   505         CalcRotationDirAngle(Gear)
   506     else if (GameTicks and $1F) = 0 then
   506     else if (GameTicks and $1F) = 0 then
   507         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
   507         begin
       
   508         if hwRound(Gear^.Y) > cWaterLine then
       
   509              AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
       
   510         else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
       
   511         end
   508 end;
   512 end;
   509 
   513 
   510 ////////////////////////////////////////////////////////////////////////////////
   514 ////////////////////////////////////////////////////////////////////////////////
   511 procedure doStepShell(Gear: PGear);
   515 procedure doStepShell(Gear: PGear);
   512 begin
   516 begin
   519         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   523         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   520         DeleteGear(Gear);
   524         DeleteGear(Gear);
   521         exit
   525         exit
   522         end;
   526         end;
   523     if (GameTicks and $3F) = 0 then
   527     if (GameTicks and $3F) = 0 then
   524         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
   528         begin
       
   529         if hwRound(Gear^.Y) > cWaterLine then
       
   530              AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
       
   531         else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
       
   532         end
   525 end;
   533 end;
   526 
   534 
   527 ////////////////////////////////////////////////////////////////////////////////
   535 ////////////////////////////////////////////////////////////////////////////////
   528 procedure doStepSnowball(Gear: PGear);
   536 procedure doStepSnowball(Gear: PGear);
   529 var kick, i: LongInt;
   537 var kick, i: LongInt;
   530     particle: PVisualGear;
   538     particle: PVisualGear;
       
   539     gdX, gdY: hwFloat;
   531 begin
   540 begin
   532     AllInactive := false;
   541     AllInactive := false;
   533     if (GameFlags and gfMoreWind) = 0 then
   542     if (GameFlags and gfMoreWind) = 0 then
   534         Gear^.dX := Gear^.dX + cWindSpeed;
   543         Gear^.dX := Gear^.dX + cWindSpeed;
       
   544     gdX := Gear^.dX;
       
   545     gdY := Gear^.dY;
   535     doStepFallingGear(Gear);
   546     doStepFallingGear(Gear);
   536     CalcRotationDirAngle(Gear);
   547     CalcRotationDirAngle(Gear);
   537     if (Gear^.State and gstCollision) <> 0 then
   548     if (Gear^.State and gstCollision) <> 0 then
   538         begin
   549         begin
   539         kick:= hwRound((hwAbs(Gear^.dX)+hwAbs(Gear^.dY)) * _20);
   550         kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20);
   540         Gear^.dY.isNegative:= (not Gear^.dY.isNegative);
   551         Gear^.dX:= gdX;
   541         Gear^.dX.isNegative:= (not Gear^.dX.isNegative);
   552         Gear^.dY:= gdY;
   542         AmmoShove(Gear, 0, kick);
   553         AmmoShove(Gear, 0, kick);
   543         for i:= 15 + kick div 10 downto 0 do
   554         for i:= 15 + kick div 10 downto 0 do
   544             begin
   555             begin
   545             particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust);
   556             particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust);
   546             if particle <> nil then
   557             if particle <> nil then
  1416 end;
  1427 end;
  1417 
  1428 
  1418 ////////////////////////////////////////////////////////////////////////////////
  1429 ////////////////////////////////////////////////////////////////////////////////
  1419 procedure doStepMine(Gear: PGear);
  1430 procedure doStepMine(Gear: PGear);
  1420 var vg: PVisualGear;
  1431 var vg: PVisualGear;
  1421 begin
  1432     dxdy: hwFloat;
       
  1433 begin
       
  1434     if Gear^.Health = 0 then dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
  1422     if (Gear^.State and gstMoving) <> 0 then
  1435     if (Gear^.State and gstMoving) <> 0 then
  1423         begin
  1436         begin
  1424         DeleteCI(Gear);
  1437         DeleteCI(Gear);
  1425         doStepFallingGear(Gear);
  1438         doStepFallingGear(Gear);
  1426         if (Gear^.State and gstMoving) = 0 then
  1439         if (Gear^.State and gstMoving) = 0 then
  1434         end
  1447         end
  1435     else if (GameTicks and $3F) = 25 then
  1448     else if (GameTicks and $3F) = 25 then
  1436         doStepFallingGear(Gear);
  1449         doStepFallingGear(Gear);
  1437     if (Gear^.Health = 0) then
  1450     if (Gear^.Health = 0) then
  1438         begin
  1451         begin
  1439         if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
  1452         if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then
  1440             inc(Gear^.Damage, hwRound(Gear^.dY * _70))
  1453             inc(Gear^.Damage, hwRound(dxdy * _50));
  1441         else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
       
  1442             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
       
  1443         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
       
  1444             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
       
  1445         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
       
  1446             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
       
  1447 
  1454 
  1448         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1455         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
  1449             begin
  1456             begin
  1450             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1457             vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1451             if vg <> nil then
  1458             if vg <> nil then
  1575     dec(Gear^.Timer);
  1582     dec(Gear^.Timer);
  1576 end;
  1583 end;
  1577 
  1584 
  1578 ///////////////////////////////////////////////////////////////////////////////
  1585 ///////////////////////////////////////////////////////////////////////////////
  1579 
  1586 
  1580 (*
       
  1581 TODO
       
  1582 Increase damage as barrel smokes?
       
  1583 Try tweaking friction some more
       
  1584 *)
       
  1585 procedure doStepRollingBarrel(Gear: PGear);
  1587 procedure doStepRollingBarrel(Gear: PGear);
  1586 var
  1588 var
  1587     i: LongInt;
  1589     i: LongInt;
  1588     particle: PVisualGear;
  1590     particle: PVisualGear;
       
  1591     dxdy: hwFloat;
  1589 begin
  1592 begin
  1590     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1593     if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
  1591         SetLittle(Gear^.dY);
  1594         SetLittle(Gear^.dY);
  1592     Gear^.State := Gear^.State or gstAnimation;
  1595     Gear^.State := Gear^.State or gstAnimation;
       
  1596     if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen;
  1593 
  1597 
  1594     if ((Gear^.dX.QWordValue <> 0)
  1598     if ((Gear^.dX.QWordValue <> 0)
  1595     or (Gear^.dY.QWordValue <> 0))  then
  1599     or (Gear^.dY.QWordValue <> 0))  then
  1596         begin
  1600         begin
  1597         DeleteCI(Gear);
  1601         DeleteCI(Gear);
  1598         AllInactive := false;
  1602         AllInactive := false;
  1599         if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
  1603         dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
  1600             begin
  1604         doStepFallingGear(Gear);
  1601             Gear^.State := Gear^.State or gsttmpFlag;
  1605         if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then
  1602             inc(Gear^.Damage, hwRound(Gear^.dY * _70));
  1606             begin
  1603             for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
  1607             if (TestCollisionYwithGear(Gear, 1) <> 0) then
  1604                 begin
  1608                 begin
  1605                 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
  1609                 Gear^.State := Gear^.State or gsttmpFlag;
  1606                 if particle <> nil then
  1610                 for i:= min(12, hwRound(dxdy*_10)) downto 0 do
  1607                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1611                     begin
  1608                 end
  1612                     particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
  1609             end
  1613                     if particle <> nil then
  1610         else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
  1614                         particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
  1611                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
  1615                     end
  1612 
  1616                 end;
  1613         else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
  1617             inc(Gear^.Damage, hwRound(dxdy * _50))
  1614                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
  1618             end;
  1615 
       
  1616         else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
       
  1617                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
       
  1618 
       
  1619         doStepFallingGear(Gear);
       
  1620         CalcRotationDirAngle(Gear);
  1619         CalcRotationDirAngle(Gear);
  1621         //CheckGearDrowning(Gear)
  1620         //CheckGearDrowning(Gear)
  1622         end
  1621         end
  1623     else
  1622     else
  1624         begin
  1623         begin
  1653     else
  1652     else
  1654         AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
  1653         AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
  1655     dec(Gear^.Health, Gear^.Damage);
  1654     dec(Gear^.Health, Gear^.Damage);
  1656     Gear^.Damage := 0;
  1655     Gear^.Damage := 0;
  1657     if Gear^.Health <= 0 then
  1656     if Gear^.Health <= 0 then
  1658         Gear^.doStep := @doStepCase;
  1657         doStepCase(Gear);
  1659     // Hand off to doStepCase for the explosion
       
  1660 
       
  1661 end;
  1658 end;
  1662 
  1659 
  1663 procedure doStepCase(Gear: PGear);
  1660 procedure doStepCase(Gear: PGear);
  1664 var
  1661 var
  1665     i, x, y: LongInt;
  1662     i, x, y: LongInt;
  1666     k: TGearType;
  1663     k: TGearType;
  1667     exBoom: boolean;
       
  1668     dX, dY: HWFloat;
  1664     dX, dY: HWFloat;
  1669     hog: PHedgehog;
  1665     hog: PHedgehog;
  1670     sparkles: PVisualGear;
  1666     sparkles: PVisualGear;
  1671     gi: PGear;
  1667     gi: PGear;
  1672 begin
  1668 begin
  1673     k := Gear^.Kind;
  1669     k := Gear^.Kind;
  1674     exBoom := false;
       
  1675 
  1670 
  1676     if (Gear^.Message and gmDestroy) > 0 then
  1671     if (Gear^.Message and gmDestroy) > 0 then
  1677         begin
  1672         begin
  1678         DeleteGear(Gear);
  1673         DeleteGear(Gear);
  1679         FreeActionsList;
  1674         FreeActionsList;
  1682         with CurrentHedgehog^ do
  1677         with CurrentHedgehog^ do
  1683             if Gear <> nil then
  1678             if Gear <> nil then
  1684                 Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
  1679                 Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
  1685         exit
  1680         exit
  1686         end;
  1681         end;
  1687 
  1682     if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen;
  1688     if k = gtExplosives then
  1683 
  1689         begin
  1684     if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then
  1690         //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
       
  1691         if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then
       
  1692             Gear^.doStep := @doStepRollingBarrel;
       
  1693 
       
  1694         if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
       
  1695             if (cBarrelHealth div Gear^.Health) > 2 then
       
  1696                 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
       
  1697         else
       
  1698             AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
       
  1699         dec(Gear^.Health, Gear^.Damage);
       
  1700         Gear^.Damage := 0;
       
  1701         if Gear^.Health <= 0 then
       
  1702             exBoom := true;
       
  1703         end
       
  1704     else
       
  1705         begin
       
  1706         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
       
  1707             begin
       
  1708             gi := GearsList;
       
  1709             while gi <> nil do
       
  1710                 begin
       
  1711                 if gi^.Kind = gtGenericFaller then
       
  1712                     begin
       
  1713                     gi^.Active:= true;
       
  1714                     gi^.X:=  int2hwFloat(GetRandom(rightX-leftX)+leftX);
       
  1715                     gi^.Y:=  int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
       
  1716                     gi^.dX:= _90-(GetRandomf*_360);
       
  1717                     gi^.dY:= _90-(GetRandomf*_360)
       
  1718                     end;
       
  1719                 gi := gi^.NextGear
       
  1720                 end
       
  1721             end;
       
  1722 
       
  1723         if Gear^.Timer = 500 then
       
  1724             begin
       
  1725 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
       
  1726    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
       
  1727    has its own complexities. *)
       
  1728             // Abuse a couple of gear values to track origin
       
  1729             Gear^.Angle:= hwRound(Gear^.Y);
       
  1730             Gear^.Tag:= random(2);
       
  1731             inc(Gear^.Timer)
       
  1732             end;
       
  1733         if Gear^.Timer < 1833 then inc(Gear^.Timer);
       
  1734         if Gear^.Timer = 1000 then
       
  1735             begin
       
  1736             sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1);
       
  1737             if sparkles <> nil then
       
  1738                 begin
       
  1739                 sparkles^.dX:= 0;
       
  1740                 sparkles^.dY:= 0;
       
  1741                 sparkles^.Angle:= 270;
       
  1742                 if Gear^.Tag = 1 then
       
  1743                     sparkles^.Tint:= $3744D7FF
       
  1744                 else sparkles^.Tint:= $FAB22CFF
       
  1745                 end;
       
  1746             end;
       
  1747         if Gear^.Timer < 1000 then
       
  1748             begin
       
  1749             AllInactive:= false;
       
  1750             exit
       
  1751             end
       
  1752         end;
       
  1753 
       
  1754     if (Gear^.Damage > 0) or exBoom then
       
  1755         begin
  1685         begin
  1756         x := hwRound(Gear^.X);
  1686         x := hwRound(Gear^.X);
  1757         y := hwRound(Gear^.Y);
  1687         y := hwRound(Gear^.Y);
  1758         hog:= Gear^.Hedgehog;
  1688         hog:= Gear^.Hedgehog;
  1759 
  1689 
  1777                     AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
  1707                     AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
  1778                     end
  1708                     end
  1779                 end;
  1709                 end;
  1780             exit
  1710             exit
  1781         end;
  1711         end;
       
  1712 
       
  1713     if k = gtExplosives then
       
  1714         begin
       
  1715         //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
       
  1716         if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then
       
  1717             begin
       
  1718             Gear^.doStep := @doStepRollingBarrel;
       
  1719             exit;
       
  1720             end
       
  1721         else Gear^.dX:= _0;
       
  1722 
       
  1723         if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
       
  1724             if (cBarrelHealth div Gear^.Health) > 2 then
       
  1725                 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
       
  1726             else
       
  1727                 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
       
  1728         dec(Gear^.Health, Gear^.Damage);
       
  1729         Gear^.Damage := 0;
       
  1730         end
       
  1731     else
       
  1732         begin
       
  1733         if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
       
  1734             begin
       
  1735             gi := GearsList;
       
  1736             while gi <> nil do
       
  1737                 begin
       
  1738                 if gi^.Kind = gtGenericFaller then
       
  1739                     begin
       
  1740                     gi^.Active:= true;
       
  1741                     gi^.X:=  int2hwFloat(GetRandom(rightX-leftX)+leftX);
       
  1742                     gi^.Y:=  int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
       
  1743                     gi^.dX:= _90-(GetRandomf*_360);
       
  1744                     gi^.dY:= _90-(GetRandomf*_360)
       
  1745                     end;
       
  1746                 gi := gi^.NextGear
       
  1747                 end
       
  1748             end;
       
  1749 
       
  1750         if Gear^.Timer = 500 then
       
  1751             begin
       
  1752 (* Can't make sparkles team coloured without working out what the next team is going to be. This should be solved, really, since it also screws up
       
  1753    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
       
  1754    has its own complexities. *)
       
  1755             // Abuse a couple of gear values to track origin
       
  1756             Gear^.Angle:= hwRound(Gear^.Y);
       
  1757             Gear^.Tag:= random(2);
       
  1758             inc(Gear^.Timer)
       
  1759             end;
       
  1760         if Gear^.Timer < 1833 then inc(Gear^.Timer);
       
  1761         if Gear^.Timer = 1000 then
       
  1762             begin
       
  1763             sparkles:= AddVisualGear(hwRound(Gear^.X), Gear^.Angle, vgtDust, 1);
       
  1764             if sparkles <> nil then
       
  1765                 begin
       
  1766                 sparkles^.dX:= 0;
       
  1767                 sparkles^.dY:= 0;
       
  1768                 sparkles^.Angle:= 270;
       
  1769                 if Gear^.Tag = 1 then
       
  1770                     sparkles^.Tint:= $3744D7FF
       
  1771                 else sparkles^.Tint:= $FAB22CFF
       
  1772                 end;
       
  1773             end;
       
  1774         if Gear^.Timer < 1000 then
       
  1775             begin
       
  1776             AllInactive:= false;
       
  1777             exit
       
  1778             end
       
  1779         end;
       
  1780 
  1782 
  1781 
  1783     if (Gear^.dY.QWordValue <> 0)
  1782     if (Gear^.dY.QWordValue <> 0)
  1784     or (TestCollisionYwithGear(Gear, 1) = 0) then
  1783     or (TestCollisionYwithGear(Gear, 1) = 0) then
  1785         begin
  1784         begin
  1786         AllInactive := false;
  1785         AllInactive := false;
  2430 ////////////////////////////////////////////////////////////////////////////////
  2429 ////////////////////////////////////////////////////////////////////////////////
  2431 procedure doStepMortar(Gear: PGear);
  2430 procedure doStepMortar(Gear: PGear);
  2432 var
  2431 var
  2433     dX, dY, gdX, gdY: hwFloat;
  2432     dX, dY, gdX, gdY: hwFloat;
  2434     i: LongInt;
  2433     i: LongInt;
  2435     dxn, dyn: boolean;
       
  2436 begin
  2434 begin
  2437     AllInactive := false;
  2435     AllInactive := false;
  2438     dxn := Gear^.dX.isNegative;
  2436     gdX := Gear^.dX;
  2439     dyn := Gear^.dY.isNegative;
  2437     gdY := Gear^.dY;
  2440 
  2438 
  2441     doStepFallingGear(Gear);
  2439     doStepFallingGear(Gear);
  2442     if (Gear^.State and gstCollision) <> 0 then
  2440     if (Gear^.State and gstCollision) <> 0 then
  2443         begin
  2441         begin
  2444         gdX := Gear^.dX;
       
  2445         gdY := Gear^.dY;
       
  2446         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
  2442         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
  2447 
  2443         gdX.isNegative := not gdX.isNegative;
  2448         gdX.isNegative := not dxn;
  2444         gdY.isNegative := not gdY.isNegative;
  2449         gdY.isNegative := not dyn;
  2445         gdX:= gdX*_0_2;
       
  2446         gdY:= gdY*_0_2;
       
  2447 
  2450         for i:= 0 to 4 do
  2448         for i:= 0 to 4 do
  2451             begin
  2449             begin
  2452             dX := gdX + (GetRandomf - _0_5) * _0_03;
  2450             dX := gdX + rndSign(GetRandomf) * _0_03;
  2453             dY := gdY + (GetRandomf - _0_5) * _0_03;
  2451             dY := gdY + rndSign(GetRandomf) * _0_03;
  2454             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
  2452             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
  2455             end;
  2453             end;
  2456 
  2454 
  2457         DeleteGear(Gear);
  2455         DeleteGear(Gear);
  2458         exit
  2456         exit
  2459         end;
  2457         end;
  2460 
  2458 
  2461     if (GameTicks and $3F) = 0 then
  2459     if (GameTicks and $3F) = 0 then
  2462         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
  2460         begin
       
  2461         if hwRound(Gear^.Y) > cWaterLine then
       
  2462              AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
       
  2463         else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
       
  2464         end
  2463 end;
  2465 end;
  2464 
  2466 
  2465 ////////////////////////////////////////////////////////////////////////////////
  2467 ////////////////////////////////////////////////////////////////////////////////
  2466 procedure doStepKamikazeWork(Gear: PGear);
  2468 procedure doStepKamikazeWork(Gear: PGear);
  2467 var
  2469 var
  2765 
  2767 
  2766 ////////////////////////////////////////////////////////////////////////////////
  2768 ////////////////////////////////////////////////////////////////////////////////
  2767 procedure doStepSeductionWork(Gear: PGear);
  2769 procedure doStepSeductionWork(Gear: PGear);
  2768 var i: LongInt;
  2770 var i: LongInt;
  2769     hogs: PGearArrayS;
  2771     hogs: PGearArrayS;
  2770     len: Integer;
       
  2771 begin
  2772 begin
  2772     AllInactive := false;
  2773     AllInactive := false;
  2773     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
  2774     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
  2774     if hogs.size > 0 then
  2775     if hogs.size > 0 then
  2775         begin
  2776         begin
  2958     oldDy := Gear^.dY;
  2959     oldDy := Gear^.dY;
  2959 
  2960 
  2960     doStepFallingGear(Gear);
  2961     doStepFallingGear(Gear);
  2961 
  2962 
  2962     if (GameTicks and $3F) = 0 then
  2963     if (GameTicks and $3F) = 0 then
  2963         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  2964         begin
       
  2965         if hwRound(Gear^.Y) > cWaterLine then
       
  2966              AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
       
  2967         else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
       
  2968         end;
  2964 
  2969 
  2965     if ((Gear^.State and gstCollision) <> 0) then
  2970     if ((Gear^.State and gstCollision) <> 0) then
  2966         begin
  2971         begin
  2967         //hit
  2972         //hit
  2968         Gear^.dX := oldDx;
  2973         Gear^.dX := oldDx;
  3208 (*if (HHGear^.Message and gmPrecise) <> 0 then
  3213 (*if (HHGear^.Message and gmPrecise) <> 0 then
  3209     begin
  3214     begin
  3210     move:= _0_02;
  3215     move:= _0_02;
  3211     fuel:= 5;
  3216     fuel:= 5;
  3212     end;*)
  3217     end;*)
  3213 
  3218     if HHGear^.Message and gmPrecise <> 0 then
  3214     if Gear^.Health > 0 then
  3219         HedgehogChAngle(HHGear)
  3215         begin
  3220     else if Gear^.Health > 0 then
  3216         if (HHGear^.Message and gmUp) <> 0 then
  3221         begin
       
  3222         if HHGear^.Message and gmUp <> 0 then
  3217             begin
  3223             begin
  3218             if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  3224             if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  3219                 begin
  3225                 begin
  3220                 if isUnderwater then
  3226                 if isUnderwater then
  3221                     begin
  3227                     begin
  3278         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3284         //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate);
  3279         FreeTexture(Gear^.Tex);
  3285         FreeTexture(Gear^.Tex);
  3280         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3286         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
  3281         end;
  3287         end;
  3282 
  3288 
  3283     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3289     if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and
       
  3290        (HHGear^.Message and gmPrecise = 0) then
  3284         Gear^.State := Gear^.State and (not gsttmpFlag);
  3291         Gear^.State := Gear^.State and (not gsttmpFlag);
  3285 
  3292 
  3286     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3293     if HHGear^.Message and gmPrecise = 0 then
       
  3294         HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight));
  3287     HHGear^.State := HHGear^.State or gstMoving;
  3295     HHGear^.State := HHGear^.State or gstMoving;
  3288 
  3296 
  3289     Gear^.X := HHGear^.X;
  3297     Gear^.X := HHGear^.X;
  3290     Gear^.Y := HHGear^.Y;
  3298     Gear^.Y := HHGear^.Y;
  3291 
  3299 
  3298         doStepHedgehogMoving(HHGear);
  3306         doStepHedgehogMoving(HHGear);
  3299 
  3307 
  3300     if // (Gear^.Health = 0)
  3308     if // (Gear^.Health = 0)
  3301         (HHGear^.Damage <> 0)
  3309         (HHGear^.Damage <> 0)
  3302         //or CheckGearDrowning(HHGear)
  3310         //or CheckGearDrowning(HHGear)
  3303         or (cWaterLine + 512 < hwRound(HHGear^.Y))
  3311         or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
  3304         or (TurnTimeLeft = 0)
  3312         or (TurnTimeLeft = 0)
  3305         // allow brief ground touches - to be fair on this, might need another counter
  3313         // allow brief ground touches - to be fair on this, might need another counter
  3306         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3314         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3307         or ((Gear^.Message and gmAttack) <> 0) then
  3315         or ((Gear^.Message and gmAttack) <> 0) then
  3308             begin
  3316             begin
  3699         if (not (isbullet or iscake)) then
  3707         if (not (isbullet or iscake)) then
  3700             begin
  3708             begin
  3701             // wow! good candidate there, let's see if the distance and direction is okay!
  3709             // wow! good candidate there, let's see if the distance and direction is okay!
  3702             if hasdxy then
  3710             if hasdxy then
  3703                 begin
  3711                 begin
  3704                 s := r / Distance(iterator^.dX, iterator^.dY);
  3712                 s := Distance(iterator^.dX, iterator^.dY);
       
  3713                 // if the resulting distance is 0 skip this gear
       
  3714                 if s.QWordValue = 0 then
       
  3715                     continue;
       
  3716                 s := r / s;
  3705                 ox:= iterator^.X + s * iterator^.dX;
  3717                 ox:= iterator^.X + s * iterator^.dX;
  3706                 oy:= iterator^.Y + s * iterator^.dY;
  3718                 oy:= iterator^.Y + s * iterator^.dY;
  3707                 end
  3719                 end
  3708             else
  3720             else
  3709                 begin
  3721                 begin
  4648 var
  4660 var
  4649     graves: PGearArrayS;
  4661     graves: PGearArrayS;
  4650     resgear: PGear;
  4662     resgear: PGear;
  4651     hh: PHedgehog;
  4663     hh: PHedgehog;
  4652     i: LongInt;
  4664     i: LongInt;
  4653     len: Integer;
       
  4654 begin
  4665 begin
  4655     if (TurnTimeLeft > 0) then
  4666     if (TurnTimeLeft > 0) then
  4656         dec(TurnTimeLeft);
  4667         dec(TurnTimeLeft);
  4657 
  4668 
  4658     AllInactive := false;
  4669     AllInactive := false;
  4741 procedure doStepResurrector(Gear: PGear);
  4752 procedure doStepResurrector(Gear: PGear);
  4742 var
  4753 var
  4743     graves: PGearArrayS;
  4754     graves: PGearArrayS;
  4744     hh: PHedgehog;
  4755     hh: PHedgehog;
  4745     i: LongInt;
  4756     i: LongInt;
  4746     len: Integer;
       
  4747 begin
  4757 begin
  4748     AllInactive := false;
  4758     AllInactive := false;
  4749     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
  4759     graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius);
  4750 
  4760 
  4751     if graves.size > 0 then
  4761     if graves.size > 0 then
  5091     Gear^.Damage:= t;
  5101     Gear^.Damage:= t;
  5092     FreeTexture(Gear^.Tex);
  5102     FreeTexture(Gear^.Tex);
  5093     Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
  5103     Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
  5094               '%', cWhiteColor, fntSmall)
  5104               '%', cWhiteColor, fntSmall)
  5095     end;
  5105     end;
  5096     if GameTicks mod 10 = 0 then dec(Gear^.Health);
  5106     if Gear^.Message and (gmUp or gmDown) <> 0 then
       
  5107         begin
       
  5108         StopSoundChan(Gear^.SoundChannel);
       
  5109         Gear^.SoundChannel:= -1;
       
  5110         if GameTicks mod 40 = 0 then dec(Gear^.Health)
       
  5111         end
       
  5112     else 
       
  5113         begin
       
  5114         if Gear^.SoundChannel = -1 then
       
  5115             Gear^.SoundChannel := LoopSound(sndIceBeam);
       
  5116         if GameTicks mod 10 = 0 then dec(Gear^.Health)
       
  5117         end
  5097 end;
  5118 end;
  5098 
  5119 
  5099 
  5120 
  5100 procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
  5121 procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
  5101 //    var
  5122 //    var
  5108     Pos:= 0;
  5129     Pos:= 0;
  5109     Target.X:= NoPointX;
  5130     Target.X:= NoPointX;
  5110     LastDamage:= nil;
  5131     LastDamage:= nil;
  5111     X:= Hedgehog^.Gear^.X;
  5132     X:= Hedgehog^.Gear^.X;
  5112     Y:= Hedgehog^.Gear^.Y;
  5133     Y:= Hedgehog^.Gear^.Y;
  5113     //unfreeze all semifrozen hogs - make this generic hog cleanup
       
  5114 (*
       
  5115     iter := GearsList;
       
  5116     while iter <> nil do
       
  5117         begin
       
  5118         if (iter^.Kind = gtHedgehog) and
       
  5119         (iter^.Hedgehog^.Effects[heFrozen] and $FF = 0) then
       
  5120         iter^.Hedgehog^.Effects[heFrozen]:= 0;
       
  5121         iter:= iter^.NextGear
       
  5122         end
       
  5123 *)
       
  5124   end;
  5134   end;
  5125 end;
  5135 end;
  5126 
  5136 
  5127 procedure doStepIceGun(Gear: PGear);
  5137 procedure doStepIceGun(Gear: PGear);
  5128 const iceWaitCollision:Longint = 0;
  5138 const iceWaitCollision:Longint = 0;
  5133 //const waterFreezingTime:Longint = 500;
  5143 //const waterFreezingTime:Longint = 500;
  5134 const groundFreezingTime:Longint = 1000;
  5144 const groundFreezingTime:Longint = 1000;
  5135 const iceRadius = 32;
  5145 const iceRadius = 32;
  5136 const iceHeight = 40;
  5146 const iceHeight = 40;
  5137 var
  5147 var
  5138     HHGear: PGear;
  5148     HHGear, iter: PGear;
  5139     landRect: TSDL_Rect;
  5149     landRect: TSDL_Rect;
  5140     ndX, ndY: hwFloat;
  5150     ndX, ndY: hwFloat;
  5141     i, t, gX, gY: LongInt;
  5151     i, j, t, gX, gY: LongInt;
  5142     hogs: PGearArrayS;
  5152     hogs: PGearArrayS;
  5143     len: Integer;
  5153     vg: PVisualGear;
  5144 begin
  5154 begin
  5145     HHGear := Gear^.Hedgehog^.Gear;
  5155     HHGear := Gear^.Hedgehog^.Gear;
  5146     if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
  5156     if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) or (HHGear^.dX.QWordValue > 4294967)  then
  5147         begin
  5157         begin
       
  5158         StopSoundChan(Gear^.SoundChannel);
  5148         DeleteGear(Gear);
  5159         DeleteGear(Gear);
  5149         AfterAttack;
  5160         AfterAttack;
  5150         exit
  5161         exit
  5151         end
  5162         end;
  5152     else if Gear^.Message and (gmUp or gmDown) = 0 then updateFuel(Gear);
  5163     updateFuel(Gear);
  5153 
  5164 
  5154     with Gear^ do
  5165     with Gear^ do
  5155         begin
  5166         begin
  5156         HedgehogChAngle(HHGear);
  5167         HedgehogChAngle(HHGear);
  5157         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5168         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
  5171             gY:= hwRound(Y);
  5182             gY:= hwRound(Y);
  5172             if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
  5183             if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
  5173 
  5184 
  5174             if Target.X <> NoPointX then
  5185             if Target.X <> NoPointX then
  5175                 begin
  5186                 begin
  5176                 CheckCollisionWithLand(Gear);
  5187                 CheckCollision(Gear);
  5177                 if (State and gstCollision) <> 0 then
  5188                 if (State and gstCollision) <> 0 then
  5178                     begin
  5189                     begin
  5179                     if Timer = iceWaitCollision then
  5190                     if Timer = iceWaitCollision then
  5180                         begin
  5191                         begin
  5181                         Timer := iceCollideWithGround;
  5192                         Timer := iceCollideWithGround;
  5203                     landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
  5214                     landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
  5204                     landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
  5215                     landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
  5205                     landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
  5216                     landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
  5206                     landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
  5217                     landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
  5207                     UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
  5218                     UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
       
  5219                     
       
  5220                     // Freeze nearby mines/explosives/cases too
       
  5221                     iter := GearsList;
       
  5222                     while iter <> nil do
       
  5223                         begin
       
  5224                         if (iter^.State and gstFrozen = 0) and
       
  5225                            ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and 
       
  5226                            (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y))<int2hwFloat(iceRadius*2)) then
       
  5227                             begin
       
  5228                             for t:= 0 to 5 do
       
  5229                                 begin
       
  5230                                 vg:= AddVisualGear(hwRound(iter^.X)+random(4)-8, hwRound(iter^.Y)+random(8), vgtDust, 1);
       
  5231                                 if vg <> nil then
       
  5232                                     begin
       
  5233                                     i:= random(100) + 155;
       
  5234                                     vg^.Tint:= i shl 24 or i shl 16 or $FF shl 8 or Longword(random(200) + 55);
       
  5235                                     vg^.Angle:= random(360);
       
  5236                                     vg^.dx:= 0.001 * random(80);
       
  5237                                     vg^.dy:= 0.001 * random(80)
       
  5238                                     end
       
  5239                                 end;
       
  5240                             PlaySound(sndHogFreeze);
       
  5241                             iter^.State:= iter^.State or gstFrozen;
       
  5242                             if iter^.Kind = gtMine then // dud mine block
       
  5243                                 begin
       
  5244                                 vg:= AddVisualGear(hwRound(iter^.X) - 4  + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke);
       
  5245                                 if vg <> nil then
       
  5246                                     vg^.Scale:= 0.5;
       
  5247                                 PlaySound(sndVaporize);
       
  5248                                 iter^.Health := 0;
       
  5249                                 iter^.Damage := 0;
       
  5250                                 iter^.State := iter^.State and (not gstAttacking)
       
  5251                                 end
       
  5252                             else if iter^.Kind = gtCase then
       
  5253                                 begin
       
  5254                                 DeleteCI(iter);
       
  5255                                 AddGearCI(iter)
       
  5256                                 end
       
  5257                             else // gtExplosives
       
  5258                                 iter^.Health:= iter^.Health + cBarrelHealth
       
  5259                             end;
       
  5260                         iter:= iter^.NextGear
       
  5261                         end;
  5208 
  5262 
  5209                     // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
  5263                     // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
  5210                     SetAllHHToActive(true);
  5264                     SetAllHHToActive(true);
  5211                     Timer := iceWaitCollision;
  5265                     Timer := iceWaitCollision;
  5212                     end;
  5266                     end;
  5213 
  5267 
  5214                 if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
  5268                 if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
  5215                     begin
  5269                     begin
       
  5270                     PlaySound(sndHogFreeze);
  5216                     DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
  5271                     DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
  5217                     SetAllHHToActive(true);
  5272                     SetAllHHToActive(true);
  5218                     Timer := iceWaitCollision;
  5273                     Timer := iceWaitCollision;
  5219                     end;
  5274                     end;
       
  5275 (*
       
  5276  Any ideas for something that would look good here?
       
  5277                 if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then
       
  5278                     begin
       
  5279                         vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1);
       
  5280                         if vg <> nil then
       
  5281                             begin
       
  5282                             i:= random(100) + 155;
       
  5283                             vg^.Tint:= IceColor or $FF;
       
  5284                             vg^.Angle:= random(360);
       
  5285                             vg^.dx:= 0.001 * random(80);
       
  5286                             vg^.dy:= 0.001 * random(80)
       
  5287                             end
       
  5288                     end;
       
  5289 *)
  5220 
  5290 
  5221 // freeze nearby hogs
  5291 // freeze nearby hogs
  5222                 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
  5292                 hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
  5223                 if hogs.size > 0 then
  5293                 if hogs.size > 0 then
  5224                     for i:= 0 to hogs.size - 1 do
  5294                     for i:= 0 to hogs.size - 1 do
  5227                                 begin
  5297                                 begin
  5228                                 hogs.ar^[i]^.Active:= true;
  5298                                 hogs.ar^[i]^.Active:= true;
  5229                                 if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
  5299                                 if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
  5230                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
  5300                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
  5231                                 else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
  5301                                 else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
  5232                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000;//cHedgehogTurnTime + cReadyDelay
  5302                                     begin
       
  5303                                     hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000-1;//cHedgehogTurnTime + cReadyDelay
       
  5304                                     PlaySound(sndHogFreeze);
       
  5305                                     end;
  5233                                 end;
  5306                                 end;
  5234                 inc(Pos)
  5307                 inc(Pos)
  5235                 end
  5308                 end
  5236             else if (t > 400) and ((gY > cWaterLine) or
  5309             else if (t > 400) and ((gY > cWaterLine) or
  5237                     (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
  5310                     (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
  5240                 Target.X:= gX;
  5313                 Target.X:= gX;
  5241                 Target.Y:= gY;
  5314                 Target.Y:= gY;
  5242                 X:= HHGear^.X;
  5315                 X:= HHGear^.X;
  5243                 Y:= HHGear^.Y
  5316                 Y:= HHGear^.Y
  5244                 end;
  5317                 end;
  5245             {if (gX > max(LAND_WIDTH,4096)*2) or
  5318             if (gX > max(LAND_WIDTH,4096)*2) or
  5246                     (gX < -max(LAND_WIDTH,4096)) or
  5319                     (gX < -max(LAND_WIDTH,4096)) or
  5247                     (gY < -max(LAND_HEIGHT,4096)) or
  5320                     (gY < -max(LAND_HEIGHT,4096)) or
  5248                     (gY > max(LAND_HEIGHT,4096)+512) then
  5321                     (gY > max(LAND_HEIGHT,4096)+512) then
  5249             begin
  5322                 begin
  5250                 X:= HHGear^.X;
  5323                 //X:= HHGear^.X;
  5251                 Y:= HHGear^.Y
  5324                 //Y:= HHGear^.Y
  5252             end}
  5325                 Target.X:= gX;
       
  5326                 Target.Y:= gY;
       
  5327                 end
  5253         end
  5328         end
  5254     end;
  5329     end;
  5255 end;
  5330 end;
  5256 
  5331 
  5257 procedure doStepAddAmmo(Gear: PGear);
  5332 procedure doStepAddAmmo(Gear: PGear);