hedgewars/GSHandlers.inc
changeset 6450 14224c9b4594
parent 6419 6a464d0a5c13
child 6452 7c6f9b6672dc
equal deleted inserted replaced
6448:88e49851d814 6450:14224c9b4594
    82     while gi <> nil do
    82     while gi <> nil do
    83         begin
    83         begin
    84         if (gi^.Kind = gtHedgehog) then
    84         if (gi^.Kind = gtHedgehog) then
    85             begin
    85             begin
    86             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    86             d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
    87             if (d > 1) and not gi^.Invulnerable and (GetRandom(2) = 0) then
    87             if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then
    88                 begin
    88                 begin
    89                 if (CurrentHedgehog^.Gear = gi) then
    89                 if (CurrentHedgehog^.Gear = gi) then
    90                     PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack)
    90                     PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack)
    91                 else
    91                 else
    92                     begin
    92                     begin
   112 RemoveGearFromList(HH^.Gear);
   112 RemoveGearFromList(HH^.Gear);
   113 with HH^.Gear^ do
   113 with HH^.Gear^ do
   114     begin
   114     begin
   115     Z := cHHZ;
   115     Z := cHHZ;
   116     Active := false;
   116     Active := false;
   117     State:= State and not (gstHHDriven or gstAttacking or gstAttacked);
   117     State:= State and (not (gstHHDriven or gstAttacking or gstAttacked));
   118     Message := Message and not gmAttack;
   118     Message := Message and (not gmAttack);
   119     end;
   119     end;
   120 HH^.GearHidden:= HH^.Gear;
   120 HH^.GearHidden:= HH^.Gear;
   121 HH^.Gear:= nil
   121 HH^.Gear:= nil
   122 end;
   122 end;
   123 
   123 
   124 procedure RestoreHog(HH: PHedgehog);
   124 procedure RestoreHog(HH: PHedgehog);
   125 begin
   125 begin
   126 HH^.Gear:=HH^.GearHidden;
   126 HH^.Gear:=HH^.GearHidden;
   127 HH^.GearHidden:= nil;
   127 HH^.GearHidden:= nil;
   128 InsertGearToList(HH^.Gear);
   128 InsertGearToList(HH^.Gear);
   129 HH^.Gear^.State:= (HH^.Gear^.State and not (gstHHDriven or gstInvisible or gstAttacking)) or gstAttacked;
   129 HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked;
   130 AddGearCI(HH^.Gear);
   130 AddGearCI(HH^.Gear);
   131 HH^.Gear^.Active:= true;
   131 HH^.Gear^.Active:= true;
   132 ScriptCall('onHogRestore', HH^.Gear^.Uid)
   132 ScriptCall('onHogRestore', HH^.Gear^.Uid)
   133 end;
   133 end;
   134 
   134 
   219 
   219 
   220 procedure CheckCollision(Gear: PGear); inline;
   220 procedure CheckCollision(Gear: PGear); inline;
   221 begin
   221 begin
   222     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
   222     if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
   223         Gear^.State := Gear^.State or gstCollision
   223         Gear^.State := Gear^.State or gstCollision
   224     else Gear^.State := Gear^.State and not gstCollision
   224     else Gear^.State := Gear^.State and (not gstCollision)
   225 end;
   225 end;
   226 
   226 
   227 procedure CheckCollisionWithLand(Gear: PGear); inline;
   227 procedure CheckCollisionWithLand(Gear: PGear); inline;
   228 begin
   228 begin
   229     if TestCollisionX(Gear, hwSign(Gear^.dX)) or TestCollisionY(Gear, hwSign(Gear^.dY)
   229     if TestCollisionX(Gear, hwSign(Gear^.dX)) or TestCollisionY(Gear, hwSign(Gear^.dY)
   230        )
   230        )
   231         then Gear^.State := Gear^.State or      gstCollision
   231         then Gear^.State := Gear^.State or      gstCollision
   232     else Gear^.State := Gear^.State and not gstCollision
   232     else Gear^.State := Gear^.State and (not gstCollision)
   233 end;
   233 end;
   234 
   234 
   235 procedure CheckHHDamage(Gear: PGear);
   235 procedure CheckHHDamage(Gear: PGear);
   236 var 
   236 var 
   237     dmg: Longword;
   237     dmg: Longword;
   305     land: word;
   305     land: word;
   306 begin
   306 begin
   307     // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems.
   307     // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems.
   308     if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
   308     if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862;
   309     if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
   309     if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862;
   310     Gear^.State := Gear^.State and not gstCollision;
   310     Gear^.State := Gear^.State and (not gstCollision);
   311     collV := 0;
   311     collV := 0;
   312     collH := 0;
   312     collH := 0;
   313     tdX := Gear^.dX;
   313     tdX := Gear^.dX;
   314     tdY := Gear^.dY;
   314     tdY := Gear^.dY;
   315 
   315 
   346             Gear^.State := Gear^.State or gstCollision
   346             Gear^.State := Gear^.State or gstCollision
   347             end
   347             end
   348         else
   348         else
   349             begin
   349             begin
   350             isFalling := true;
   350             isFalling := true;
   351             if (Gear^.AdvBounce=1) and not Gear^.dY.isNegative and (TestCollisionYwithGear(Gear, -1) <> 0) then
   351             if (Gear^.AdvBounce=1) and (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then
   352                 collV := -1
   352                 collV := -1
   353             end
   353             end
   354         end;
   354         end;
   355 
   355 
   356 
   356 
   388     if Gear^.Kind <> gtBee then
   388     if Gear^.Kind <> gtBee then
   389         CheckGearDrowning(Gear);
   389         CheckGearDrowning(Gear);
   390     //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   390     //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   391     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and
   391     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and
   392        (not isFalling) then
   392        (not isFalling) then
   393         Gear^.State := Gear^.State and not gstMoving
   393         Gear^.State := Gear^.State and (not gstMoving)
   394     else
   394     else
   395         Gear^.State := Gear^.State or      gstMoving;
   395         Gear^.State := Gear^.State or      gstMoving;
   396 
   396 
   397     if (Gear^.nImpactSounds > 0) and 
   397     if (Gear^.nImpactSounds > 0) and 
   398        (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or 
   398        (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or 
   665 gun:= (Gear^.State and gstTmpFlag) <> 0;
   665 gun:= (Gear^.State and gstTmpFlag) <> 0;
   666 move:= false;
   666 move:= false;
   667 draw:= false;
   667 draw:= false;
   668 if gun then
   668 if gun then
   669     begin
   669     begin
   670     Gear^.State:= Gear^.State and not gstInvisible;
   670     Gear^.State:= Gear^.State and (not gstInvisible);
   671     doStepFallingGear(Gear);
   671     doStepFallingGear(Gear);
   672     CheckCollision(Gear);
   672     CheckCollision(Gear);
   673     if ((Gear^.State and gstCollision) <> 0) or ((Gear^.State and gstMoving) = 0) then draw:= true;
   673     if ((Gear^.State and gstCollision) <> 0) or ((Gear^.State and gstMoving) = 0) then draw:= true;
   674     xx:= hwRound(Gear^.X);
   674     xx:= hwRound(Gear^.X);
   675     yy:= hwRound(Gear^.Y);
   675     yy:= hwRound(Gear^.Y);
   676     end
   676     end
   677 else if GameTicks and $7 = 0 then
   677 else if GameTicks and $7 = 0 then
   678     begin
   678     begin
   679     with Gear^ do
   679     with Gear^ do
   680         begin
   680         begin
   681         State:= State and not gstInvisible;
   681         State:= State and (not gstInvisible);
   682         X:= X + cWindSpeed * 3200 + dX;
   682         X:= X + cWindSpeed * 3200 + dX;
   683         Y:= Y + dY + cGravity * vobFallSpeed * 8;  // using same value as flakes to try and get similar results
   683         Y:= Y + dY + cGravity * vobFallSpeed * 8;  // using same value as flakes to try and get similar results
   684         xx:= hwRound(X);
   684         xx:= hwRound(X);
   685         yy:= hwRound(Y);
   685         yy:= hwRound(Y);
   686         if vobVelocity <> 0 then
   686         if vobVelocity <> 0 then
   773                                 if LandPixels[ry, rx] = 0 then Land[ly, lx]:=  lfDamaged or lfObject
   773                                 if LandPixels[ry, rx] = 0 then Land[ly, lx]:=  lfDamaged or lfObject
   774                                 else Land[ly, lx]:=  lfDamaged or lfBasic
   774                                 else Land[ly, lx]:=  lfDamaged or lfBasic
   775                                 end
   775                                 end
   776                             else Land[ly, lx]:= lf;
   776                             else Land[ly, lx]:= lf;
   777                         if gun then
   777                         if gun then
   778                             LandPixels[ry, rx]:= (cExplosionBorderColor and not AMask) or (p^[px] and AMask)
   778                             LandPixels[ry, rx]:= (cExplosionBorderColor and (not AMask)) or (p^[px] and AMask)
   779                         else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]);
   779                         else LandPixels[ry, rx]:= addBgColor(LandPixels[ry, rx], p^[px]);
   780                         end
   780                         end
   781                     else allpx:= false
   781                     else allpx:= false
   782                     end;
   782                     end;
   783                 p:= @(p^[s^.pitch shr 2])
   783                 p:= @(p^[s^.pitch shr 2])
   948         exit
   948         exit
   949     end;
   949     end;
   950     dec(Gear^.Timer);
   950     dec(Gear^.Timer);
   951     if Gear^.Timer = 0 then
   951     if Gear^.Timer = 0 then
   952     begin
   952     begin
   953         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and not gmAttack;
   953         Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
   954         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and not gstAttacking;
   954         Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
   955         AttackBar:= 0;
   955         AttackBar:= 0;
   956         
   956         
   957         Gear^.SoundChannel := LoopSound(sndBee);
   957         Gear^.SoundChannel := LoopSound(sndBee);
   958         Gear^.Timer := 5000;
   958         Gear^.Timer := 5000;
   959         // save initial speed in otherwise unused Friction variable
   959         // save initial speed in otherwise unused Friction variable
  1266     y:= hwRound(Gear^.Y);
  1266     y:= hwRound(Gear^.Y);
  1267     if (Gear^.Timer mod 33) = 0 then
  1267     if (Gear^.Timer mod 33) = 0 then
  1268         begin
  1268         begin
  1269         HHGear^.State := HHGear^.State or gstNoDamage;
  1269         HHGear^.State := HHGear^.State or gstNoDamage;
  1270         doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw);
  1270         doMakeExplosion(x, y + 7, 6, Gear^.Hedgehog, EXPLDontDraw);
  1271         HHGear^.State := HHGear^.State and not gstNoDamage
  1271         HHGear^.State := HHGear^.State and (not gstNoDamage)
  1272         end;
  1272         end;
  1273 
  1273 
  1274     if (Gear^.Timer mod 47) = 0 then
  1274     if (Gear^.Timer mod 47) = 0 then
  1275         begin
  1275         begin
  1276         // ok. this was an attempt to turn off dust if not actually drilling land.  I have no idea why it isn't working as expected
  1276         // ok. this was an attempt to turn off dust if not actually drilling land.  I have no idea why it isn't working as expected
  1396         else
  1396         else
  1397             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
  1397             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
  1398 
  1398 
  1399         if ((HHGear^.State and gstMoving) = 0) then
  1399         if ((HHGear^.State and gstMoving) = 0) then
  1400             begin
  1400             begin
  1401             HHGear^.State := HHGear^.State and not gstAttacking;
  1401             HHGear^.State := HHGear^.State and (not gstAttacking);
  1402             prevX := hwRound(HHGear^.X);
  1402             prevX := hwRound(HHGear^.X);
  1403 
  1403 
  1404             // why the call to HedgehogStep then a further increment of X?
  1404             // why the call to HedgehogStep then a further increment of X?
  1405             if (prevX = hwRound(HHGear^.X)) and
  1405             if (prevX = hwRound(HHGear^.X)) and
  1406                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
  1406                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
  1423                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
  1423                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
  1424                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
  1424                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
  1425                 end;
  1425                 end;
  1426             HHGear^.State := HHGear^.State or gstNoDamage;
  1426             HHGear^.State := HHGear^.State or gstNoDamage;
  1427             AmmoShove(Gear, 2, 15);
  1427             AmmoShove(Gear, 2, 15);
  1428             HHGear^.State := HHGear^.State and not gstNoDamage
  1428             HHGear^.State := HHGear^.State and (not gstNoDamage)
  1429             end;
  1429             end;
  1430         end;
  1430         end;
  1431 
  1431 
  1432     if b then
  1432     if b then
  1433     begin
  1433     begin
  1498 
  1498 
  1499         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX);
  1499         Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX);
  1500         Gear^.dY := -AngleCos(HHGear^.Angle);
  1500         Gear^.dY := -AngleCos(HHGear^.Angle);
  1501         Gear^.Friction := _450 * _0_01 * cRopePercent;
  1501         Gear^.Friction := _450 * _0_01 * cRopePercent;
  1502         Gear^.Elasticity := _0;
  1502         Gear^.Elasticity := _0;
  1503         Gear^.State := Gear^.State and not gsttmpflag;
  1503         Gear^.State := Gear^.State and (not gsttmpflag);
  1504         Gear^.doStep := @doStepRope;
  1504         Gear^.doStep := @doStepRope;
  1505     end
  1505     end
  1506 end;
  1506 end;
  1507 
  1507 
  1508 procedure doStepRopeWork(Gear: PGear);
  1508 procedure doStepRopeWork(Gear: PGear);
  1515 
  1515 
  1516 procedure DeleteMe;
  1516 procedure DeleteMe;
  1517 begin
  1517 begin
  1518     with HHGear^ do
  1518     with HHGear^ do
  1519     begin
  1519     begin
  1520         Message := Message and not gmAttack;
  1520         Message := Message and (not gmAttack);
  1521         State := (State or gstMoving) and not gstWinner;
  1521         State := (State or gstMoving) and (not gstWinner);
  1522     end;
  1522     end;
  1523     DeleteGear(Gear)
  1523     DeleteGear(Gear)
  1524 end;
  1524 end;
  1525 
  1525 
  1526 procedure WaitCollision;
  1526 procedure WaitCollision;
  1527 begin
  1527 begin
  1528     with HHGear^ do
  1528     with HHGear^ do
  1529     begin
  1529     begin
  1530         Message := Message and not gmAttack;
  1530         Message := Message and (not gmAttack);
  1531         State := State or gstMoving;
  1531         State := State or gstMoving;
  1532     end;
  1532     end;
  1533     RopePoints.Count := 0;
  1533     RopePoints.Count := 0;
  1534     Gear^.Elasticity := _0;
  1534     Gear^.Elasticity := _0;
  1535     Gear^.doStep := @doStepRopeAfterAttack
  1535     Gear^.doStep := @doStepRopeAfterAttack
  1544         PlaySound(sndRopeRelease);
  1544         PlaySound(sndRopeRelease);
  1545         DeleteMe;
  1545         DeleteMe;
  1546         exit
  1546         exit
  1547         end;
  1547         end;
  1548 
  1548 
  1549     if (Gear^.Message and gmLeft  <> 0) and not TestCollisionXwithGear(HHGear, -1) then
  1549     if (Gear^.Message and gmLeft  <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then
  1550         HHGear^.dX := HHGear^.dX - _0_0002;
  1550         HHGear^.dX := HHGear^.dX - _0_0002;
  1551 
  1551 
  1552     if (Gear^.Message and gmRight <> 0) and not TestCollisionXwithGear(HHGear,  1) then
  1552     if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear,  1)) then
  1553         HHGear^.dX := HHGear^.dX + _0_0002;
  1553         HHGear^.dX := HHGear^.dX + _0_0002;
  1554 
  1554 
  1555     // vector between hedgehog and rope attaching point
  1555     // vector between hedgehog and rope attaching point
  1556     ropeDx := HHGear^.X - Gear^.X;
  1556     ropeDx := HHGear^.X - Gear^.X;
  1557     ropeDy := HHGear^.Y - Gear^.Y;
  1557     ropeDy := HHGear^.Y - Gear^.Y;
  1799 
  1799 
  1800         if TestCollisionYwithGear(HHGear, 1) <> 0 then
  1800         if TestCollisionYwithGear(HHGear, 1) <> 0 then
  1801             begin
  1801             begin
  1802             CheckHHDamage(HHGear);
  1802             CheckHHDamage(HHGear);
  1803             HHGear^.dY := _0
  1803             HHGear^.dY := _0
  1804             //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump);
  1804             //HHGear^.State:= HHGear^.State and (not (gstHHJumping or gstHHHJump));
  1805             end
  1805             end
  1806         else
  1806         else
  1807             begin
  1807             begin
  1808             HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1808             HHGear^.Y := HHGear^.Y + HHGear^.dY;
  1809             Gear^.Y := Gear^.Y + HHGear^.dY;
  1809             Gear^.Y := Gear^.Y + HHGear^.dY;
  1823                 Gear^.Elasticity := tt;
  1823                 Gear^.Elasticity := tt;
  1824                 Gear^.doStep := @doStepRopeWork;
  1824                 Gear^.doStep := @doStepRopeWork;
  1825                 PlaySound(sndRopeAttach);
  1825                 PlaySound(sndRopeAttach);
  1826                 with HHGear^ do
  1826                 with HHGear^ do
  1827                     begin
  1827                     begin
  1828                     State := State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1828                     State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
  1829                     Message := Message and not gmAttack
  1829                     Message := Message and (not gmAttack)
  1830                     end;
  1830                     end;
  1831 
  1831 
  1832                 RemoveFromAmmo;
  1832                 RemoveFromAmmo;
  1833 
  1833 
  1834                 tt := _0;
  1834                 tt := _0;
  1849         begin
  1849         begin
  1850         Gear^.doStep := @doStepRopeWork;
  1850         Gear^.doStep := @doStepRopeWork;
  1851         PlaySound(sndRopeAttach);
  1851         PlaySound(sndRopeAttach);
  1852         with HHGear^ do
  1852         with HHGear^ do
  1853             begin
  1853             begin
  1854             State := State and not (gstAttacking or gstHHJumping or gstHHHJump);
  1854             State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
  1855             Message := Message and not gmAttack
  1855             Message := Message and (not gmAttack)
  1856             end;
  1856             end;
  1857 
  1857 
  1858         RemoveFromAmmo;
  1858         RemoveFromAmmo;
  1859 
  1859 
  1860         exit
  1860         exit
  1865        or ((HHGear^.State and gstHHDriven) = 0)
  1865        or ((HHGear^.State and gstHHDriven) = 0)
  1866        or (HHGear^.Damage > 0) then
  1866        or (HHGear^.Damage > 0) then
  1867         begin
  1867         begin
  1868         with Gear^.Hedgehog^.Gear^ do
  1868         with Gear^.Hedgehog^.Gear^ do
  1869             begin
  1869             begin
  1870             State := State and not gstAttacking;
  1870             State := State and (not gstAttacking);
  1871             Message := Message and not gmAttack
  1871             Message := Message and (not gmAttack)
  1872             end;
  1872             end;
  1873         DeleteGear(Gear)
  1873         DeleteGear(Gear)
  1874         end;
  1874         end;
  1875     CheckGearDrowning(HHGear)
  1875     CheckGearDrowning(HHGear)
  1876 end;
  1876 end;
  1953                     vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1953                     vg:= AddVisualGear(hwRound(Gear^.X) - 4  + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
  1954                     if vg <> nil then vg^.Scale:= 0.5;
  1954                     if vg <> nil then vg^.Scale:= 0.5;
  1955                     PlaySound(sndVaporize);
  1955                     PlaySound(sndVaporize);
  1956                     Gear^.Health := 0;
  1956                     Gear^.Health := 0;
  1957                     Gear^.Damage := 0;
  1957                     Gear^.Damage := 0;
  1958                     Gear^.State := Gear^.State and not gstAttacking
  1958                     Gear^.State := Gear^.State and (not gstAttacking)
  1959                     end;
  1959                     end;
  1960                 exit
  1960                 exit
  1961                 end;
  1961                 end;
  1962             dec(Gear^.Timer);
  1962             dec(Gear^.Timer);
  1963             end
  1963             end
  2126         DeleteGear(Gear);
  2126         DeleteGear(Gear);
  2127         FreeActionsList;
  2127         FreeActionsList;
  2128         SetAllToActive;
  2128         SetAllToActive;
  2129         // something (hh, mine, etc...) could be on top of the case
  2129         // something (hh, mine, etc...) could be on top of the case
  2130         with CurrentHedgehog^ do
  2130         with CurrentHedgehog^ do
  2131             if Gear <> nil then Gear^.Message := Gear^.Message and not (gmLJump or gmHJump);
  2131             if Gear <> nil then Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
  2132         exit
  2132         exit
  2133     end;
  2133     end;
  2134 
  2134 
  2135     if k = gtExplosives then
  2135     if k = gtExplosives then
  2136     begin
  2136     begin
  2439         Gear^.Tag := hwRound(HHGear^.Y);
  2439         Gear^.Tag := hwRound(HHGear^.Y);
  2440         DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
  2440         DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2);
  2441         HHGear^.State := HHGear^.State or gstNoDamage;
  2441         HHGear^.State := HHGear^.State or gstNoDamage;
  2442         Gear^.Y := HHGear^.Y;
  2442         Gear^.Y := HHGear^.Y;
  2443         AmmoShove(Gear, 30, 40);
  2443         AmmoShove(Gear, 30, 40);
  2444         HHGear^.State := HHGear^.State and not gstNoDamage
  2444         HHGear^.State := HHGear^.State and (not gstNoDamage)
  2445     end;
  2445     end;
  2446 
  2446 
  2447     HHGear^.dY := HHGear^.dY + cGravity;
  2447     HHGear^.dY := HHGear^.dY + cGravity;
  2448     if not (HHGear^.dY.isNegative) then
  2448     if not (HHGear^.dY.isNegative) then
  2449     begin
  2449     begin
  2530 
  2530 
  2531     DeleteCI(HHGear);
  2531     DeleteCI(HHGear);
  2532 
  2532 
  2533     AfterAttack;
  2533     AfterAttack;
  2534 
  2534 
  2535     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked or gstMoving);
  2535     HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked or gstMoving));
  2536     HHGear^.Message := HHGear^.Message and not gmAttack;
  2536     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2537 
  2537 
  2538     Gear^.doStep := @doStepParachuteWork;
  2538     Gear^.doStep := @doStepParachuteWork;
  2539 
  2539 
  2540     Gear^.Message := HHGear^.Message;
  2540     Gear^.Message := HHGear^.Message;
  2541     doStepParachuteWork(Gear)
  2541     doStepParachuteWork(Gear)
  2640     ty := int2hwFloat(Gear^.Target.Y);
  2640     ty := int2hwFloat(Gear^.Target.Y);
  2641     x := HHGear^.X;
  2641     x := HHGear^.X;
  2642     y := HHGear^.Y;
  2642     y := HHGear^.Y;
  2643 
  2643 
  2644     if (Distance(tx - x, ty - y) > _256) or
  2644     if (Distance(tx - x, ty - y) > _256) or
  2645        not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2,
  2645        (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2,
  2646        Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2,
  2646        Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2,
  2647        sprAmGirder, Gear^.State, true, false) then
  2647        sprAmGirder, Gear^.State, true, false)) then
  2648     begin
  2648     begin
  2649         PlaySound(sndDenied);
  2649         PlaySound(sndDenied);
  2650         HHGear^.Message := HHGear^.Message and not gmAttack;
  2650         HHGear^.Message := HHGear^.Message and (not gmAttack);
  2651         HHGear^.State := HHGear^.State and not gstAttacking;
  2651         HHGear^.State := HHGear^.State and (not gstAttacking);
  2652         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2652         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2653         isCursorVisible := true;
  2653         isCursorVisible := true;
  2654         DeleteGear(Gear)
  2654         DeleteGear(Gear)
  2655     end
  2655     end
  2656     else 
  2656     else 
  2658         PlaySound(sndPlaced);
  2658         PlaySound(sndPlaced);
  2659         DeleteGear(Gear);
  2659         DeleteGear(Gear);
  2660         AfterAttack;
  2660         AfterAttack;
  2661     end;
  2661     end;
  2662 
  2662 
  2663     HHGear^.State := HHGear^.State and not (gstAttacking or gstAttacked);
  2663     HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked));
  2664     HHGear^.Message := HHGear^.Message and not gmAttack;
  2664     HHGear^.Message := HHGear^.Message and (not gmAttack);
  2665 end;
  2665 end;
  2666 
  2666 
  2667 ////////////////////////////////////////////////////////////////////////////////
  2667 ////////////////////////////////////////////////////////////////////////////////
  2668 procedure doStepTeleportAfter(Gear: PGear);
  2668 procedure doStepTeleportAfter(Gear: PGear);
  2669 var 
  2669 var 
  2704     HHGear := Gear^.Hedgehog^.Gear;
  2704     HHGear := Gear^.Hedgehog^.Gear;
  2705     if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
  2705     if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
  2706        Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
  2706        Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
  2707        sprHHTelepMask, 0, false, false) then
  2707        sprHHTelepMask, 0, false, false) then
  2708     begin
  2708     begin
  2709         HHGear^.Message := HHGear^.Message and not gmAttack;
  2709         HHGear^.Message := HHGear^.Message and (not gmAttack);
  2710         HHGear^.State := HHGear^.State and not gstAttacking;
  2710         HHGear^.State := HHGear^.State and (not gstAttacking);
  2711         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2711         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2712         DeleteGear(Gear);
  2712         DeleteGear(Gear);
  2713         isCursorVisible := true;
  2713         isCursorVisible := true;
  2714         PlaySound(sndDenied)
  2714         PlaySound(sndDenied)
  2715     end
  2715     end
  2739     HHGear: PGear;
  2739     HHGear: PGear;
  2740     Msg, State: Longword;
  2740     Msg, State: Longword;
  2741 begin
  2741 begin
  2742     AllInactive := false;
  2742     AllInactive := false;
  2743 
  2743 
  2744     if ((Gear^.Message and not gmSwitch) <> 0) or (TurnTimeLeft = 0) then
  2744     if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then
  2745     begin
  2745     begin
  2746         HHGear := Gear^.Hedgehog^.Gear;
  2746         HHGear := Gear^.Hedgehog^.Gear;
  2747         Msg := Gear^.Message and not gmSwitch;
  2747         Msg := Gear^.Message and (not gmSwitch);
  2748         DeleteGear(Gear);
  2748         DeleteGear(Gear);
  2749         ApplyAmmoChanges(HHGear^.Hedgehog^);
  2749         ApplyAmmoChanges(HHGear^.Hedgehog^);
  2750 
  2750 
  2751         HHGear := CurrentHedgehog^.Gear;
  2751         HHGear := CurrentHedgehog^.Gear;
  2752         ApplyAmmoChanges(HHGear^.Hedgehog^);
  2752         ApplyAmmoChanges(HHGear^.Hedgehog^);
  2755     end;
  2755     end;
  2756 
  2756 
  2757     if (Gear^.Message and gmSwitch) <> 0 then
  2757     if (Gear^.Message and gmSwitch) <> 0 then
  2758     begin
  2758     begin
  2759         HHGear := CurrentHedgehog^.Gear;
  2759         HHGear := CurrentHedgehog^.Gear;
  2760         HHGear^.Message := HHGear^.Message and not gmSwitch;
  2760         HHGear^.Message := HHGear^.Message and (not gmSwitch);
  2761         Gear^.Message := Gear^.Message and not gmSwitch;
  2761         Gear^.Message := Gear^.Message and (not gmSwitch);
  2762         State := HHGear^.State;
  2762         State := HHGear^.State;
  2763         HHGear^.State := 0;
  2763         HHGear^.State := 0;
  2764         HHGear^.Active := false;
  2764         HHGear^.Active := false;
  2765         HHGear^.Z := cHHZ;
  2765         HHGear^.Z := cHHZ;
  2766         RemoveGearFromList(HHGear);
  2766         RemoveGearFromList(HHGear);
  2795 
  2795 
  2796     HHGear := Gear^.Hedgehog^.Gear;
  2796     HHGear := Gear^.Hedgehog^.Gear;
  2797     OnUsedAmmo(HHGear^.Hedgehog^);
  2797     OnUsedAmmo(HHGear^.Hedgehog^);
  2798     with HHGear^ do
  2798     with HHGear^ do
  2799     begin
  2799     begin
  2800         State := State and not gstAttacking;
  2800         State := State and (not gstAttacking);
  2801         Message := Message and not gmAttack
  2801         Message := Message and (not gmAttack)
  2802     end
  2802     end
  2803 end;
  2803 end;
  2804 
  2804 
  2805 ////////////////////////////////////////////////////////////////////////////////
  2805 ////////////////////////////////////////////////////////////////////////////////
  2806 procedure doStepMortar(Gear: PGear);
  2806 procedure doStepMortar(Gear: PGear);
  3297     t := CheckGearsCollision(Gear);
  3297     t := CheckGearsCollision(Gear);
  3298     //fixes drill not exploding when touching HH bug
  3298     //fixes drill not exploding when touching HH bug
  3299     if (Gear^.Timer = 0) or (t^.Count <> 0) or 
  3299     if (Gear^.Timer = 0) or (t^.Count <> 0) or 
  3300        ( ((Gear^.State and gsttmpFlag) = 0) and
  3300        ( ((Gear^.State and gsttmpFlag) = 0) and
  3301          (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0)
  3301          (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0)
  3302          and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
  3302          and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
  3303 // CheckLandValue returns true if the type isn't matched
  3303 // CheckLandValue returns true if the type isn't matched
  3304        or not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible) then
  3304        or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then
  3305         begin
  3305         begin
  3306         //out of time or exited ground
  3306         //out of time or exited ground
  3307         StopSound(Gear^.SoundChannel);
  3307         StopSound(Gear^.SoundChannel);
  3308         if (Gear^.State and gsttmpFlag) <> 0 then
  3308         if (Gear^.State and gsttmpFlag) <> 0 then
  3309             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  3309             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound)
  3310         else
  3310         else
  3311             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  3311             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
  3312         DeleteGear(Gear);
  3312         DeleteGear(Gear);
  3313         exit
  3313         exit
  3314         end
  3314         end
  3315     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) then
  3315     else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
  3316         begin
  3316         begin
  3317         StopSound(Gear^.SoundChannel);
  3317         StopSound(Gear^.SoundChannel);
  3318         Gear^.Tag := 1;
  3318         Gear^.Tag := 1;
  3319         Gear^.doStep := @doStepDrill
  3319         Gear^.doStep := @doStepDrill
  3320         end;
  3320         end;
  3420 procedure doStepBallgun(Gear: PGear);
  3420 procedure doStepBallgun(Gear: PGear);
  3421 var 
  3421 var 
  3422     HHGear: PGear;
  3422     HHGear: PGear;
  3423 begin
  3423 begin
  3424     HHGear := Gear^.Hedgehog^.Gear;
  3424     HHGear := Gear^.Hedgehog^.Gear;
  3425     HHGear^.Message := HHGear^.Message and not (gmUp or gmDown);
  3425     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown));
  3426     HHGear^.State := HHGear^.State or gstNotKickable;
  3426     HHGear^.State := HHGear^.State or gstNotKickable;
  3427     Gear^.doStep := @doStepBallgunWork
  3427     Gear^.doStep := @doStepBallgunWork
  3428 end;
  3428 end;
  3429 
  3429 
  3430 ////////////////////////////////////////////////////////////////////////////////
  3430 ////////////////////////////////////////////////////////////////////////////////
  3491     else
  3491     else
  3492         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  3492         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  3493 
  3493 
  3494     if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
  3494     if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then
  3495     begin
  3495     begin
  3496         HHGear^.Message := HHGear^.Message and not gmAttack;
  3496         HHGear^.Message := HHGear^.Message and (not gmAttack);
  3497         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
  3497         AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY *
  3498         _0_5, 0);
  3498         _0_5, 0);
  3499         dec(Gear^.Health)
  3499         dec(Gear^.Health)
  3500     end;
  3500     end;
  3501 
  3501 
  3540             if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  3540             if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  3541             TurnTimeLeft:= 14 * 125;
  3541             TurnTimeLeft:= 14 * 125;
  3542             end;
  3542             end;
  3543 
  3543 
  3544         HHGear^.Message := 0;
  3544         HHGear^.Message := 0;
  3545         ParseCommand('/taunt '#1, true)
  3545         ParseCommand('/taunt ' + #1, true)
  3546     end
  3546     end
  3547 end;
  3547 end;
  3548 
  3548 
  3549 procedure doStepRCPlane(Gear: PGear);
  3549 procedure doStepRCPlane(Gear: PGear);
  3550 var 
  3550 var 
  3645         FreeTexture(Gear^.Tex);
  3645         FreeTexture(Gear^.Tex);
  3646         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
  3646         Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) +
  3647                      '%', cWhiteColor, fntSmall)
  3647                      '%', cWhiteColor, fntSmall)
  3648         end;
  3648         end;
  3649 
  3649 
  3650     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then Gear^
  3650     if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then 
  3651         .State := Gear^.State and not gsttmpFlag;
  3651         Gear^.State := Gear^.State and (not gsttmpFlag);
  3652     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3652     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3653     HHGear^.State := HHGear^.State or gstMoving;
  3653     HHGear^.State := HHGear^.State or gstMoving;
  3654 
  3654 
  3655     Gear^.X := HHGear^.X;
  3655     Gear^.X := HHGear^.X;
  3656     Gear^.Y := HHGear^.Y;
  3656     Gear^.Y := HHGear^.Y;
  3657     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3657     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3697     HHGear := Gear^.Hedgehog^.Gear;
  3697     HHGear := Gear^.Hedgehog^.Gear;
  3698     FollowGear := HHGear;
  3698     FollowGear := HHGear;
  3699     AfterAttack;
  3699     AfterAttack;
  3700     with HHGear^ do
  3700     with HHGear^ do
  3701     begin
  3701     begin
  3702         State := State and not gstAttacking;
  3702         State := State and (not gstAttacking);
  3703         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight);
  3703         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
  3704         if (dY < _0_1) and (dY > -_0_1) then
  3704         if (dY < _0_1) and (dY > -_0_1) then
  3705         begin
  3705         begin
  3706             Gear^.State := Gear^.State or gsttmpFlag;
  3706             Gear^.State := Gear^.State or gsttmpFlag;
  3707             dY := dY - _0_2
  3707             dY := dY - _0_2
  3708         end
  3708         end
  3768         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3768         for i:= ((500-Gear^.Health) div 250) downto 0 do
  3769             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3769             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
  3770 
  3770 
  3771     if (HHGear^.Message and gmAttack <> 0) then
  3771     if (HHGear^.Message and gmAttack <> 0) then
  3772         begin
  3772         begin
  3773         HHGear^.Message := HHGear^.Message and not gmAttack;
  3773         HHGear^.Message := HHGear^.Message and (not gmAttack);
  3774         if Gear^.FlightTime > 0 then
  3774         if Gear^.FlightTime > 0 then
  3775             begin
  3775             begin
  3776             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0);
  3776             AddGear(hwRound(Gear^.X), hwRound(Gear^.Y) + 32, gtEgg, 0, Gear^.dX * _0_5, Gear^.dY, 0);
  3777             PlaySound(sndBirdyLay);
  3777             PlaySound(sndBirdyLay);
  3778             dec(Gear^.FlightTime)
  3778             dec(Gear^.FlightTime)
  3779             end;
  3779             end;
  3780         end;
  3780         end;
  3781 
  3781 
  3782     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3782     if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
  3783         Gear^.State := Gear^.State and not gsttmpFlag;
  3783         Gear^.State := Gear^.State and (not gsttmpFlag);
  3784     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3784     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3785     HHGear^.State := HHGear^.State or gstMoving;
  3785     HHGear^.State := HHGear^.State or gstMoving;
  3786 
  3786 
  3787     Gear^.X := HHGear^.X;
  3787     Gear^.X := HHGear^.X;
  3788     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3788     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3789     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3789     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3831             DeleteGear(Gear);
  3831             DeleteGear(Gear);
  3832             AfterAttack;
  3832             AfterAttack;
  3833             exit
  3833             exit
  3834         end;
  3834         end;
  3835     HHGear := Gear^.Hedgehog^.Gear;
  3835     HHGear := Gear^.Hedgehog^.Gear;
  3836     HHGear^.Message := HHGear^.Message and not (gmUp or gmPrecise or gmLeft or gmRight);
  3836     HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
  3837     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
  3837     if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then
  3838     begin
  3838     begin
  3839         if Gear^.Timer = 0 then
  3839         if Gear^.Timer = 0 then
  3840             Gear^.Y := Gear^.Y + _0_1
  3840             Gear^.Y := Gear^.Y + _0_1
  3841     end
  3841     end
  3854     else
  3854     else
  3855     begin
  3855     begin
  3856         Gear^.Timer := 500;
  3856         Gear^.Timer := 500;
  3857         Gear^.dX := _0;
  3857         Gear^.dX := _0;
  3858         Gear^.dY := _0;
  3858         Gear^.dY := _0;
  3859         Gear^.State :=  Gear^.State and not gstAnimation;
  3859         Gear^.State :=  Gear^.State and (not gstAnimation);
  3860         Gear^.doStep := @doStepBirdyDescend;
  3860         Gear^.doStep := @doStepBirdyDescend;
  3861     end
  3861     end
  3862 end;
  3862 end;
  3863 
  3863 
  3864 procedure doStepBirdy(Gear: PGear);
  3864 procedure doStepBirdy(Gear: PGear);
  3865 var 
  3865 var 
  3866     HHGear: PGear;
  3866     HHGear: PGear;
  3867 begin
  3867 begin
  3868     gear^.State :=  gear^.State or gstAnimation and not gstTmpFlag;
  3868     gear^.State :=  gear^.State or gstAnimation and (not gstTmpFlag);
  3869     Gear^.doStep := @doStepBirdyAppear;
  3869     Gear^.doStep := @doStepBirdyAppear;
  3870     if CurrentHedgehog = nil then
  3870     if CurrentHedgehog = nil then
  3871     begin
  3871     begin
  3872         DeleteGear(Gear);
  3872         DeleteGear(Gear);
  3873         exit
  3873         exit
  3882     Gear^.Pos := 0;
  3882     Gear^.Pos := 0;
  3883     AllInactive := false;
  3883     AllInactive := false;
  3884     FollowGear := HHGear;
  3884     FollowGear := HHGear;
  3885     with HHGear^ do
  3885     with HHGear^ do
  3886         begin
  3886         begin
  3887         State := State and not gstAttacking;
  3887         State := State and (not gstAttacking);
  3888         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight)
  3888         Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight))
  3889         end
  3889         end
  3890 end;
  3890 end;
  3891 
  3891 
  3892 ////////////////////////////////////////////////////////////////////////////////
  3892 ////////////////////////////////////////////////////////////////////////////////
  3893 procedure doStepEggWork(Gear: PGear);
  3893 procedure doStepEggWork(Gear: PGear);
  3926 var CurWeapon: PAmmo;
  3926 var CurWeapon: PAmmo;
  3927 begin
  3927 begin
  3928     if (CurrentHedgehog <> nil)
  3928     if (CurrentHedgehog <> nil)
  3929        and (CurrentHedgehog^.Gear <> nil)
  3929        and (CurrentHedgehog^.Gear <> nil)
  3930        and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3930        and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then
  3931         With CurrentHedgehog^ do
  3931         with CurrentHedgehog^ do
  3932             if (CurAmmoType = amPortalGun) then
  3932             if (CurAmmoType = amPortalGun) then
  3933             begin
  3933             begin
  3934                 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSwitch;
  3934                 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
  3935                 
  3935                 
  3936                 CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  3936                 CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  3937                 if CurWeapon^.Pos <> 0 then
  3937                 if CurWeapon^.Pos <> 0 then
  3938                     CurWeapon^.Pos := 0
  3938                     CurWeapon^.Pos := 0
  3939                 else
  3939                 else
  4082 
  4082 
  4083         if not isBullet and poffs.isNegative then
  4083         if not isBullet and poffs.isNegative then
  4084             continue;
  4084             continue;
  4085 
  4085 
  4086         // only port bullets close to the portal
  4086         // only port bullets close to the portal
  4087         if isBullet and not (hwAbs(poffs) < _3) then
  4087         if isBullet and (not (hwAbs(poffs) < _3)) then
  4088             continue;
  4088             continue;
  4089 
  4089 
  4090         //
  4090         //
  4091         // gears that make it till here will definately be ported
  4091         // gears that make it till here will definately be ported
  4092         //
  4092         //
  4172         end;
  4172         end;
  4173 
  4173 
  4174         iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
  4174         iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx;
  4175         iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
  4175         iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny;
  4176 
  4176 
  4177         if not hasdxy and not (conPortal^.dY.isNegative) then
  4177         if not hasdxy and (not (conPortal^.dY.isNegative)) then
  4178         begin
  4178         begin
  4179             iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
  4179             iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y))
  4180         end;
  4180         end;
  4181 
  4181 
  4182         // see if the space on the exit side actually is enough
  4182         // see if the space on the exit side actually is enough
  4227         // Until loops are reliably broken
  4227         // Until loops are reliably broken
  4228         if iscake then iterator^.PortalCounter:= 33
  4228         if iscake then iterator^.PortalCounter:= 33
  4229         else
  4229         else
  4230             begin
  4230             begin
  4231             inc(iterator^.PortalCounter);
  4231             inc(iterator^.PortalCounter);
  4232             iterator^.State:= iterator^.State and not gstHHHJump
  4232             iterator^.State:= iterator^.State and (not gstHHHJump)
  4233             end;
  4233             end;
  4234 
  4234 
  4235         if not isbullet and (iterator^.Kind <> gtFlake) then
  4235         if not isbullet and (iterator^.Kind <> gtFlake) then
  4236             FollowGear := iterator;
  4236             FollowGear := iterator;
  4237 
  4237 
  4301     // avoid compiler hints
  4301     // avoid compiler hints
  4302 
  4302 
  4303     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  4303     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  4304     begin
  4304     begin
  4305         Gear^.State := Gear^.State or gstCollision;
  4305         Gear^.State := Gear^.State or gstCollision;
  4306         Gear^.State := Gear^.State and not gstMoving;
  4306         Gear^.State := Gear^.State and (not gstMoving);
  4307         if not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
  4307         if not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
  4308            or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4308            or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4309         begin
  4309         begin
  4310             loadNewPortalBall(Gear, true);
  4310             loadNewPortalBall(Gear, true);
  4311             EXIT;
  4311             EXIT;
  4368         begin
  4368         begin
  4369             CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  4369             CurWeapon:= GetAmmoEntry(CurrentHedgehog^);
  4370             // let's save the HH's dX's direction so we can decide where the "top" of the portal hole
  4370             // let's save the HH's dX's direction so we can decide where the "top" of the portal hole
  4371             newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative;
  4371             newPortal^.Elasticity.isNegative := CurrentHedgehog^.Gear^.dX.isNegative;
  4372             // when doing a backjump the dx is the opposite of the facing direction
  4372             // when doing a backjump the dx is the opposite of the facing direction
  4373             if ((Gear^.State and gstHHHJump) <> 0) and not cArtillery then
  4373             if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
  4374                 newPortal^.Elasticity.isNegative := not newPortal^.Elasticity.isNegative;
  4374                 newPortal^.Elasticity.isNegative := not newPortal^.Elasticity.isNegative;
  4375 
  4375 
  4376             // make portal gun look unloaded
  4376             // make portal gun look unloaded
  4377             if (CurWeapon <> nil) and (CurAmmoType = amPortalGun) then
  4377             if (CurWeapon <> nil) and (CurAmmoType = amPortalGun) then
  4378                 CurWeapon^.Timer := CurWeapon^.Timer or 2;
  4378                 CurWeapon^.Timer := CurWeapon^.Timer or 2;
  4397                     end;
  4397                     end;
  4398                 iterator^.PortalCounter:= 0;
  4398                 iterator^.PortalCounter:= 0;
  4399                 iterator := iterator^.NextGear
  4399                 iterator := iterator^.NextGear
  4400             end;
  4400             end;
  4401         end;
  4401         end;
  4402     newPortal^.State := newPortal^.State and not gstCollision;
  4402     newPortal^.State := newPortal^.State and (not gstCollision);
  4403     newPortal^.State := newPortal^.State or gstMoving;
  4403     newPortal^.State := newPortal^.State or gstMoving;
  4404     newPortal^.doStep := @doStepMovingPortal;
  4404     newPortal^.doStep := @doStepMovingPortal;
  4405 end;
  4405 end;
  4406 
  4406 
  4407 ////////////////////////////////////////////////////////////////////////////////
  4407 ////////////////////////////////////////////////////////////////////////////////
  4425             7: PlaySound(sndPiano7);
  4425             7: PlaySound(sndPiano7);
  4426             else PlaySound(sndPiano8);
  4426             else PlaySound(sndPiano8);
  4427         end;
  4427         end;
  4428         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4428         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4429         CurrentHedgehog^.Gear^.MsgParam := 0;
  4429         CurrentHedgehog^.Gear^.MsgParam := 0;
  4430         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSlot;
  4430         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot);
  4431         end;
  4431         end;
  4432 
  4432 
  4433     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  4433     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  4434         begin
  4434         begin
  4435         Gear^.dY := Gear^.dY + cGravity * 2;
  4435         Gear^.dY := Gear^.dY + cGravity * 2;
  4696 procedure doStepFlamethrower(Gear: PGear);
  4696 procedure doStepFlamethrower(Gear: PGear);
  4697 var 
  4697 var 
  4698     HHGear: PGear;
  4698     HHGear: PGear;
  4699 begin
  4699 begin
  4700     HHGear := Gear^.Hedgehog^.Gear;
  4700     HHGear := Gear^.Hedgehog^.Gear;
  4701     HHGear^.Message := HHGear^.Message and not (gmUp or gmDown or gmLeft or gmRight);
  4701     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight));
  4702     HHGear^.State := HHGear^.State or gstNotKickable;
  4702     HHGear^.State := HHGear^.State or gstNotKickable;
  4703     Gear^.doStep := @doStepFlamethrowerWork
  4703     Gear^.doStep := @doStepFlamethrowerWork
  4704 end;
  4704 end;
  4705 
  4705 
  4706 ////////////////////////////////////////////////////////////////////////////////
  4706 ////////////////////////////////////////////////////////////////////////////////
  4746         Gear^.Timer:= Gear^.Tag
  4746         Gear^.Timer:= Gear^.Tag
  4747         end;
  4747         end;
  4748 
  4748 
  4749     if (Gear^.Health = 0) or (HHGear^.Damage <> 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4749     if (Gear^.Health = 0) or (HHGear^.Damage <> 0) or ((HHGear^.Message and gmAttack) <> 0) then
  4750         begin
  4750         begin
  4751         HHGear^.Message:= HHGear^.Message and not gmAttack;
  4751         HHGear^.Message:= HHGear^.Message and (not gmAttack);
  4752         DeleteGear(Gear);
  4752         DeleteGear(Gear);
  4753         AfterAttack
  4753         AfterAttack
  4754         end
  4754         end
  4755     else
  4755     else
  4756         begin
  4756         begin
  4768 procedure doStepLandGun(Gear: PGear);
  4768 procedure doStepLandGun(Gear: PGear);
  4769 var 
  4769 var 
  4770     HHGear: PGear;
  4770     HHGear: PGear;
  4771 begin
  4771 begin
  4772     HHGear := Gear^.Hedgehog^.Gear;
  4772     HHGear := Gear^.Hedgehog^.Gear;
  4773     HHGear^.Message := HHGear^.Message and not (gmUp or gmDown or gmLeft or gmRight or gmAttack);
  4773     HHGear^.Message := HHGear^.Message and (not (gmUp or gmDown or gmLeft or gmRight or gmAttack));
  4774     HHGear^.State := HHGear^.State or gstNotKickable;
  4774     HHGear^.State := HHGear^.State or gstNotKickable;
  4775     Gear^.doStep := @doStepLandGunWork
  4775     Gear^.doStep := @doStepLandGunWork
  4776 end;
  4776 end;
  4777 
  4777 
  4778 ////////////////////////////////////////////////////////////////////////////////
  4778 ////////////////////////////////////////////////////////////////////////////////
  4826         else
  4826         else
  4827             begin
  4827             begin
  4828             end
  4828             end
  4829     end;
  4829     end;
  4830 
  4830 
  4831 HHGear^.State:= HHGear^.State and not gstNoDamage;
  4831 HHGear^.State:= HHGear^.State and (not gstNoDamage);
  4832 Gear^.Timer:= 250;
  4832 Gear^.Timer:= 250;
  4833 Gear^.doStep:= @doStepIdle
  4833 Gear^.doStep:= @doStepIdle
  4834 end;
  4834 end;
  4835 
  4835 
  4836 procedure doStepHammerHitWork(Gear: PGear);
  4836 procedure doStepHammerHitWork(Gear: PGear);
  5073     if (Gear^.State and gstMoving) <> 0 then
  5073     if (Gear^.State and gstMoving) <> 0 then
  5074         begin
  5074         begin
  5075         AddGearCI(Gear);
  5075         AddGearCI(Gear);
  5076         Gear^.dX:= _0;
  5076         Gear^.dX:= _0;
  5077         Gear^.dY:= _0;
  5077         Gear^.dY:= _0;
  5078         Gear^.State:= Gear^.State and not gstMoving;
  5078         Gear^.State:= Gear^.State and (not gstMoving);
  5079         end;
  5079         end;
  5080 
  5080 
  5081     if CurAmmoGear = Gear then
  5081     if CurAmmoGear = Gear then
  5082         begin
  5082         begin
  5083         if (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then
  5083         if (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then
  5088         if Gear = CurAmmoGear then CurAmmoGear := nil;
  5088         if Gear = CurAmmoGear then CurAmmoGear := nil;
  5089         Gear^.Hedgehog:= CurrentHedgehog;
  5089         Gear^.Hedgehog:= CurrentHedgehog;
  5090         RemoveGearFromList(CurrentHedgehog^.Gear);
  5090         RemoveGearFromList(CurrentHedgehog^.Gear);
  5091         CurrentHedgehog^.Gear^.Z := cHHZ;
  5091         CurrentHedgehog^.Gear^.Z := cHHZ;
  5092         CurrentHedgehog^.Gear^.Active := false;
  5092         CurrentHedgehog^.Gear^.Active := false;
  5093         CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and not gstHHDriven;
  5093         CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstHHDriven);
  5094         CurrentHedgehog^.GearHidden:= CurrentHedgehog^.Gear;
  5094         CurrentHedgehog^.GearHidden:= CurrentHedgehog^.Gear;
  5095         CurrentHedgehog^.Gear:= nil;
  5095         CurrentHedgehog^.Gear:= nil;
  5096         Gear^.Tag:= TotalRounds + Gear^.Tag;
  5096         Gear^.Tag:= TotalRounds + Gear^.Tag;
  5097         AddGearCI(Gear);
  5097         AddGearCI(Gear);
  5098         end;
  5098         end;
  5244     if HH^.Gear <> nil then
  5244     if HH^.Gear <> nil then
  5245     if (HH^.Gear = nil) or (HH^.King) or (SuddenDeathDmg) then
  5245     if (HH^.Gear = nil) or (HH^.King) or (SuddenDeathDmg) then
  5246         begin
  5246         begin
  5247         if HH^.Gear <> nil then
  5247         if HH^.Gear <> nil then
  5248             begin
  5248             begin
  5249             HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
  5249             HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
  5250             HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
  5250             HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
  5251             end;
  5251             end;
  5252         PlaySound(sndDenied);
  5252         PlaySound(sndDenied);
  5253         DeleteGear(gear);
  5253         DeleteGear(gear);
  5254         exit
  5254         exit
  5255         end;
  5255         end;
  5262                 HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then inc(cnt);
  5262                 HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then inc(cnt);
  5263     if cnt < 2 then
  5263     if cnt < 2 then
  5264         begin
  5264         begin
  5265         if HH^.Gear <> nil then
  5265         if HH^.Gear <> nil then
  5266             begin
  5266             begin
  5267             HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
  5267             HH^.Gear^.Message := HH^.Gear^.Message and (not gmAttack);
  5268             HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
  5268             HH^.Gear^.State:= HH^.Gear^.State and (not gstAttacking);
  5269             end;
  5269             end;
  5270             PlaySound(sndDenied);
  5270             PlaySound(sndDenied);
  5271             DeleteGear(gear);
  5271             DeleteGear(gear);
  5272             exit
  5272             exit
  5273         end;
  5273         end;