hedgewars/GSHandlers.inc
changeset 5906 ed9676dc8cb4
parent 5896 9ce1cf4e5a32
child 5913 1791f776b726
equal deleted inserted replaced
5713:190d6bb075c5 5906:ed9676dc8cb4
    99                     end;
    99                     end;
   100                 end;
   100                 end;
   101             end;
   101             end;
   102         gi := gi^.NextGear
   102         gi := gi^.NextGear
   103         end;
   103         end;
       
   104 end;
       
   105 
       
   106 procedure HideHog(HH: PHedgehog);
       
   107 begin
       
   108 ScriptCall('onHogHide', HH^.Gear^.Uid);
       
   109 DeleteCI(HH^.Gear);
       
   110 if FollowGear = HH^.Gear then FollowGear:= nil;
       
   111 if lastGearByUID = HH^.Gear then lastGearByUID := nil;
       
   112 RemoveGearFromList(HH^.Gear);
       
   113 with HH^.Gear^ do
       
   114     begin
       
   115     Z := cHHZ;
       
   116     Active := false;
       
   117     State:= State and not (gstHHDriven or gstAttacking or gstAttacked);
       
   118     Message := Message and not gmAttack;
       
   119     end;
       
   120 HH^.GearHidden:= HH^.Gear;
       
   121 HH^.Gear:= nil;
       
   122 end;
       
   123 
       
   124 procedure RestoreHog(HH: PHedgehog);
       
   125 begin
       
   126 HH^.Gear:=HH^.GearHidden;
       
   127 HH^.GearHidden:= nil;
       
   128 InsertGearToList(HH^.Gear);
       
   129 HH^.Gear^.State:= (HH^.Gear^.State and not (gstHHDriven or gstInvisible or gstAttacking)) or gstAttacked;
       
   130 AddGearCI(HH^.Gear);
       
   131 HH^.Gear^.Active:= true;
       
   132 ScriptCall('onHogRestore', HH^.Gear^.Uid)
   104 end;
   133 end;
   105 
   134 
   106 ////////////////////////////////////////////////////////////////////////////////
   135 ////////////////////////////////////////////////////////////////////////////////
   107 procedure doStepDrowningGear(Gear: PGear);
   136 procedure doStepDrowningGear(Gear: PGear);
   108 forward;
   137 forward;
   481 procedure doStepMolotov(Gear: PGear);
   510 procedure doStepMolotov(Gear: PGear);
   482 var 
   511 var 
   483     i, gX, gY: LongInt;
   512     i, gX, gY: LongInt;
   484     dX, dY: hwFloat;
   513     dX, dY: hwFloat;
   485     Fire: PGear;
   514     Fire: PGear;
       
   515     smoke, glass: PVisualGear;
   486 begin
   516 begin
   487     AllInactive := false;
   517     AllInactive := false;
   488 
   518 
   489     doStepFallingGear(Gear);
   519     doStepFallingGear(Gear);
   490     CalcRotationDirAngle(Gear);
   520     CalcRotationDirAngle(Gear);
       
   521 
       
   522     // let's add some smoke depending on speed
       
   523     i:= max(32,152 - hwRound(Distance(Gear^.dX,Gear^.dY)*120))+random(10);
       
   524     if (GameTicks mod i) = 0 then
       
   525         begin
       
   526         // adjust angle to match the texture
       
   527         if Gear^.dX.isNegative then i:= 130 else i:= 50;
       
   528         smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
       
   529         if smoke <> nil then smoke^.Scale:= 0.75;
       
   530         end;
   491 
   531 
   492     if (Gear^.State and gstCollision) <> 0 then
   532     if (Gear^.State and gstCollision) <> 0 then
   493     begin
   533     begin
   494         PlaySound(sndMolotov);
   534         PlaySound(sndMolotov);
   495         gX := hwRound(Gear^.X);
   535         gX := hwRound(Gear^.X);
   496         gY := hwRound(Gear^.Y);
   536         gY := hwRound(Gear^.Y);
   497         //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound);
   537         for i:= 0 to 2 do
       
   538             begin
       
   539             glass:= AddVisualGear(gx+random(7)-3, gy+random(5)-2, vgtEgg);
       
   540             if glass <> nil then
       
   541                 begin
       
   542                 glass^.Frame:= 2;
       
   543                 glass^.Tint:= $41B83ED0 - i * $10081000;
       
   544                 glass^.dX:= 1/(10*(random(11)-5));
       
   545                 glass^.dY:= -1/(random(4)+5);
       
   546                 end;
       
   547             end;
   498         for i:= 0 to 24 do
   548         for i:= 0 to 24 do
   499         begin
   549         begin
   500             dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandom + _1);
   550             dX := AngleCos(i * 2) * ((_0_15*(i div 5))) * (GetRandom + _1);
   501             dY := AngleSin(i * 8) * _0_5 * (GetRandom + _1);
   551             dY := AngleSin(i * 8) * _0_5 * (GetRandom + _1);
   502             Fire := AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
   552             Fire := AddGear(gX, gY, gtFlame, 0, dX, dY, 0);
   764 
   814 
   765 ////////////////////////////////////////////////////////////////////////////////
   815 ////////////////////////////////////////////////////////////////////////////////
   766 procedure doStepBeeWork(Gear: PGear);
   816 procedure doStepBeeWork(Gear: PGear);
   767 var 
   817 var 
   768     t: hwFloat;
   818     t: hwFloat;
   769     gX,gY: LongInt;
   819     gX,gY,i: LongInt;
   770     nuw: boolean;
   820     nuw: boolean;
       
   821     flower: PVisualGear;
   771 
   822 
   772 const uw: boolean =   false;
   823 const uw: boolean =   false;
   773 begin
   824 begin
   774     AllInactive := false;
   825     AllInactive := false;
   775     gX := hwRound(Gear^.X);
   826     gX := hwRound(Gear^.X);
   814     dec(Gear^.Timer);
   865     dec(Gear^.Timer);
   815     if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then
   866     if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then
   816     begin
   867     begin
   817         StopSound(Gear^.SoundChannel);
   868         StopSound(Gear^.SoundChannel);
   818         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   869         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
       
   870         for i:= 0 to 31 do
       
   871             begin
       
   872             flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot);
       
   873             if flower <> nil then 
       
   874                 with flower^ do
       
   875                     begin
       
   876                     Scale:= 0.75;
       
   877                     dx:= 0.001 * (random(200));
       
   878                     dy:= 0.001 * (random(200));
       
   879                     if random(2) = 0 then dx := -dx;
       
   880                     if random(2) = 0 then dy := -dy;
       
   881                     FrameTicks:= random(250) + 250;
       
   882                     State:= ord(sprTargetBee);
       
   883                     end;
       
   884             end;
   819         DeleteGear(Gear);
   885         DeleteGear(Gear);
   820     end;
   886     end;
   821 end;
   887 end;
   822 
   888 
   823 procedure doStepBee(Gear: PGear);
   889 procedure doStepBee(Gear: PGear);
   912         then
   978         then
   913         Gear^.doStep := @doStepShotIdle
   979         Gear^.doStep := @doStepShotIdle
   914 end;
   980 end;
   915 
   981 
   916 ////////////////////////////////////////////////////////////////////////////////
   982 ////////////////////////////////////////////////////////////////////////////////
       
   983 procedure spawnBulletTrail(Bullet: PGear);
       
   984 var oX, oY: hwFloat;
       
   985     VGear: PVisualGear;
       
   986 begin
       
   987     if Bullet^.PortalCounter = 0 then
       
   988         begin
       
   989         ox:= CurrentHedgehog^.Gear^.X + Int2hwFloat(GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle));
       
   990         oy:= CurrentHedgehog^.Gear^.Y + Int2hwFloat(GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle));
       
   991         end
       
   992     else
       
   993         begin
       
   994         ox:= Bullet^.Elasticity;
       
   995         oy:= Bullet^.Friction;
       
   996         end;
       
   997 
       
   998         // Bullet trail
       
   999         VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
       
  1000         if VGear <> nil then
       
  1001             begin
       
  1002             VGear^.X:= hwFloat2Float(ox);
       
  1003             VGear^.Y:= hwFloat2Float(oy);
       
  1004             VGear^.dX:= hwFloat2Float(Bullet^.X);
       
  1005             VGear^.dY:= hwFloat2Float(Bullet^.Y);
       
  1006 
       
  1007             // reached edge of land. assume infinite beam. Extend it way out past camera
       
  1008             if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
       
  1009                 or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
       
  1010                     // only extend if not under water
       
  1011                     if hwRound(Bullet^.Y) < cWaterLine then
       
  1012                         begin
       
  1013                         VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X);
       
  1014                         VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y);
       
  1015                         end;
       
  1016 
       
  1017             VGear^.Timer := 200;
       
  1018             end;
       
  1019 end;
       
  1020 
   917 procedure doStepBulletWork(Gear: PGear);
  1021 procedure doStepBulletWork(Gear: PGear);
   918 var 
  1022 var 
   919     i, x, y: LongWord;
  1023     i, x, y: LongWord;
   920     oX, oY: hwFloat;
  1024     oX, oY: hwFloat;
   921     VGear: PVisualGear;
  1025     VGear: PVisualGear;
   930         Gear^.Y := Gear^.Y + Gear^.dY;
  1034         Gear^.Y := Gear^.Y + Gear^.dY;
   931         x := hwRound(Gear^.X);
  1035         x := hwRound(Gear^.X);
   932         y := hwRound(Gear^.Y);
  1036         y := hwRound(Gear^.Y);
   933         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
  1037         if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
   934            and (Land[y, x] <> 0) then inc(Gear^.Damage);
  1038            and (Land[y, x] <> 0) then inc(Gear^.Damage);
       
  1039         // let's interrupt before a collision to give portals a chance to catch the bullet
       
  1040         if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then
       
  1041         begin
       
  1042             Gear^.Tag := 1;
       
  1043             Gear^.Damage := 0;
       
  1044             Gear^.X := Gear^.X - Gear^.dX;
       
  1045             Gear^.Y := Gear^.Y - Gear^.dY;
       
  1046             CheckGearDrowning(Gear);
       
  1047             break;
       
  1048         end
       
  1049         else
       
  1050             Gear^.Tag := 0;
       
  1051 
   935         if Gear^.Damage > 5 then
  1052         if Gear^.Damage > 5 then
   936             if Gear^.AmmoType = amDEagle then
  1053             if Gear^.AmmoType = amDEagle then
   937                 AmmoShove(Gear, 7, 20)
  1054                 AmmoShove(Gear, 7, 20)
   938         else
  1055         else
   939             AmmoShove(Gear, Gear^.Timer, 20);
  1056             AmmoShove(Gear, Gear^.Timer, 20);
   975             begin
  1092             begin
   976                 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
  1093                 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
   977             end;
  1094             end;
   978         end;
  1095         end;
   979        
  1096        
   980         if Gear^.PortalCounter = 0 then
  1097         spawnBulletTrail(Gear);
   981             begin 
       
   982             // Bullet trail
       
   983             VGear := AddVisualGear(
       
   984                 hwround(CurrentHedgehog^.Gear^.X) + GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle), 
       
   985                 hwround(CurrentHedgehog^.Gear^.Y) + GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle),
       
   986                 vgtLineTrail
       
   987             );
       
   988             if VGear <> nil then
       
   989                 begin
       
   990                 // http://mantis.freepascal.org/view.php?id=17714 hits again
       
   991                 VGear^.dX := Gear^.X.QWordValue / SignAs(_1,_1).QWordValue;
       
   992                 VGear^.dY := Gear^.Y.QWordValue / SignAs(_1,_1).QWordValue;
       
   993                 
       
   994                 // reached edge of land. assume infinite beam. Extend it way out past camera
       
   995                 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) 
       
   996                     or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then
       
   997                     begin
       
   998                     VGear^.dX := VGear^.dX + (CurrentHedgehog^.Gear^.dX * LAND_WIDTH).QWordValue / SignAs(_1,_1).QWordValue;
       
   999                     VGear^.dY := VGear^.dY + (CurrentHedgehog^.Gear^.dY * LAND_WIDTH).QWordValue / SignAs(_1,_1).QWordValue;
       
  1000                     end;
       
  1001                 
       
  1002                 VGear^.Timer := 200;
       
  1003                 end
       
  1004             end;
       
  1005         Gear^.doStep := @doStepShotIdle
  1098         Gear^.doStep := @doStepShotIdle
  1006     end;
  1099     end;
  1007 end;
  1100 end;
  1008 
  1101 
  1009 procedure doStepDEagleShot(Gear: PGear);
  1102 procedure doStepDEagleShot(Gear: PGear);
  1108     HHGear: PGear;
  1201     HHGear: PGear;
  1109 begin
  1202 begin
  1110     AllInactive := false;
  1203     AllInactive := false;
  1111     HHGear := Gear^.Hedgehog^.Gear;
  1204     HHGear := Gear^.Hedgehog^.Gear;
  1112     dec(Gear^.Timer);
  1205     dec(Gear^.Timer);
  1113     if (Gear^.Timer = 0)or((Gear^.Message and gmDestroy) <> 0)or((HHGear^.State and gstHHDriven) =
  1206     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then dec(TurnTimeLeft);
       
  1207     if (TurnTimeLeft = 0) or (Gear^.Timer = 0)or((Gear^.Message and gmDestroy) <> 0)or((HHGear^.State and gstHHDriven) =
  1114        0) then
  1208        0) then
  1115         begin
  1209         begin
  1116         StopSound(Gear^.SoundChannel);
  1210         StopSound(Gear^.SoundChannel);
  1117         DeleteGear(Gear);
  1211         DeleteGear(Gear);
  1118         AfterAttack;
  1212         AfterAttack;
  1217     b: boolean;
  1311     b: boolean;
  1218     prevX: LongInt;
  1312     prevX: LongInt;
  1219 begin
  1313 begin
  1220     AllInactive := false;
  1314     AllInactive := false;
  1221     dec(Gear^.Timer);
  1315     dec(Gear^.Timer);
       
  1316     if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then dec(TurnTimeLeft);
       
  1317     
  1222     HHGear := Gear^.Hedgehog^.Gear;
  1318     HHGear := Gear^.Hedgehog^.Gear;
  1223 
  1319 
  1224     HedgehogChAngle(HHGear);
  1320     HedgehogChAngle(HHGear);
  1225 
  1321 
  1226     b := false;
  1322     b := false;
  1227 
  1323 
  1228     if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7  then
  1324     if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7  then
  1229     begin
  1325         begin
  1230         Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX);
  1326         Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
  1231         Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
  1327         Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
  1232         BTPrevAngle := HHGear^.Angle;
  1328         BTPrevAngle := HHGear^.Angle;
  1233         b := true
  1329         b := true
  1234     end;
  1330         end;
  1235 
  1331 
  1236     if ((HHGear^.State and gstMoving) <> 0) then
  1332     if ((HHGear^.State and gstMoving) <> 0) then
  1237     begin
  1333         begin
  1238         doStepHedgehogMoving(HHGear);
  1334         doStepHedgehogMoving(HHGear);
  1239         if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer := 0
  1335         if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer := 0
  1240     end;
  1336         end;
  1241 
  1337 
  1242     if Gear^.Timer mod cHHStepTicks = 0 then
  1338     if Gear^.Timer mod cHHStepTicks = 0 then
  1243     begin
  1339         begin
  1244         b := true;
  1340         b := true;
  1245         if Gear^.dX.isNegative then
  1341         if Gear^.dX.isNegative then
  1246             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmLeft
  1342             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmLeft
  1247         else
  1343         else
  1248             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
  1344             HHGear^.Message := (HHGear^.Message and (gmAttack or gmUp or gmDown)) or gmRight;
  1249 
  1345 
  1250         if ((HHGear^.State and gstMoving) = 0) then
  1346         if ((HHGear^.State and gstMoving) = 0) then
  1251         begin
  1347             begin
  1252             HHGear^.State := HHGear^.State and not gstAttacking;
  1348             HHGear^.State := HHGear^.State and not gstAttacking;
  1253             prevX := hwRound(HHGear^.X);
  1349             prevX := hwRound(HHGear^.X);
  1254 
  1350 
  1255             // why the call to HedgehogStep then a further increment of X?
  1351             // why the call to HedgehogStep then a further increment of X?
  1256             if (prevX = hwRound(HHGear^.X)) and
  1352             if (prevX = hwRound(HHGear^.X)) and
  1259 
  1355 
  1260             if (prevX = hwRound(HHGear^.X)) and
  1356             if (prevX = hwRound(HHGear^.X)) and
  1261                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
  1357                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
  1262                lfIndestructible) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
  1358                lfIndestructible) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
  1263             HHGear^.State := HHGear^.State or gstAttacking
  1359             HHGear^.State := HHGear^.State or gstAttacking
  1264         end;
  1360             end;
  1265 
  1361 
  1266         inc(BTSteps);
  1362         inc(BTSteps);
  1267         if BTSteps = 7 then
  1363         if BTSteps = 7 then
  1268         begin
  1364             begin
  1269             BTSteps := 0;
  1365             BTSteps := 0;
  1270             if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,
  1366             if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,
  1271                Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),
  1367                Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),
  1272                lfIndestructible) then
  1368                lfIndestructible) then
  1273             begin
  1369                 begin
  1274                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
  1370                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
  1275                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
  1371                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
  1276             end;
  1372                 end;
  1277             HHGear^.State := HHGear^.State or gstNoDamage;
  1373             HHGear^.State := HHGear^.State or gstNoDamage;
  1278             AmmoShove(Gear, 2, 15);
  1374             AmmoShove(Gear, 2, 15);
  1279             HHGear^.State := HHGear^.State and not gstNoDamage
  1375             HHGear^.State := HHGear^.State and not gstNoDamage
  1280         end;
  1376             end;
  1281     end;
  1377         end;
  1282 
  1378 
  1283     if b then
  1379     if b then
  1284         DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(
  1380         DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(
  1285                    Gear^.dY) * 7,
  1381                    Gear^.dY) * 7,
  1286         Gear^.dX, Gear^.dY,
  1382         Gear^.dX, Gear^.dY,
  1287         cHHRadius * 5, cHHRadius * 2 + 7);
  1383         cHHRadius * 5, cHHRadius * 2 + 7);
  1288 
  1384 
  1289     if (Gear^.Timer = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  1385     if (TurnTimeLeft = 0) or (Gear^.Timer = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  1290     begin
  1386         begin
  1291         HHGear^.Message := 0;
  1387         HHGear^.Message := 0;
  1292         HHGear^.State := HHGear^.State and (not gstNotKickable);
  1388         HHGear^.State := HHGear^.State and (not gstNotKickable);
  1293         DeleteGear(Gear);
  1389         DeleteGear(Gear);
  1294         AfterAttack
  1390         AfterAttack
  1295     end
  1391         end
  1296 end;
  1392 end;
  1297 
  1393 
  1298 procedure doStepBlowTorch(Gear: PGear);
  1394 procedure doStepBlowTorch(Gear: PGear);
  1299 var 
  1395 var 
  1300     HHGear: PGear;
  1396     HHGear: PGear;
  1355 
  1451 
  1356 procedure doStepRopeWork(Gear: PGear);
  1452 procedure doStepRopeWork(Gear: PGear);
  1357 var 
  1453 var 
  1358     HHGear: PGear;
  1454     HHGear: PGear;
  1359     len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
  1455     len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
  1360     lx, ly: LongInt;
  1456     lx, ly, cd: LongInt;
  1361     haveCollision,
  1457     haveCollision,
  1362     haveDivided: boolean;
  1458     haveDivided: boolean;
  1363 
  1459 
  1364 procedure DeleteMe;
  1460 procedure DeleteMe;
  1365 begin
  1461 begin
  1396 
  1492 
  1397     if (Gear^.Message and gmLeft  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1493     if (Gear^.Message and gmLeft  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1398     else
  1494     else
  1399         if (Gear^.Message and gmRight <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1495         if (Gear^.Message and gmRight <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1400 
  1496 
  1401     if not TestCollisionYwithGear(HHGear, 1) then
       
  1402         begin
       
  1403         HHGear^.dY := HHGear^.dY + cGravity;
       
  1404         if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
       
  1405         end;
       
  1406 
       
  1407     // vector between hedgehog and rope attaching point
  1497     // vector between hedgehog and rope attaching point
  1408     ropeDx := HHGear^.X - Gear^.X;
  1498     ropeDx := HHGear^.X - Gear^.X;
  1409     ropeDy := HHGear^.Y - Gear^.Y;
  1499     ropeDy := HHGear^.Y - Gear^.Y;
       
  1500 
       
  1501     if not TestCollisionYwithGear(HHGear, 1) then
       
  1502         begin
       
  1503 
       
  1504         // depending on the rope vector we know which X-side to check for collision
       
  1505         // in order to find out if the hog can still be moved by gravity
       
  1506         if ropeDx.isNegative = RopeDy.IsNegative then
       
  1507             cd:= -1
       
  1508         else
       
  1509             cd:= 1;
       
  1510 
       
  1511         // apply gravity if there is no obstacle
       
  1512         if not TestCollisionXwithGear(HHGear, cd) then
       
  1513             HHGear^.dY := HHGear^.dY + cGravity;
       
  1514 
       
  1515         if (GameFlags and gfMoreWind) <> 0 then
       
  1516             // apply wind if there's no obstacle
       
  1517             if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then
       
  1518                 HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
       
  1519         end;
  1410 
  1520 
  1411     mdX := ropeDx + HHGear^.dX;
  1521     mdX := ropeDx + HHGear^.dX;
  1412     mdY := ropeDy + HHGear^.dY;
  1522     mdY := ropeDy + HHGear^.dY;
  1413     len := _1 / Distance(mdX, mdY);
  1523     len := _1 / Distance(mdX, mdY);
  1414     // rope vector plus hedgehog direction vector normalized
  1524     // rope vector plus hedgehog direction vector normalized
  2601         PlaySound(sndSwitchHog);
  2711         PlaySound(sndSwitchHog);
  2602 
  2712 
  2603         repeat
  2713         repeat
  2604             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.
  2714             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.
  2605                                          HedgehogsNumber);
  2715                                          HedgehogsNumber);
  2606         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
  2716         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
  2607 
  2717 
  2608         CurrentHedgehog := @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog];
  2718         CurrentHedgehog := @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog];
  2609 
  2719 
  2610         HHGear := CurrentHedgehog^.Gear;
  2720         HHGear := CurrentHedgehog^.Gear;
  2611         HHGear^.State := State;
  2721         HHGear^.State := State;
  2672 
  2782 
  2673 const upd: Longword =   0;
  2783 const upd: Longword =   0;
  2674 var 
  2784 var 
  2675     i: LongWord;
  2785     i: LongWord;
  2676     HHGear: PGear;
  2786     HHGear: PGear;
       
  2787     sparkles: PVisualGear;
  2677 begin
  2788 begin
  2678     AllInactive := false;
  2789     AllInactive := false;
  2679 
  2790 
  2680     HHGear := Gear^.Hedgehog^.Gear;
  2791     HHGear := Gear^.Hedgehog^.Gear;
  2681     HHGear^.State := HHGear^.State or gstNoDamage;
  2792     HHGear^.State := HHGear^.State or gstNoDamage;
  2682     DeleteCI(HHGear);
  2793     DeleteCI(HHGear);
  2683 
  2794 
  2684     Gear^.X := HHGear^.X;
  2795     Gear^.X := HHGear^.X;
  2685     Gear^.Y := HHGear^.Y;
  2796     Gear^.Y := HHGear^.Y;
       
  2797     if (GameTicks mod 2 = 0) and ((Gear^.Message and (gmPrecise or gmSwitch)) = (gmPrecise or gmSwitch)) then
       
  2798         begin
       
  2799         sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust, 1);
       
  2800         if sparkles <> nil then sparkles^.Tint:= ((random(210)+45) shl 24) or ((random(210)+45) shl 16) or ((random(210)+45) shl 8) or $FF;
       
  2801         end;
  2686 
  2802 
  2687     i := 2;
  2803     i := 2;
  2688     repeat
  2804     repeat
       
  2805         
  2689         Gear^.X := Gear^.X + HHGear^.dX;
  2806         Gear^.X := Gear^.X + HHGear^.dX;
  2690         Gear^.Y := Gear^.Y + HHGear^.dY;
  2807         Gear^.Y := Gear^.Y + HHGear^.dY;
  2691         HHGear^.X := Gear^.X;
  2808         HHGear^.X := Gear^.X;
  2692         HHGear^.Y := Gear^.Y;
  2809         HHGear^.Y := Gear^.Y;
  2693 
  2810 
  2882         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2999         Gear^.DirAngle := DxDy2Angle(tdx, tdy);
  2883     end;
  3000     end;
  2884 
  3001 
  2885     dec(Gear^.Health);
  3002     dec(Gear^.Health);
  2886     Gear^.Timer := Gear^.Health*10;
  3003     Gear^.Timer := Gear^.Health*10;
  2887     Gear^.PortalCounter:= 0;
  3004     if Gear^.Health mod 100 = 0 then Gear^.PortalCounter:= 0;
  2888     // This is not seconds, but at least it is *some* feedback
  3005     // This is not seconds, but at least it is *some* feedback
  2889     if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
  3006     if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then
  2890     begin
  3007     begin
  2891         FollowGear := Gear;
  3008         FollowGear := Gear;
  2892         Gear^.RenderTimer := false;
  3009         Gear^.RenderTimer := false;
  2947     Gear^.doStep := @doStepCakeFall
  3064     Gear^.doStep := @doStepCakeFall
  2948 end;
  3065 end;
  2949 
  3066 
  2950 ////////////////////////////////////////////////////////////////////////////////
  3067 ////////////////////////////////////////////////////////////////////////////////
  2951 procedure doStepSeductionWork(Gear: PGear);
  3068 procedure doStepSeductionWork(Gear: PGear);
  2952 var 
  3069 var i: LongInt;
  2953     x, y, i: LongInt;
       
  2954     hogs: TPGearArray;
  3070     hogs: TPGearArray;
  2955     d: hwFloat;
       
  2956 begin
  3071 begin
  2957     AllInactive := false;
  3072     AllInactive := false;
  2958     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
  3073     hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
  2959     if Length(hogs) > 0 then
  3074     if Length(hogs) > 0 then
  2960         begin
  3075         begin
  3019                 dx:= 0.001 * (random(200));
  3134                 dx:= 0.001 * (random(200));
  3020                 dy:= 0.001 * (random(200));
  3135                 dy:= 0.001 * (random(200));
  3021                 if random(2) = 0 then dx := -dx;
  3136                 if random(2) = 0 then dx := -dx;
  3022                 if random(2) = 0 then dy := -dy;
  3137                 if random(2) = 0 then dy := -dy;
  3023                 FrameTicks:= random(750) + 1000;
  3138                 FrameTicks:= random(750) + 1000;
  3024                 heart^.State:= ord(sprSeduction)
  3139                 State:= ord(sprSeduction)
  3025                 end;
  3140                 end;
  3026         end;
  3141         end;
  3027 
  3142 
  3028     if Gear^.Pos = 15 then
  3143     if Gear^.Pos = 15 then
  3029         Gear^.doStep := @doStepSeductionWork
  3144         Gear^.doStep := @doStepSeductionWork
  3676         Gear^.Tag := 1;
  3791         Gear^.Tag := 1;
  3677     Gear^.Pos := 0;
  3792     Gear^.Pos := 0;
  3678     AllInactive := false;
  3793     AllInactive := false;
  3679     FollowGear := HHGear;
  3794     FollowGear := HHGear;
  3680     with HHGear^ do
  3795     with HHGear^ do
  3681     begin
  3796         begin
  3682         State := State and not gstAttacking;
  3797         State := State and not gstAttacking;
  3683         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight)
  3798         Message := Message and not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight)
  3684     end
  3799         end
  3685 end;
  3800 end;
  3686 
  3801 
  3687 ////////////////////////////////////////////////////////////////////////////////
  3802 ////////////////////////////////////////////////////////////////////////////////
  3688 procedure doStepEggWork(Gear: PGear);
  3803 procedure doStepEggWork(Gear: PGear);
  3689 var 
  3804 var 
  3864 
  3979 
  3865             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  3980             if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then
  3866                 continue;
  3981                 continue;
  3867         end;
  3982         end;
  3868 
  3983 
       
  3984         // draw bullet trail
       
  3985         if isbullet then
       
  3986             spawnBulletTrail(iterator);
       
  3987 
  3869         // calc gear offset in portal vector direction
  3988         // calc gear offset in portal vector direction
  3870         ox := (iterator^.X - Gear^.X);
  3989         ox := (iterator^.X - Gear^.X);
  3871         oy := (iterator^.Y - Gear^.Y);
  3990         oy := (iterator^.Y - Gear^.Y);
  3872         poffs:= (Gear^.dX * ox + Gear^.dY * oy);
  3991         poffs:= (Gear^.dX * ox + Gear^.dY * oy);
  3873 
  3992 
  3874         if poffs < _0 then
  3993         if not isBullet and poffs.isNegative then
       
  3994             continue;
       
  3995 
       
  3996         // only port bullets close to the portal
       
  3997         if isBullet and not (hwAbs(poffs) < _3) then
  3875             continue;
  3998             continue;
  3876 
  3999 
  3877         //
  4000         //
  3878         // gears that make it till here will definately be ported
  4001         // gears that make it till here will definately be ported
  3879         //
  4002         //
  3897             ny.isNegative := not ny.isNegative;
  4020             ny.isNegative := not ny.isNegative;
  3898 
  4021 
  3899         // calc gear offset in portal normal vector direction
  4022         // calc gear offset in portal normal vector direction
  3900         noffs:= (nx * ox + ny * oy);
  4023         noffs:= (nx * ox + ny * oy);
  3901 
  4024 
       
  4025         if isBullet and (hwRound(hwAbs(noffs)) >= Gear^.Radius) then
       
  4026             continue;
       
  4027 
  3902         // avoid gravity related loops of not really moving gear
  4028         // avoid gravity related loops of not really moving gear
  3903         if not iscake and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative)
  4029         if not (iscake or isbullet) and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative)
  3904             and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
  4030             and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue)
  3905             and (iterator^.PortalCounter > 0) then
  4031             and (iterator^.PortalCounter > 0) then
  3906              continue;
  4032              continue;
  3907 
  4033 
  3908         // calc gear speed along to the vector and the normal vector of the portal
  4034         // calc gear speed along to the vector and the normal vector of the portal
  3925         else
  4051         else
  3926             ny.isNegative := not ny.isNegative;
  4052             ny.isNegative := not ny.isNegative;
  3927 
  4053 
  3928         // inverse cake's normal movement direction,
  4054         // inverse cake's normal movement direction,
  3929         // as if it just walked through a hole
  4055         // as if it just walked through a hole
  3930         if iscake then
  4056         //if iscake then nspeed.isNegative:= not nspeed.isNegative;
  3931             nspeed.isNegative:= not nspeed.isNegative;
       
  3932 
  4057 
  3933 //AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed));
  4058 //AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed));
  3934         iterator^.dX := -pspeed * conPortal^.dX + nspeed * nx;
  4059         iterator^.dX := -pspeed * conPortal^.dX + nspeed * nx;
  3935         iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny;
  4060         iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny;
  3936 
  4061 
  3977 
  4102 
  3978             if iterator^.Radius > 1 then
  4103             if iterator^.Radius > 1 then
  3979                 iterator^.Radius := iterator^.Radius - 1;
  4104                 iterator^.Radius := iterator^.Radius - 1;
  3980 
  4105 
  3981             // check front
  4106             // check front
  3982             isCollision := TestCollisionYwithGear(iterator, sy)
  4107             isCollision := TestCollisionY(iterator, sy)
  3983                         or TestCollisionXwithGear(iterator, sx);
  4108                         or TestCollisionX(iterator, sx);
  3984 
  4109 
  3985             if not isCollision then
  4110             if not isCollision then
  3986             begin
  4111             begin
  3987                 // check center area (with half the radius so that the
  4112                 // check center area (with half the radius so that the
  3988                 // the square check won't check more pixels than we want to)
  4113                 // the square check won't check more pixels than we want to)
  3989                 iterator^.Radius := 1 + resetr div 2;
  4114                 iterator^.Radius := 1 + resetr div 2;
  3990                 rh := resetr div 4;
  4115                 rh := resetr div 4;
  3991                 isCollision := TestCollisionYwithXYShift(iterator,       0, -sy * rh, sy)
  4116                 isCollision := TestCollisionYwithXYShift(iterator,       0, -sy * rh, sy, false)
  3992                             or TestCollisionXwithXYShift(iterator, ox * rh,        0, sx);
  4117                             or TestCollisionXwithXYShift(iterator, ox * rh,        0, sx, false);
  3993             end;
  4118             end;
  3994 
  4119 
  3995             iterator^.Radius := resetr;
  4120             iterator^.Radius := resetr;
  3996 
  4121 
  3997             if isCollision then
  4122             if isCollision then
  4008         //
  4133         //
  4009         // You're now officially portaled!
  4134         // You're now officially portaled!
  4010         //
  4135         //
  4011 
  4136 
  4012         // Until loops are reliably broken
  4137         // Until loops are reliably broken
  4013         inc(iterator^.PortalCounter);
  4138         if iscake then iterator^.PortalCounter:= 33
       
  4139         else inc(iterator^.PortalCounter);
  4014 
  4140 
  4015         if not isbullet and (iterator^.Kind <> gtFlake) then
  4141         if not isbullet and (iterator^.Kind <> gtFlake) then
  4016             FollowGear := iterator;
  4142             FollowGear := iterator;
       
  4143 
       
  4144         // store X/Y values of exit for net bullet trail
       
  4145         if isbullet then
       
  4146         begin
       
  4147             iterator^.Elasticity:= iterator^.X;
       
  4148             iterator^.Friction  := iterator^.Y;
       
  4149         end;
  4017 
  4150 
  4018         // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
  4151         // This jiggles gears, to ensure a portal connection just placed under a gear takes effect.
  4019         iterator:= GearsList;
  4152         iterator:= GearsList;
  4020         while iterator <> nil do
  4153         while iterator <> nil do
  4021             begin
  4154             begin
  4074 
  4207 
  4075     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  4208     if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then
  4076     begin
  4209     begin
  4077         Gear^.State := Gear^.State or gstCollision;
  4210         Gear^.State := Gear^.State or gstCollision;
  4078         Gear^.State := Gear^.State and not gstMoving;
  4211         Gear^.State := Gear^.State and not gstMoving;
  4079         if not calcSlopeTangent(Gear, x, y, tx, ty, 255)
  4212         if not CalcSlopeTangent(Gear, x, y, tx, ty, 255)
  4080            or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4213            or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
  4081         begin
  4214         begin
  4082             loadNewPortalBall(Gear, true);
  4215             loadNewPortalBall(Gear, true);
  4083             EXIT;
  4216             EXIT;
  4084         end;
  4217         end;
  4900         doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound);
  5033         doMakeExplosion(x, y, 50, CurrentHedgehog, EXPLAutoSound);
  4901         end;
  5034         end;
  4902 end;
  5035 end;
  4903 
  5036 
  4904 ////////////////////////////////////////////////////////////////////////////////
  5037 ////////////////////////////////////////////////////////////////////////////////
       
  5038 (*
       
  5039  TARDIS needs 
       
  5040  Warp in.  Pos = 1
       
  5041  Pause.    Pos = 2
       
  5042  Hide gear  (TARDIS hedgehog was nil)
       
  5043  Warp out. Pos = 3
       
  5044  ... idle active for some time period ...  Pos = 4
       
  5045  Warp in.  Pos = 1
       
  5046  Pause.    Pos = 2
       
  5047  Restore gear  (TARDIS hedgehog was not nil)
       
  5048  Warp out. Pos = 3
       
  5049 *)
       
  5050 
       
  5051 procedure doStepTardisWarp(Gear: PGear);
       
  5052 var HH: PHedgehog;
       
  5053     i,j,cnt: LongWord;
       
  5054 begin
       
  5055 
       
  5056 HH:= Gear^.Hedgehog;
       
  5057 if Gear^.Pos = 2 then
       
  5058     begin
       
  5059     StopSound(Gear^.SoundChannel);
       
  5060     if (Gear^.Timer = 0) then
       
  5061         begin
       
  5062         if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible = 0) then
       
  5063             begin
       
  5064 	        AfterAttack;
       
  5065             if Gear = CurAmmoGear then CurAmmoGear := nil;
       
  5066             HideHog(HH)
       
  5067             end
       
  5068         //else if (HH^.Gear <> nil) and (HH^.Gear^.State and gstInvisible <> 0) then
       
  5069         else if (HH^.GearHidden <> nil) then// and (HH^.Gear^.State and gstInvisible <> 0) then
       
  5070             RestoreHog(HH)
       
  5071         end;
       
  5072 
       
  5073     inc(Gear^.Timer);
       
  5074     if (Gear^.Timer > 2000) and ((GameTicks mod 2000) = 1000) then
       
  5075         begin
       
  5076         Gear^.SoundChannel := LoopSound(sndTardis);
       
  5077         Gear^.Pos:= 3
       
  5078         end
       
  5079     end;
       
  5080 
       
  5081 if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then inc(Gear^.Power);
       
  5082 if (Gear^.Pos = 3) and (GameTicks and $1F = 0) and (Gear^.Power > 0) then dec(Gear^.Power);
       
  5083 if (Gear^.Pos = 1) and (Gear^.Power = 255) and ((GameTicks mod 2000) = 1000) then Gear^.Pos:= 2;
       
  5084 if (Gear^.Pos = 3) and (Gear^.Power = 0) then
       
  5085     begin
       
  5086     StopSound(Gear^.SoundChannel);
       
  5087     if HH^.GearHidden = nil then
       
  5088         begin
       
  5089         DeleteGear(Gear);
       
  5090         exit
       
  5091         end;
       
  5092     Gear^.Pos:= 4;
       
  5093     // This condition might need tweaking
       
  5094     Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime
       
  5095     end;
       
  5096 
       
  5097 if (Gear^.Pos = 4) then
       
  5098     begin
       
  5099     cnt:= 0;
       
  5100     for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
       
  5101         for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
       
  5102             if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil) and
       
  5103                ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0) and
       
  5104                (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health >
       
  5105                 HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then inc(cnt);
       
  5106     if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then
       
  5107         begin
       
  5108         Gear^.SoundChannel := LoopSound(sndTardis);
       
  5109         Gear^.Pos:= 1;
       
  5110         Gear^.Power:= 0;
       
  5111         Gear^.Timer:= 0;
       
  5112         if HH^.GearHidden <> nil then FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
       
  5113         if HH^.GearHidden <> nil then 
       
  5114             begin
       
  5115             Gear^.X:= HH^.GearHidden^.X;
       
  5116             Gear^.Y:= HH^.GearHidden^.Y;
       
  5117             //HH^.Gear:=HH^.GearHidden;
       
  5118             //HH^.GearHidden:= nil;
       
  5119             //HH^.Gear^.State:= HH^.Gear^.State or gstInvisible;
       
  5120             end
       
  5121         end
       
  5122     else dec(Gear^.Timer);
       
  5123     end;
       
  5124 
       
  5125 end;
       
  5126 
  4905 procedure doStepTardis(Gear: PGear);
  5127 procedure doStepTardis(Gear: PGear);
  4906 (*var 
  5128 var i,j,cnt: LongWord;
  4907     i, x, y: LongInt;
  5129     HH: PHedgehog;
  4908     dX, dY: hwFloat;
  5130 begin
  4909     Fire: PGear;
  5131 (*
  4910     vg: PVisualGear;*)
  5132     Conditions for not activating.
  4911 begin
  5133     1. Hog is last of his clan
  4912     if (Gear^.State and gstTmpFlag) = 0 then dec(Gear^.Timer);
  5134     2. Sudden Death is in play
  4913     if (Gear^.Timer = 0) and (CurAmmoGear = Gear) then
  5135     3. Hog is a king
  4914         begin
  5136 *)
  4915         if (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then 
  5137     HH:= Gear^.Hedgehog;
  4916             begin
  5138     if (HH^.Gear = nil) or (HH^.King) or (SuddenDeathDmg) then
  4917             DeleteGear(Gear);
  5139         begin
  4918             exit
  5140 	if HH^.Gear <> nil then 
  4919             end;
  5141 	    begin
  4920         if Gear = CurAmmoGear then CurAmmoGear := nil;
  5142 	    HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
  4921         Gear^.Hedgehog:= CurrentHedgehog;
  5143 	    HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
  4922         RemoveGearFromList(CurrentHedgehog^.Gear);
  5144 	    end;
  4923         CurrentHedgehog^.Gear^.Z := cHHZ;
  5145         PlaySound(sndDenied);
  4924         CurrentHedgehog^.Gear^.Active := false;
  5146         DeleteGear(gear);
  4925         CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and not gstHHDriven;
  5147         exit
  4926         CurrentHedgehog^.GearHidden:= CurrentHedgehog^.Gear;
  5148         end;
  4927         CurrentHedgehog^.Gear:= nil;
  5149     cnt:= 0;
  4928         Gear^.State:= Gear^.State or gstTmpFlag;
  5150     for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
  4929         Gear^.Timer:= GameTicks + GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime;
  5151         for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
  4930         end
  5152             if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil) and
  4931     else if (((Gear^.State and gstTmpFlag) <> 0) and (Gear^.Timer = GameTicks)) or SuddenDeath then
  5153                ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0) and
  4932         begin
  5154                (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health >
  4933         if Gear^.Hedgehog <> nil then
  5155                 HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then inc(cnt);
  4934             begin
  5156     if cnt < 2 then
  4935             Gear^.Hedgehog^.Gear:= Gear^.Hedgehog^.GearHidden;
  5157         begin
  4936             Gear^.Hedgehog^.GearHidden:= nil;
  5158 	if HH^.Gear <> nil then 
  4937             FindPlace(Gear^.Hedgehog^.Gear, false, 0, LAND_WIDTH,true);
  5159 	    begin
  4938             InsertGearToList(Gear^.Hedgehog^.Gear);
  5160 	    HH^.Gear^.Message := HH^.Gear^.Message and not gmAttack;
  4939             Gear^.Hedgehog^.Gear^.State:= (Gear^.Hedgehog^.Gear^.State or gstTmpFlag or gstAttacked) and not gstHHDriven;
  5161 	    HH^.Gear^.State:= HH^.Gear^.State and not gstAttacking;
  4940             Gear^.Hedgehog^.Gear^.Timer:= $FF;
  5162 	    end;
  4941             Gear^.Hedgehog^.Gear^.doStep:= @doStepHedgehogReturn;
  5163         PlaySound(sndDenied);
  4942             SetAllHHToActive;
  5164         DeleteGear(gear);
  4943             end;
  5165         exit
  4944             DeleteGear(Gear)
  5166         end;
  4945         end
  5167     Gear^.SoundChannel := LoopSound(sndTardis);
  4946 end;
  5168     Gear^.doStep:= @doStepTardisWarp
  4947 
  5169 end;
  4948 ////////////////////////////////////////////////////////////////////////////////
  5170 
  4949 
  5171 ////////////////////////////////////////////////////////////////////////////////
       
  5172