hedgewars/GSHandlers.inc
changeset 3894 9abce5468583
parent 3852 37f883cc7edb
child 3907 5b516f0d9957
equal deleted inserted replaced
3892:60d9709f2d8e 3894:9abce5468583
   755         cLaserSighting := true;
   755         cLaserSighting := true;
   756         HHGear^.Message := 0;
   756         HHGear^.Message := 0;
   757         if (HHGear^.Angle - 32 >= 0) then dec(HHGear^.Angle,32)
   757         if (HHGear^.Angle - 32 >= 0) then dec(HHGear^.Angle,32)
   758     end;
   758     end;
   759 
   759 
   760     if (HHGear^.Message and gm_Attack) <> 0 then
   760     if (HHGear^.Message and gmAttack) <> 0 then
   761     begin
   761     begin
   762         shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
   762         shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell);
   763         if shell <> nil then
   763         if shell <> nil then
   764         begin
   764         begin
   765             shell^.dX := gear^.dX.QWordValue / -8589934592;
   765             shell^.dX := gear^.dX.QWordValue / -8589934592;
   839     HHGear: PGear;
   839     HHGear: PGear;
   840 begin
   840 begin
   841     AllInactive := false;
   841     AllInactive := false;
   842     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
   842     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
   843     dec(Gear^.Timer);
   843     dec(Gear^.Timer);
   844     if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) =
   844     if (Gear^.Timer = 0)or((Gear^.Message and gmDestroy) <> 0)or((HHGear^.State and gstHHDriven) =
   845        0) then
   845        0) then
   846     begin
   846     begin
   847         StopSound(Gear^.SoundChannel);
   847         StopSound(Gear^.SoundChannel);
   848         DeleteGear(Gear);
   848         DeleteGear(Gear);
   849         AfterAttack;
   849         AfterAttack;
   892 
   892 
   893     Gear^.X := Gear^.X + HHGear^.dX;
   893     Gear^.X := Gear^.X + HHGear^.dX;
   894     HHGear^.X := Gear^.X;
   894     HHGear^.X := Gear^.X;
   895     HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius);
   895     HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius);
   896 
   896 
   897     if (Gear^.Message and gm_Attack) <> 0 then
   897     if (Gear^.Message and gmAttack) <> 0 then
   898         if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1
   898         if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1
   899     else
   899     else
   900     else
   900     else
   901         if (Gear^.State and gsttmpFlag) = 0 then Gear^.State := Gear^.State or gsttmpFlag;
   901         if (Gear^.State and gsttmpFlag) = 0 then Gear^.State := Gear^.State or gsttmpFlag;
   902     if ((Gear^.Message and gm_Left) <> 0) then Gear^.dX := - _0_3
   902     if ((Gear^.Message and gmLeft) <> 0) then Gear^.dX := - _0_3
   903     else
   903     else
   904         if ((Gear^.Message and gm_Right) <> 0) then Gear^.dX := _0_3
   904         if ((Gear^.Message and gmRight) <> 0) then Gear^.dX := _0_3
   905     else Gear^.dX := _0;
   905     else Gear^.dX := _0;
   906 end;
   906 end;
   907 
   907 
   908 procedure doStepPickHammer(Gear: PGear);
   908 procedure doStepPickHammer(Gear: PGear);
   909 var 
   909 var 
   966 
   966 
   967     if Gear^.Timer mod cHHStepTicks = 0 then
   967     if Gear^.Timer mod cHHStepTicks = 0 then
   968     begin
   968     begin
   969         b := true;
   969         b := true;
   970         if Gear^.dX.isNegative then
   970         if Gear^.dX.isNegative then
   971             HHGear^.Message := (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left
   971             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmLeft
   972         else
   972         else
   973             HHGear^.Message := (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right;
   973             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
   974 
   974 
   975         if ((HHGear^.State and gstMoving) = 0) then
   975         if ((HHGear^.State and gstMoving) = 0) then
   976         begin
   976         begin
   977             HHGear^.State := HHGear^.State and not gstAttacking;
   977             HHGear^.State := HHGear^.State and not gstAttacking;
   978             prevX := hwRound(HHGear^.X);
   978             prevX := hwRound(HHGear^.X);
  1009         DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(
  1009         DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(
  1010                    Gear^.dY) * 7,
  1010                    Gear^.dY) * 7,
  1011         Gear^.dX, Gear^.dY,
  1011         Gear^.dX, Gear^.dY,
  1012         cHHRadius * 5, cHHRadius * 2 + 7);
  1012         cHHRadius * 5, cHHRadius * 2 + 7);
  1013 
  1013 
  1014     if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then
  1014     if (Gear^.Timer = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  1015     begin
  1015     begin
  1016         HHGear^.Message := 0;
  1016         HHGear^.Message := 0;
  1017         HHGear^.State := HHGear^.State and (not gstNotKickable);
  1017         HHGear^.State := HHGear^.State and (not gstNotKickable);
  1018         DeleteGear(Gear);
  1018         DeleteGear(Gear);
  1019         AfterAttack
  1019         AfterAttack
  1059     if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0;
  1059     if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY := _0;
  1060     HHGear^.X := HHGear^.X + HHGear^.dX;
  1060     HHGear^.X := HHGear^.X + HHGear^.dX;
  1061     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1061     HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1062     HHGear^.dY := HHGear^.dY + cGravity;
  1062     HHGear^.dY := HHGear^.dY + cGravity;
  1063 
  1063 
  1064     if (Gear^.Message and gm_Attack) <> 0 then
  1064     if (Gear^.Message and gmAttack) <> 0 then
  1065     begin
  1065     begin
  1066         Gear^.X := HHGear^.X;
  1066         Gear^.X := HHGear^.X;
  1067         Gear^.Y := HHGear^.Y;
  1067         Gear^.Y := HHGear^.Y;
  1068 
  1068 
  1069         ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope);
  1069         ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope);
  1087 
  1087 
  1088 procedure DeleteMe;
  1088 procedure DeleteMe;
  1089 begin
  1089 begin
  1090     with HHGear^ do
  1090     with HHGear^ do
  1091     begin
  1091     begin
  1092         Message := Message and not gm_Attack;
  1092         Message := Message and not gmAttack;
  1093         State := (State or gstMoving) and not gstWinner;
  1093         State := (State or gstMoving) and not gstWinner;
  1094     end;
  1094     end;
  1095     DeleteGear(Gear)
  1095     DeleteGear(Gear)
  1096 end;
  1096 end;
  1097 
  1097 
  1098 procedure WaitCollision;
  1098 procedure WaitCollision;
  1099 begin
  1099 begin
  1100     with HHGear^ do
  1100     with HHGear^ do
  1101     begin
  1101     begin
  1102         Message := Message and not gm_Attack;
  1102         Message := Message and not gmAttack;
  1103         State := State or gstMoving;
  1103         State := State or gstMoving;
  1104     end;
  1104     end;
  1105     RopePoints.Count := 0;
  1105     RopePoints.Count := 0;
  1106     Gear^.Elasticity := _0;
  1106     Gear^.Elasticity := _0;
  1107     Gear^.doStep := @doStepRopeAfterAttack
  1107     Gear^.doStep := @doStepRopeAfterAttack
  1116         PlaySound(sndRopeRelease);
  1116         PlaySound(sndRopeRelease);
  1117         DeleteMe;
  1117         DeleteMe;
  1118         exit
  1118         exit
  1119     end;
  1119     end;
  1120 
  1120 
  1121     if (Gear^.Message and gm_Left  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1121     if (Gear^.Message and gmLeft  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1122     else
  1122     else
  1123         if (Gear^.Message and gm_Right <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1123         if (Gear^.Message and gmRight <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1124 
  1124 
  1125     if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY := HHGear^.dY + cGravity;
  1125     if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY := HHGear^.dY + cGravity;
  1126 
  1126 
  1127     ropeDx := HHGear^.X - Gear^.X;
  1127     ropeDx := HHGear^.X - Gear^.X;
  1128     // vector between hedgehog and rope attaching point
  1128     // vector between hedgehog and rope attaching point
  1141 
  1141 
  1142     /////
  1142     /////
  1143     tx := HHGear^.X;
  1143     tx := HHGear^.X;
  1144     ty := HHGear^.Y;
  1144     ty := HHGear^.Y;
  1145 
  1145 
  1146     if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
  1146     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
  1147         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
  1147         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
  1148            or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then
  1148            or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then
  1149             Gear^.Elasticity := Gear^.Elasticity + _0_3;
  1149             Gear^.Elasticity := Gear^.Elasticity + _0_3;
  1150 
  1150 
  1151     if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then
  1151     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
  1152         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
  1152         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
  1153            or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then
  1153            or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then
  1154             Gear^.Elasticity := Gear^.Elasticity - _0_3;
  1154             Gear^.Elasticity := Gear^.Elasticity - _0_3;
  1155 
  1155 
  1156     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
  1156     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
  1248         HHGear^.dY := -_0_6 * HHGear^.dY;
  1248         HHGear^.dY := -_0_6 * HHGear^.dY;
  1249         haveCollision := true
  1249         haveCollision := true
  1250     end;
  1250     end;
  1251 
  1251 
  1252     if haveCollision
  1252     if haveCollision
  1253        and (Gear^.Message and (gm_Left or gm_Right) <> 0)
  1253        and (Gear^.Message and (gmLeft or gmRight) <> 0)
  1254        and (Gear^.Message and (gm_Up or gm_Down) <> 0) then
  1254        and (Gear^.Message and (gmUp or gmDown) <> 0) then
  1255     begin
  1255     begin
  1256         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1256         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1257         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1257         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1258     end;
  1258     end;
  1259 
  1259 
  1264         HHGear^.dX := HHGear^.dX * len;
  1264         HHGear^.dX := HHGear^.dX * len;
  1265         HHGear^.dY := HHGear^.dY * len;
  1265         HHGear^.dY := HHGear^.dY * len;
  1266     end;
  1266     end;
  1267 
  1267 
  1268 
  1268 
  1269     if (Gear^.Message and gm_Attack) <> 0 then
  1269     if (Gear^.Message and gmAttack) <> 0 then
  1270         if (Gear^.State and gsttmpFlag) <> 0 then
  1270         if (Gear^.State and gsttmpFlag) <> 0 then
  1271             with PHedgehog(Gear^.Hedgehog)^ do
  1271             with PHedgehog(Gear^.Hedgehog)^ do
  1272             begin
  1272             begin
  1273                 PlaySound(sndRopeRelease);
  1273                 PlaySound(sndRopeRelease);
  1274                 if CurAmmoType <> amParachute then
  1274                 if CurAmmoType <> amParachute then
  1369 
  1369 
  1370         exit
  1370         exit
  1371     end;
  1371     end;
  1372 
  1372 
  1373     if (Gear^.Elasticity > Gear^.Friction)
  1373     if (Gear^.Elasticity > Gear^.Friction)
  1374        or ((Gear^.Message and gm_Attack) = 0)
  1374        or ((Gear^.Message and gmAttack) = 0)
  1375        or ((HHGear^.State and gstHHDriven) = 0)
  1375        or ((HHGear^.State and gstHHDriven) = 0)
  1376        or (HHGear^.Damage > 0) then
  1376        or (HHGear^.Damage > 0) then
  1377     begin
  1377     begin
  1378         with PHedgehog(Gear^.Hedgehog)^.Gear^ do
  1378         with PHedgehog(Gear^.Hedgehog)^.Gear^ do
  1379         begin
  1379         begin
  1380             State := State and not gstAttacking;
  1380             State := State and not gstAttacking;
  1381             Message := Message and not gm_Attack
  1381             Message := Message and not gmAttack
  1382         end;
  1382         end;
  1383         DeleteGear(Gear)
  1383         DeleteGear(Gear)
  1384     end
  1384     end
  1385 end;
  1385 end;
  1386 
  1386 
  1595     dX, dY: HWFloat;
  1595     dX, dY: HWFloat;
  1596 begin
  1596 begin
  1597     k := Gear^.Kind;
  1597     k := Gear^.Kind;
  1598     exBoom := false;
  1598     exBoom := false;
  1599 
  1599 
  1600     if (Gear^.Message and gm_Destroy) > 0 then
  1600     if (Gear^.Message and gmDestroy) > 0 then
  1601     begin
  1601     begin
  1602         DeleteGear(Gear);
  1602         DeleteGear(Gear);
  1603         FreeActionsList;
  1603         FreeActionsList;
  1604         SetAllToActive;
  1604         SetAllToActive;
  1605         // something (hh, mine, etc...) could be on top of the case
  1605         // something (hh, mine, etc...) could be on top of the case
  1606         with CurrentHedgehog^ do
  1606         with CurrentHedgehog^ do
  1607             if Gear <> nil then Gear^.Message := Gear^.Message and not (gm_LJump or gm_HJump);
  1607             if Gear <> nil then Gear^.Message := Gear^.Message and not (gmLJump or gmHJump);
  1608         exit
  1608         exit
  1609     end;
  1609     end;
  1610 
  1610 
  1611     if k = gtExplosives then
  1611     if k = gtExplosives then
  1612     begin
  1612     begin
  1896 procedure doStepFirePunchWork(Gear: PGear);
  1896 procedure doStepFirePunchWork(Gear: PGear);
  1897 var 
  1897 var 
  1898     HHGear: PGear;
  1898     HHGear: PGear;
  1899 begin
  1899 begin
  1900     AllInactive := false;
  1900     AllInactive := false;
  1901     if ((Gear^.Message and gm_Destroy) <> 0) then
  1901     if ((Gear^.Message and gmDestroy) <> 0) then
  1902     begin
  1902     begin
  1903         DeleteGear(Gear);
  1903         DeleteGear(Gear);
  1904         AfterAttack;
  1904         AfterAttack;
  1905         exit
  1905         exit
  1906     end;
  1906     end;
  1963     inc(Gear^.Timer);
  1963     inc(Gear^.Timer);
  1964 
  1964 
  1965     if TestCollisionYwithGear(HHGear, 1)
  1965     if TestCollisionYwithGear(HHGear, 1)
  1966        or ((HHGear^.State and gstHHDriven) = 0)
  1966        or ((HHGear^.State and gstHHDriven) = 0)
  1967        or CheckGearDrowning(HHGear)
  1967        or CheckGearDrowning(HHGear)
  1968        or ((Gear^.Message and gm_Attack) <> 0) then
  1968        or ((Gear^.Message and gmAttack) <> 0) then
  1969     begin
  1969     begin
  1970         with HHGear^ do
  1970         with HHGear^ do
  1971         begin
  1971         begin
  1972             Message := 0;
  1972             Message := 0;
  1973             SetLittle(dX);
  1973             SetLittle(dX);
  1981     end;
  1981     end;
  1982 
  1982 
  1983     if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1983     if not TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1984         HHGear^.X := HHGear^.X + cWindSpeed * 200;
  1984         HHGear^.X := HHGear^.X + cWindSpeed * 200;
  1985 
  1985 
  1986     if (Gear^.Message and gm_Left) <> 0 then HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  1986     if (Gear^.Message and gmLeft) <> 0 then HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
  1987     else if (Gear^.Message and gm_Right) <> 0 then HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  1987     else if (Gear^.Message and gmRight) <> 0 then HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
  1988     if (Gear^.Message and gm_Up) <> 0 then HHGear^.Y := HHGear^.Y - cGravity * 40
  1988     if (Gear^.Message and gmUp) <> 0 then HHGear^.Y := HHGear^.Y - cGravity * 40
  1989     else if (Gear^.Message and gm_Down) <> 0 then HHGear^.Y := HHGear^.Y + cGravity * 40;
  1989     else if (Gear^.Message and gmDown) <> 0 then HHGear^.Y := HHGear^.Y + cGravity * 40;
  1990 
  1990 
  1991     HHGear^.Y := HHGear^.Y + cGravity * 100;
  1991     HHGear^.Y := HHGear^.Y + cGravity * 100;
  1992     Gear^.X := HHGear^.X;
  1992     Gear^.X := HHGear^.X;
  1993     Gear^.Y := HHGear^.Y
  1993     Gear^.Y := HHGear^.Y
  1994 end;
  1994 end;
  2002     DeleteCI(HHGear);
  2002     DeleteCI(HHGear);
  2003 
  2003 
  2004     AfterAttack;
  2004     AfterAttack;
  2005 
  2005 
  2006     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked or gstMoving);
  2006     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked or gstMoving);
  2007     HHGear^.Message := HHGear^.Message and not gm_Attack;
  2007     HHGear^.Message := HHGear^.Message and not gmAttack;
  2008 
  2008 
  2009     Gear^.doStep := @doStepParachuteWork;
  2009     Gear^.doStep := @doStepParachuteWork;
  2010 
  2010 
  2011     Gear^.Message := HHGear^.Message;
  2011     Gear^.Message := HHGear^.Message;
  2012     doStepParachuteWork(Gear)
  2012     doStepParachuteWork(Gear)
  2102        not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2,
  2102        not TryPlaceOnLand(TargetPoint.X - SpritesData[sprAmGirder].Width div 2,
  2103        TargetPoint.Y - SpritesData[sprAmGirder].Height div 2,
  2103        TargetPoint.Y - SpritesData[sprAmGirder].Height div 2,
  2104        sprAmGirder, Gear^.State, true) then
  2104        sprAmGirder, Gear^.State, true) then
  2105     begin
  2105     begin
  2106         PlaySound(sndDenied);
  2106         PlaySound(sndDenied);
  2107         HHGear^.Message := HHGear^.Message and not gm_Attack;
  2107         HHGear^.Message := HHGear^.Message and not gmAttack;
  2108         HHGear^.State := HHGear^.State and not gstAttacking;
  2108         HHGear^.State := HHGear^.State and not gstAttacking;
  2109         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2109         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2110         isCursorVisible := true;
  2110         isCursorVisible := true;
  2111         DeleteGear(Gear)
  2111         DeleteGear(Gear)
  2112     end
  2112     end
  2116         DeleteGear(Gear);
  2116         DeleteGear(Gear);
  2117         AfterAttack;
  2117         AfterAttack;
  2118     end;
  2118     end;
  2119 
  2119 
  2120     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked);
  2120     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked);
  2121     HHGear^.Message := HHGear^.Message and not gm_Attack;
  2121     HHGear^.Message := HHGear^.Message and not gmAttack;
  2122     TargetPoint.X := NoPointX
  2122     TargetPoint.X := NoPointX
  2123 end;
  2123 end;
  2124 
  2124 
  2125 ////////////////////////////////////////////////////////////////////////////////
  2125 ////////////////////////////////////////////////////////////////////////////////
  2126 procedure doStepTeleportAfter(Gear: PGear);
  2126 procedure doStepTeleportAfter(Gear: PGear);
  2161     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2161     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2162     if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2,
  2162     if not TryPlaceOnLand(TargetPoint.X - SpritesData[sprHHTelepMask].Width div 2,
  2163        TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2,
  2163        TargetPoint.Y - SpritesData[sprHHTelepMask].Height div 2,
  2164        sprHHTelepMask, 0, false) then
  2164        sprHHTelepMask, 0, false) then
  2165     begin
  2165     begin
  2166         HHGear^.Message := HHGear^.Message and not gm_Attack;
  2166         HHGear^.Message := HHGear^.Message and not gmAttack;
  2167         HHGear^.State := HHGear^.State and not gstAttacking;
  2167         HHGear^.State := HHGear^.State and not gstAttacking;
  2168         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2168         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2169         DeleteGear(Gear);
  2169         DeleteGear(Gear);
  2170         isCursorVisible := true;
  2170         isCursorVisible := true;
  2171         PlaySound(sndDenied)
  2171         PlaySound(sndDenied)
  2196     HHGear: PGear;
  2196     HHGear: PGear;
  2197     Msg, State: Longword;
  2197     Msg, State: Longword;
  2198 begin
  2198 begin
  2199     AllInactive := false;
  2199     AllInactive := false;
  2200 
  2200 
  2201     if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then
  2201     if ((Gear^.Message and not gmSwitch) <> 0) or (TurnTimeLeft = 0) then
  2202     begin
  2202     begin
  2203         HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2203         HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2204         Msg := Gear^.Message and not gm_Switch;
  2204         Msg := Gear^.Message and not gmSwitch;
  2205         DeleteGear(Gear);
  2205         DeleteGear(Gear);
  2206         OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  2206         OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^);
  2207         ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2207         ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2208 
  2208 
  2209         HHGear := CurrentHedgehog^.Gear;
  2209         HHGear := CurrentHedgehog^.Gear;
  2210         ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2210         ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^);
  2211         HHGear^.Message := Msg;
  2211         HHGear^.Message := Msg;
  2212         exit
  2212         exit
  2213     end;
  2213     end;
  2214 
  2214 
  2215     if (Gear^.Message and gm_Switch) <> 0 then
  2215     if (Gear^.Message and gmSwitch) <> 0 then
  2216     begin
  2216     begin
  2217         HHGear := CurrentHedgehog^.Gear;
  2217         HHGear := CurrentHedgehog^.Gear;
  2218         HHGear^.Message := HHGear^.Message and not gm_Switch;
  2218         HHGear^.Message := HHGear^.Message and not gmSwitch;
  2219         Gear^.Message := Gear^.Message and not gm_Switch;
  2219         Gear^.Message := Gear^.Message and not gmSwitch;
  2220         State := HHGear^.State;
  2220         State := HHGear^.State;
  2221         HHGear^.State := 0;
  2221         HHGear^.State := 0;
  2222         HHGear^.Active := false;
  2222         HHGear^.Active := false;
  2223         HHGear^.Z := cHHZ;
  2223         HHGear^.Z := cHHZ;
  2224         RemoveGearFromList(HHGear);
  2224         RemoveGearFromList(HHGear);
  2253 
  2253 
  2254     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2254     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2255     with HHGear^ do
  2255     with HHGear^ do
  2256     begin
  2256     begin
  2257         State := State and not gstAttacking;
  2257         State := State and not gstAttacking;
  2258         Message := Message and not gm_Attack
  2258         Message := Message and not gmAttack
  2259     end
  2259     end
  2260 end;
  2260 end;
  2261 
  2261 
  2262 ////////////////////////////////////////////////////////////////////////////////
  2262 ////////////////////////////////////////////////////////////////////////////////
  2263 procedure doStepMortar(Gear: PGear);
  2263 procedure doStepMortar(Gear: PGear);
  2509 
  2509 
  2510     dec(Gear^.Health);
  2510     dec(Gear^.Health);
  2511     Gear^.Timer := Gear^.Health*10;
  2511     Gear^.Timer := Gear^.Health*10;
  2512     Gear^.PortalCounter:= 0;
  2512     Gear^.PortalCounter:= 0;
  2513     // This is not seconds, but at least it is *some* feedback
  2513     // This is not seconds, but at least it is *some* feedback
  2514     if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then
  2514     if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
  2515     begin
  2515     begin
  2516         FollowGear := Gear;
  2516         FollowGear := Gear;
  2517         Gear^.RenderTimer := false;
  2517         Gear^.RenderTimer := false;
  2518         Gear^.doStep := @doStepCakeDown
  2518         Gear^.doStep := @doStepCakeDown
  2519     end
  2519     end
  2561     HHGear: PGear;
  2561     HHGear: PGear;
  2562 begin
  2562 begin
  2563     AllInactive := false;
  2563     AllInactive := false;
  2564 
  2564 
  2565     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2565     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2566     HHGear^.Message := HHGear^.Message and (not gm_Attack);
  2566     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2567     DeleteCI(HHGear);
  2567     DeleteCI(HHGear);
  2568     Gear^.IntersectGear:= nil;
  2568     Gear^.IntersectGear:= nil;
  2569 
  2569 
  2570     FollowGear := Gear;
  2570     FollowGear := Gear;
  2571 
  2571 
  2774 procedure doStepBallgun(Gear: PGear);
  2774 procedure doStepBallgun(Gear: PGear);
  2775 var 
  2775 var 
  2776     HHGear: PGear;
  2776     HHGear: PGear;
  2777 begin
  2777 begin
  2778     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2778     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2779     HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Down);
  2779     HHGear^.Message := HHGear^.Message and not (gmUp or gmDown);
  2780     HHGear^.State := HHGear^.State or gstNotKickable;
  2780     HHGear^.State := HHGear^.State or gstNotKickable;
  2781     Gear^.doStep := @doStepBallgunWork
  2781     Gear^.doStep := @doStepBallgunWork
  2782 end;
  2782 end;
  2783 
  2783 
  2784 ////////////////////////////////////////////////////////////////////////////////
  2784 ////////////////////////////////////////////////////////////////////////////////
  2812             if Gear^.Angle < 2048 then inc(Gear^.Angle)
  2812             if Gear^.Angle < 2048 then inc(Gear^.Angle)
  2813         else fChanged := false
  2813         else fChanged := false
  2814     end
  2814     end
  2815     else
  2815     else
  2816     begin
  2816     begin
  2817         if ((Gear^.Message and gm_Left) <> 0) then
  2817         if ((Gear^.Message and gmLeft) <> 0) then
  2818         begin
  2818         begin
  2819             fChanged := true;
  2819             fChanged := true;
  2820             Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
  2820             Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096
  2821         end;
  2821         end;
  2822 
  2822 
  2823         if ((Gear^.Message and gm_Right) <> 0) then
  2823         if ((Gear^.Message and gmRight) <> 0) then
  2824         begin
  2824         begin
  2825             fChanged := true;
  2825             fChanged := true;
  2826             Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096
  2826             Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096
  2827         end
  2827         end
  2828     end;
  2828     end;
  2848             if Gear^.Timer < 3500 then
  2848             if Gear^.Timer < 3500 then
  2849                 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace)
  2849                 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace)
  2850         else
  2850         else
  2851             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  2851             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  2852 
  2852 
  2853         if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then
  2853         if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
  2854         begin
  2854         begin
  2855             HHGear^.Message := HHGear^.Message and not gm_Attack;
  2855             HHGear^.Message := HHGear^.Message and not gmAttack;
  2856             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
  2856             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
  2857             _0_5, 0);
  2857             _0_5, 0);
  2858             dec(Gear^.Health)
  2858             dec(Gear^.Health)
  2859         end;
  2859         end;
  2860 
  2860 
  2861         if ((HHGear^.Message and gm_LJump) <> 0)
  2861         if ((HHGear^.Message and gmLJump) <> 0)
  2862            and ((Gear^.State and gsttmpFlag) = 0) then
  2862            and ((Gear^.State and gsttmpFlag) = 0) then
  2863         begin
  2863         begin
  2864             Gear^.State := Gear^.State or gsttmpFlag;
  2864             Gear^.State := Gear^.State or gsttmpFlag;
  2865             PauseMusic;
  2865             PauseMusic;
  2866             playSound(sndRideOfTheValkyries);
  2866             playSound(sndRideOfTheValkyries);
  2954     AllInactive := false;
  2954     AllInactive := false;
  2955     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2955     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  2956     //dec(Gear^.Timer);
  2956     //dec(Gear^.Timer);
  2957     move := _0_1;
  2957     move := _0_1;
  2958     fuel := 50;
  2958     fuel := 50;
  2959 (*if (HHGear^.Message and gm_Precise) <> 0 then
  2959 (*if (HHGear^.Message and gmPrecise) <> 0 then
  2960     begin
  2960     begin
  2961     move:= _0_02;
  2961     move:= _0_02;
  2962     fuel:= 5;
  2962     fuel:= 5;
  2963     end;*)
  2963     end;*)
  2964 
  2964 
  2965     if (HHGear^.Message and gm_Up) <> 0 then
  2965     if (HHGear^.Message and gmUp) <> 0 then
  2966     begin
  2966     begin
  2967         if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  2967         if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  2968             HHGear^.dY := HHGear^.dY - move;
  2968             HHGear^.dY := HHGear^.dY - move;
  2969         HHGear^.dY := HHGear^.dY - move;
  2969         HHGear^.dY := HHGear^.dY - move;
  2970         dec(Gear^.Health, fuel);
  2970         dec(Gear^.Health, fuel);
  2971         Gear^.MsgParam := Gear^.MsgParam or gm_Up;
  2971         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  2972         Gear^.Timer := GameTicks
  2972         Gear^.Timer := GameTicks
  2973     end;
  2973     end;
  2974     if (HHGear^.Message and gm_Left) <> 0 then move.isNegative := true;
  2974     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  2975     if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then
  2975     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  2976     begin
  2976     begin
  2977         HHGear^.dX := HHGear^.dX + (move * _0_2);
  2977         HHGear^.dX := HHGear^.dX + (move * _0_2);
  2978         dec(Gear^.Health, fuel div 5);
  2978         dec(Gear^.Health, fuel div 5);
  2979         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right));
  2979         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  2980         Gear^.Timer := GameTicks
  2980         Gear^.Timer := GameTicks
  2981     end;
  2981     end;
  2982 
  2982 
  2983     // erases them all at once :-/
  2983     // erases them all at once :-/
  2984     if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then
  2984     if (Gear^.Timer <> 0) and (GameTicks - Gear^.Timer > 250) then
  2994         if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
  2994         if Gear^.Tex <> nil then FreeTexture(Gear^.Tex);
  2995         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) +
  2995         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) +
  2996                      '%', cWhiteColor, fntSmall)
  2996                      '%', cWhiteColor, fntSmall)
  2997     end;
  2997     end;
  2998 
  2998 
  2999     if HHGear^.Message and (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then Gear^
  2999     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then Gear^
  3000         .State := Gear^.State and not gsttmpFlag;
  3000         .State := Gear^.State and not gsttmpFlag;
  3001     HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right);
  3001     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3002     HHGear^.State := HHGear^.State or gstMoving;
  3002     HHGear^.State := HHGear^.State or gstMoving;
  3003 
  3003 
  3004     Gear^.X := HHGear^.X;
  3004     Gear^.X := HHGear^.X;
  3005     Gear^.Y := HHGear^.Y;
  3005     Gear^.Y := HHGear^.Y;
  3006     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3006     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3013        or CheckGearDrowning(HHGear)
  3013        or CheckGearDrowning(HHGear)
  3014        or (TurnTimeLeft = 0)
  3014        or (TurnTimeLeft = 0)
  3015        // allow brief ground touches - to be fair on this, might need another counter
  3015        // allow brief ground touches - to be fair on this, might need another counter
  3016        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3016        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3017        HHGear, 1))
  3017        HHGear, 1))
  3018        or ((Gear^.Message and gm_Attack) <> 0) then
  3018        or ((Gear^.Message and gmAttack) <> 0) then
  3019     begin
  3019     begin
  3020         with HHGear^ do
  3020         with HHGear^ do
  3021         begin
  3021         begin
  3022             Message := 0;
  3022             Message := 0;
  3023             Active := true;
  3023             Active := true;
  3045     FollowGear := HHGear;
  3045     FollowGear := HHGear;
  3046     AfterAttack;
  3046     AfterAttack;
  3047     with HHGear^ do
  3047     with HHGear^ do
  3048     begin
  3048     begin
  3049         State := State and not gstAttacking;
  3049         State := State and not gstAttacking;
  3050         Message := Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right);
  3050         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight);
  3051         if (dY < _0_1) and (dY > -_0_1) then
  3051         if (dY < _0_1) and (dY > -_0_1) then
  3052         begin
  3052         begin
  3053             Gear^.State := Gear^.State or gsttmpFlag;
  3053             Gear^.State := Gear^.State or gsttmpFlag;
  3054             dY := dY - _0_2
  3054             dY := dY - _0_2
  3055         end
  3055         end
  3081     move := _0_1;
  3081     move := _0_1;
  3082     fuel := 50;
  3082     fuel := 50;
  3083 
  3083 
  3084     if Gear^.Pos > 0 then
  3084     if Gear^.Pos > 0 then
  3085         dec(Gear^.Pos, 1)
  3085         dec(Gear^.Pos, 1)
  3086     else if (HHGear^.Message and (gm_Left or gm_Right or gm_Up)) <> 0 then
  3086     else if (HHGear^.Message and (gmLeft or gmRight or gmUp)) <> 0 then
  3087              Gear^.Pos := 500;
  3087              Gear^.Pos := 500;
  3088 
  3088 
  3089     if HHGear^.dX.isNegative then
  3089     if HHGear^.dX.isNegative then
  3090         Gear^.Tag := -1
  3090         Gear^.Tag := -1
  3091     else
  3091     else
  3092         Gear^.Tag := 1;
  3092         Gear^.Tag := 1;
  3093 
  3093 
  3094     if (HHGear^.Message and gm_Up) <> 0 then
  3094     if (HHGear^.Message and gmUp) <> 0 then
  3095     begin
  3095     begin
  3096         if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  3096         if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
  3097             HHGear^.dY := HHGear^.dY - move;
  3097             HHGear^.dY := HHGear^.dY - move;
  3098         HHGear^.dY := HHGear^.dY - move;
  3098         HHGear^.dY := HHGear^.dY - move;
  3099         dec(Gear^.Health, fuel);
  3099         dec(Gear^.Health, fuel);
  3100         Gear^.MsgParam := Gear^.MsgParam or gm_Up;
  3100         Gear^.MsgParam := Gear^.MsgParam or gmUp;
  3101     end;
  3101     end;
  3102     if (HHGear^.Message and gm_Left) <> 0 then move.isNegative := true;
  3102     if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
  3103     if (HHGear^.Message and (gm_Left or gm_Right)) <> 0 then
  3103     if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
  3104     begin
  3104     begin
  3105         HHGear^.dX := HHGear^.dX + (move * _0_2);
  3105         HHGear^.dX := HHGear^.dX + (move * _0_2);
  3106         dec(Gear^.Health, fuel div 5);
  3106         dec(Gear^.Health, fuel div 5);
  3107         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gm_Left or gm_Right));
  3107         Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight));
  3108     end;
  3108     end;
  3109 
  3109 
  3110     if Gear^.Health < 0 then Gear^.Health := 0;
  3110     if Gear^.Health < 0 then Gear^.Health := 0;
  3111     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3111     if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
  3112         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3112         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3113             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3113             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3114 
  3114 
  3115     if (HHGear^.Message and gm_Attack <> 0) then
  3115     if (HHGear^.Message and gmAttack <> 0) then
  3116     begin
  3116     begin
  3117         HHGear^.Message := HHGear^.Message and not gm_Attack;
  3117         HHGear^.Message := HHGear^.Message and not gmAttack;
  3118         if Gear^.FlightTime > 0 then
  3118         if Gear^.FlightTime > 0 then
  3119         begin
  3119         begin
  3120             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0)
  3120             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0)
  3121             ;
  3121             ;
  3122             PlaySound(sndBirdyLay);
  3122             PlaySound(sndBirdyLay);
  3123             dec(Gear^.FlightTime)
  3123             dec(Gear^.FlightTime)
  3124         end;
  3124         end;
  3125     end;
  3125     end;
  3126 
  3126 
  3127     if HHGear^.Message and (gm_Up or gm_Precise or gm_Left or gm_Right) <> 0 then 
  3127     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then 
  3128         Gear^.State := Gear^.State and not gsttmpFlag;
  3128         Gear^.State := Gear^.State and not gsttmpFlag;
  3129     HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right);
  3129     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3130     HHGear^.State := HHGear^.State or gstMoving;
  3130     HHGear^.State := HHGear^.State or gstMoving;
  3131 
  3131 
  3132     Gear^.X := HHGear^.X;
  3132     Gear^.X := HHGear^.X;
  3133     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3133     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3134     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3134     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3141        or CheckGearDrowning(HHGear)
  3141        or CheckGearDrowning(HHGear)
  3142        or (TurnTimeLeft = 0)
  3142        or (TurnTimeLeft = 0)
  3143        // allow brief ground touches - to be fair on this, might need another counter
  3143        // allow brief ground touches - to be fair on this, might need another counter
  3144        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3144        or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and TestCollisionYwithGear(
  3145        HHGear, 1))
  3145        HHGear, 1))
  3146        or ((Gear^.Message and gm_Attack) <> 0) then
  3146        or ((Gear^.Message and gmAttack) <> 0) then
  3147     begin
  3147     begin
  3148         with HHGear^ do
  3148         with HHGear^ do
  3149         begin
  3149         begin
  3150             Message := 0;
  3150             Message := 0;
  3151             Active := true;
  3151             Active := true;
  3177             DeleteGear(Gear);
  3177             DeleteGear(Gear);
  3178             AfterAttack;
  3178             AfterAttack;
  3179             exit
  3179             exit
  3180         end;
  3180         end;
  3181     HHGear := CurrentHedgehog^.Gear;
  3181     HHGear := CurrentHedgehog^.Gear;
  3182     HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Precise or gm_Left or gm_Right);
  3182     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3183     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
  3183     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
  3184     begin
  3184     begin
  3185         if Gear^.Timer = 0 then
  3185         if Gear^.Timer = 0 then
  3186             Gear^.Y := Gear^.Y + _0_1
  3186             Gear^.Y := Gear^.Y + _0_1
  3187     end
  3187     end
  3230     AllInactive := false;
  3230     AllInactive := false;
  3231     FollowGear := HHGear;
  3231     FollowGear := HHGear;
  3232     with HHGear^ do
  3232     with HHGear^ do
  3233     begin
  3233     begin
  3234         State := State and not gstAttacking;
  3234         State := State and not gstAttacking;
  3235         Message := Message and not (gm_Attack or gm_Up or gm_Precise or gm_Left or gm_Right)
  3235         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight)
  3236     end
  3236     end
  3237 end;
  3237 end;
  3238 
  3238 
  3239 ////////////////////////////////////////////////////////////////////////////////
  3239 ////////////////////////////////////////////////////////////////////////////////
  3240 procedure doStepEggWork(Gear: PGear);
  3240 procedure doStepEggWork(Gear: PGear);
  3273 var flags: LongWord;
  3273 var flags: LongWord;
  3274     CurWeapon: PAmmo;
  3274     CurWeapon: PAmmo;
  3275 begin
  3275 begin
  3276     if (CurrentHedgehog <> nil)
  3276     if (CurrentHedgehog <> nil)
  3277        and (CurrentHedgehog^.Gear <> nil)
  3277        and (CurrentHedgehog^.Gear <> nil)
  3278        and ((CurrentHedgehog^.Gear^.Message and gm_Switch) <> 0) then
  3278        and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3279         With CurrentHedgehog^ do
  3279         With CurrentHedgehog^ do
  3280             if (CurAmmoType = amPortalGun) then
  3280             if (CurAmmoType = amPortalGun) then
  3281             begin
  3281             begin
  3282                 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gm_Switch;
  3282                 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSwitch;
  3283                 
  3283                 
  3284                 CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  3284                 CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  3285                 flags := CurWeapon^.Timer and not 2;
  3285                 flags := CurWeapon^.Timer and not 2;
  3286                 if (flags and 1) = 0 then
  3286                 if (flags and 1) = 0 then
  3287                     CurWeapon^.Timer := flags or 1
  3287                     CurWeapon^.Timer := flags or 1
  3614     r0, r1: LongInt;
  3614     r0, r1: LongInt;
  3615     odY: hwFloat;
  3615     odY: hwFloat;
  3616 begin
  3616 begin
  3617     AllInactive := false;
  3617     AllInactive := false;
  3618     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.
  3618     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.
  3619        Message and gm_Slot) <> 0) then
  3619        Message and gmSlot) <> 0) then
  3620     begin
  3620     begin
  3621         case CurrentHedgehog^.Gear^.MsgParam of 
  3621         case CurrentHedgehog^.Gear^.MsgParam of 
  3622             0: PlaySound(sndPiano0);
  3622             0: PlaySound(sndPiano0);
  3623             1: PlaySound(sndPiano1);
  3623             1: PlaySound(sndPiano1);
  3624             2: PlaySound(sndPiano2);
  3624             2: PlaySound(sndPiano2);
  3629             7: PlaySound(sndPiano7);
  3629             7: PlaySound(sndPiano7);
  3630             else PlaySound(sndPiano8);
  3630             else PlaySound(sndPiano8);
  3631         end;
  3631         end;
  3632         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  3632         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  3633         CurrentHedgehog^.Gear^.MsgParam := 0;
  3633         CurrentHedgehog^.Gear^.MsgParam := 0;
  3634         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gm_Slot;
  3634         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSlot;
  3635     end;
  3635     end;
  3636 
  3636 
  3637     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  3637     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  3638         // bounce up to 10 times (3 times on gameflagged solid land) before dropping past landscape
  3638         // bounce up to 10 times (3 times on gameflagged solid land) before dropping past landscape
  3639     begin
  3639     begin
  3838     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  3838     gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
  3839     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  3839     gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
  3840     
  3840     
  3841     if (GameTicks and $FF) = 0 then
  3841     if (GameTicks and $FF) = 0 then
  3842     begin
  3842     begin
  3843         if (HHGear^.Message and gm_Right) <> 0 then
  3843         if (HHGear^.Message and gmRight) <> 0 then
  3844         begin
  3844         begin
  3845             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then inc(Gear^.Tag)
  3845             if HHGear^.dX.isNegative and (Gear^.Tag < 20) then inc(Gear^.Tag)
  3846             else if Gear^.Tag > 5 then dec(Gear^.Tag);
  3846             else if Gear^.Tag > 5 then dec(Gear^.Tag);
  3847         end
  3847         end
  3848         else if (HHGear^.Message and gm_Left) <> 0 then
  3848         else if (HHGear^.Message and gmLeft) <> 0 then
  3849         begin
  3849         begin
  3850             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then dec(Gear^.Tag)
  3850             if HHGear^.dX.isNegative and (Gear^.Tag > 5) then dec(Gear^.Tag)
  3851             else if Gear^.Tag < 20 then inc(Gear^.Tag);
  3851             else if Gear^.Tag < 20 then inc(Gear^.Tag);
  3852         end
  3852         end
  3853     end;
  3853     end;
  3891 procedure doStepFlamethrower(Gear: PGear);
  3891 procedure doStepFlamethrower(Gear: PGear);
  3892 var 
  3892 var 
  3893     HHGear: PGear;
  3893     HHGear: PGear;
  3894 begin
  3894 begin
  3895     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  3895     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  3896     HHGear^.Message := HHGear^.Message and not (gm_Up or gm_Down or gm_Left or gm_Right);
  3896     HHGear^.Message := HHGear^.Message and not (gmUp or gmDown or gmLeft or gmRight);
  3897     HHGear^.State := HHGear^.State or gstNotKickable;
  3897     HHGear^.State := HHGear^.State or gstNotKickable;
  3898     Gear^.doStep := @doStepFlamethrowerWork
  3898     Gear^.doStep := @doStepFlamethrowerWork
  3899 end;
  3899 end;
  3900 
  3900 
  3901 procedure doStepPoisonCloud(Gear: PGear);
  3901 procedure doStepPoisonCloud(Gear: PGear);
  3962     HHGear: PGear;
  3962     HHGear: PGear;
  3963 begin
  3963 begin
  3964     AllInactive := false;
  3964     AllInactive := false;
  3965     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  3965     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  3966     dec(Gear^.Timer);
  3966     dec(Gear^.Timer);
  3967     if (HHGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gm_Destroy) <> 0) then
  3967     if (HHGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gmDestroy) <> 0) then
  3968     begin
  3968     begin
  3969         DeleteGear(Gear);
  3969         DeleteGear(Gear);
  3970         exit
  3970         exit
  3971     end;
  3971     end;
  3972 
  3972