hedgewars/uGearsUtils.pas
branchios-develop
changeset 13418 ba39a1d396c0
parent 13412 06792533ef91
child 13573 470982c05f7e
equal deleted inserted replaced
13416:6e8b807bda4b 13418:ba39a1d396c0
    29 
    29 
    30 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
    30 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
    31 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
    31 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
    32 procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
    32 procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
    33 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
    33 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
       
    34 procedure HHHeal(Hedgehog: PHedgehog; healthBoost: Longword; showMessage: boolean; vgTint: Longword);
       
    35 procedure HHHeal(Hedgehog: PHedgehog; healthBoost: Longword; showMessage: boolean);
    34 procedure CheckHHDamage(Gear: PGear);
    36 procedure CheckHHDamage(Gear: PGear);
    35 procedure CalcRotationDirAngle(Gear: PGear);
    37 procedure CalcRotationDirAngle(Gear: PGear);
    36 procedure ResurrectHedgehog(var gear: PGear);
    38 procedure ResurrectHedgehog(var gear: PGear);
    37 
    39 
    38 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
    40 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
    39 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
    41 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
    40 
    42 
       
    43 function  CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
    41 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
    44 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
    42 function  CheckGearDrowning(var Gear: PGear): boolean;
    45 function  CheckGearDrowning(var Gear: PGear): boolean;
    43 procedure CheckCollision(Gear: PGear); inline;
    46 procedure CheckCollision(Gear: PGear); inline;
    44 procedure CheckCollisionWithLand(Gear: PGear); inline;
    47 procedure CheckCollisionWithLand(Gear: PGear); inline;
    45 
    48 
    46 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
    49 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
       
    50 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
    47 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    51 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    48 procedure SpawnBoxOfSmth;
    52 procedure SpawnBoxOfSmth;
    49 procedure ShotgunShot(Gear: PGear);
    53 procedure ShotgunShot(Gear: PGear);
    50 function  CanUseTardis(HHGear: PGear): boolean;
    54 function  CanUseTardis(HHGear: PGear): boolean;
    51 
    55 
   260 else
   264 else
   261     ModifyDamage:= hwRound(cDamageModifier * dmg * i * cDamagePercent * _0_01);
   265     ModifyDamage:= hwRound(cDamageModifier * dmg * i * cDamagePercent * _0_01);
   262 end;
   266 end;
   263 
   267 
   264 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
   268 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource);
   265 var s: ansistring;
   269 var vampDmg, tmpDmg, i: Longword;
   266     vampDmg, tmpDmg, i: Longword;
       
   267     vg: PVisualGear;
   270     vg: PVisualGear;
   268 begin
   271 begin
   269     if Damage = 0 then
   272     if Damage = 0 then
   270         exit; // nothing to apply
   273         exit; // nothing to apply
   271 
   274 
   285                 if vampDmg >= 1 then
   288                 if vampDmg >= 1 then
   286                     begin
   289                     begin
   287                     // was considering pulsing on attack, Tiy thinks it should be permanent while in play
   290                     // was considering pulsing on attack, Tiy thinks it should be permanent while in play
   288                     //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
   291                     //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
   289                     inc(CurrentHedgehog^.Gear^.Health,vampDmg);
   292                     inc(CurrentHedgehog^.Gear^.Health,vampDmg);
   290                     s:= IntToStr(vampDmg);
       
   291                     AddCaption(FormatA(trmsg[sidHealthGain], s), CurrentHedgehog^.Team^.Clan^.Color, capgrpAmmoinfo);
       
   292                     RenderHealth(CurrentHedgehog^);
   293                     RenderHealth(CurrentHedgehog^);
   293                     RecountTeamHealth(CurrentHedgehog^.Team);
   294                     RecountTeamHealth(CurrentHedgehog^.Team);
   294                     i:= 0;
   295                     HHHeal(CurrentHedgehog, vampDmg, true, $FF0000FF);
   295                     while (i < vampDmg) and (i < 1000) do
       
   296                         begin
       
   297                         vg:= AddVisualGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), vgtStraightShot);
       
   298                         if vg <> nil then
       
   299                             with vg^ do
       
   300                                 begin
       
   301                                 Tint:= $FF0000FF;
       
   302                                 State:= ord(sprHealth)
       
   303                                 end;
       
   304                         inc(i, 5);
       
   305                         end;
       
   306                     end
   296                     end
   307                 end;
   297                 end;
   308             if (GameFlags and gfKarma <> 0) and (GameFlags and gfInvulnerable = 0) and
   298             if (GameFlags and gfKarma <> 0) and (GameFlags and gfInvulnerable = 0) and
   309                (CurrentHedgehog^.Effects[heInvulnerable] = 0) then
   299                (CurrentHedgehog^.Effects[heInvulnerable] = 0) then
   310                 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
   300                 begin // this cannot just use Damage or it interrupts shotgun and gets you called stupid
   352     tag^.Hedgehog:= HHGear^.Hedgehog; // the tag needs the tag to determine the text color
   342     tag^.Hedgehog:= HHGear^.Hedgehog; // the tag needs the tag to determine the text color
   353 AllInactive:= false;
   343 AllInactive:= false;
   354 HHGear^.Active:= true;
   344 HHGear^.Active:= true;
   355 end;
   345 end;
   356 
   346 
       
   347 // Play effects for hurt hedgehog
   357 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
   348 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
   358 begin
   349 begin
   359 if Hedgehog^.Effects[heFrozen] <> 0 then exit;
   350 if Hedgehog^.Effects[heFrozen] <> 0 then exit;
   360 
   351 
   361 if (Source = dsFall) or (Source = dsExplosion) then
   352 if (Source = dsFall) or (Source = dsExplosion) then
   376         2: PlaySoundV(sndOw3, Hedgehog^.Team^.voicepack);
   367         2: PlaySoundV(sndOw3, Hedgehog^.Team^.voicepack);
   377         3: PlaySoundV(sndOw4, Hedgehog^.Team^.voicepack);
   368         3: PlaySoundV(sndOw4, Hedgehog^.Team^.voicepack);
   378     end
   369     end
   379 end;
   370 end;
   380 
   371 
       
   372 {-
       
   373 Show heal particles and message at hog gear.
       
   374 Hedgehog: Hedgehog which gets the health boost
       
   375 healthBoost: Amount of added health added
       
   376 showMessage: Whether to show announcer message
       
   377 vgTint: Tint of heal particle
       
   378 -}
       
   379 procedure HHHeal(Hedgehog: PHedgehog; healthBoost: Longword; showMessage: boolean; vgTint: Longword);
       
   380 var i: LongInt;
       
   381     vg: PVisualGear;
       
   382     s: ansistring;
       
   383 begin
       
   384     if healthBoost < 1 then
       
   385         exit;
       
   386 
       
   387     if showMessage then
       
   388         begin
       
   389         s:= IntToStr(healthBoost);
       
   390         AddCaption(FormatA(trmsg[sidHealthGain], s), Hedgehog^.Team^.Clan^.Color, capgrpAmmoinfo)
       
   391         end;
       
   392 
       
   393     i:= 0;
       
   394     // One particle for every 5 HP. Max. 200 particles
       
   395     while (i < healthBoost) and (i < 1000) do
       
   396         begin
       
   397         vg:= AddVisualGear(hwRound(Hedgehog^.Gear^.X), hwRound(Hedgehog^.Gear^.Y), vgtStraightShot);
       
   398         if vg <> nil then
       
   399             with vg^ do
       
   400                 begin
       
   401                 Tint:= vgTint;
       
   402                 State:= ord(sprHealth)
       
   403                 end;
       
   404         inc(i, 5)
       
   405         end;
       
   406 end;
       
   407 
       
   408 // Shorthand for the same above, but with tint implied
       
   409 procedure HHHeal(Hedgehog: PHedgehog; healthBoost: Longword; showMessage: boolean);
       
   410 begin
       
   411     HHHeal(Hedgehog, healthBoost, showMessage, $00FF00FF);
       
   412 end;
       
   413 
   381 procedure CheckHHDamage(Gear: PGear);
   414 procedure CheckHHDamage(Gear: PGear);
   382 var
   415 var
   383     dmg: LongInt;
   416     dmg: LongInt;
   384     i: LongWord;
   417     i: LongWord;
   385     particle: PVisualGear;
   418     particle: PVisualGear;
   661                 Gear^.State := gstDrowning;
   694                 Gear^.State := gstDrowning;
   662                 if Gear = CurrentHedgehog^.Gear then
   695                 if Gear = CurrentHedgehog^.Gear then
   663                     TurnTimeLeft := 0;
   696                     TurnTimeLeft := 0;
   664                 Gear^.RenderTimer := false;
   697                 Gear^.RenderTimer := false;
   665                 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot)
   698                 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot)
   666                 and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
   699                 and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot)
       
   700                 and (Gear^.Kind <> gtMinigunBullet) then
   667                     if Gear^.Kind = gtHedgehog then
   701                     if Gear^.Kind = gtHedgehog then
   668                         begin
   702                         begin
   669                         if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
   703                         if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
   670                             begin
   704                             begin
   671                             // Gear could become nil after this, just exit to skip splashes
   705                             // Gear could become nil after this, just exit to skip splashes
   990         Gear:= nil
  1024         Gear:= nil
   991         end
  1025         end
   992     end
  1026     end
   993 end;
  1027 end;
   994 
  1028 
   995 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
  1029 function CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
   996 var t: PGear;
  1030 var t: PGear;
       
  1031 	width: hwFloat;
   997 begin
  1032 begin
   998 t:= GearsList;
  1033 t:= GearsList;
   999 rX:= sqr(rX);
  1034 rX:= sqr(rX);
  1000 rY:= sqr(rY);
  1035 rY:= sqr(rY);
       
  1036 width:= int2hwFloat(RightX-LeftX);
       
  1037 
       
  1038 while t <> nil do
       
  1039     begin
       
  1040     if (t^.Kind = Kind) then
       
  1041         if (not ((hwSqr(X - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)) or
       
  1042         ((WorldEdge = weWrap) and (
       
  1043         (not ((hwSqr(X - width - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)) or
       
  1044         (not ((hwSqr(X + width - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)))) then
       
  1045         begin
       
  1046             CheckGearNear:= t;
       
  1047             exit;
       
  1048         end;
       
  1049     t:= t^.NextGear
       
  1050     end;
       
  1051 
       
  1052 CheckGearNear:= nil
       
  1053 end;
       
  1054 
       
  1055 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
       
  1056 var t: PGear;
       
  1057 	width: hwFloat;
       
  1058 begin
       
  1059 t:= GearsList;
       
  1060 rX:= sqr(rX);
       
  1061 rY:= sqr(rY);
       
  1062 width:= int2hwFloat(RightX-LeftX);
  1001 
  1063 
  1002 while t <> nil do
  1064 while t <> nil do
  1003     begin
  1065     begin
  1004     if (t <> Gear) and (t^.Kind = Kind) then
  1066     if (t <> Gear) and (t^.Kind = Kind) then
  1005         if (not ((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
  1067         if (not ((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
  1006         ((WorldEdge = weWrap) and (
  1068         ((WorldEdge = weWrap) and (
  1007         (not ((hwSqr(Gear^.X - int2hwFloat(RightX-LeftX) - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
  1069         (not ((hwSqr(Gear^.X - width - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
  1008         (not ((hwSqr(Gear^.X + int2hwFloat(RightX-LeftX) - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)))) then
  1070         (not ((hwSqr(Gear^.X + width - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)))) then
  1009         begin
  1071         begin
  1010             CheckGearNear:= t;
  1072             CheckGearNear:= t;
  1011             exit;
  1073             exit;
  1012         end;
  1074         end;
  1013     t:= t^.NextGear
  1075     t:= t^.NextGear
  1115     begin
  1177     begin
  1116     case t^.Kind of
  1178     case t^.Kind of
  1117         gtHedgehog,
  1179         gtHedgehog,
  1118             gtMine,
  1180             gtMine,
  1119             gtSMine,
  1181             gtSMine,
       
  1182             gtAirMine,
  1120             gtKnife,
  1183             gtKnife,
  1121             gtCase,
  1184             gtCase,
  1122             gtTarget,
  1185             gtTarget,
  1123             gtExplosives: begin//,
  1186             gtExplosives: begin//,
  1124 //            gtStructure: begin
  1187 //            gtStructure: begin
  1188     3. Hog is a king
  1251     3. Hog is a king
  1189 *)
  1252 *)
  1190     usable:= true;
  1253     usable:= true;
  1191     HH:= HHGear^.Hedgehog;
  1254     HH:= HHGear^.Hedgehog;
  1192     if HHGear <> nil then
  1255     if HHGear <> nil then
  1193     if (HHGear = nil) or (HH^.King) or (SuddenDeathDmg) then
  1256     if (HHGear = nil) or (HH^.King) or (SuddenDeathActive) then
  1194         usable:= false;
  1257         usable:= false;
  1195     cnt:= 0;
  1258     cnt:= 0;
  1196     for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
  1259     for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
  1197         for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
  1260         for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
  1198             if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
  1261             if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
  1202     if (cnt < 2) then
  1265     if (cnt < 2) then
  1203         usable:= false;
  1266         usable:= false;
  1204     CanUseTardis:= usable;
  1267     CanUseTardis:= usable;
  1205 end;
  1268 end;
  1206 
  1269 
  1207 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
  1270 procedure AmmoShoveImpl(Ammo: PGear; Damage, Power: LongInt; collisions: PGearArray);
  1208 var t: PGearArray;
  1271 var t: PGearArray;
  1209     Gear: PGear;
  1272     Gear: PGear;
  1210     i, j, tmpDmg: LongInt;
  1273     i, j, tmpDmg: LongInt;
  1211     VGear: PVisualGear;
  1274     VGear: PVisualGear;
  1212 begin
  1275 begin
  1213 t:= CheckGearsCollision(Ammo);
  1276 t:= collisions;
       
  1277 
  1214 // Just to avoid hogs on rope dodging fire.
  1278 // Just to avoid hogs on rope dodging fire.
  1215 if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy))
  1279 if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy))
  1216 and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1)
  1280 and (CurrentHedgehog^.Gear <> nil) and (CurrentHedgehog^.Gear^.CollisionIndex = -1)
  1217 and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then
  1281 and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then
  1218     begin
  1282     begin
  1226     Ammo^.Health:= 0;
  1290     Ammo^.Health:= 0;
  1227 while i > 0 do
  1291 while i > 0 do
  1228     begin
  1292     begin
  1229     dec(i);
  1293     dec(i);
  1230     Gear:= t^.ar[i];
  1294     Gear:= t^.ar[i];
  1231     if (Ammo^.Data <> nil) and (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot]) and (PGear(Ammo^.Data) = Gear) then
  1295     if (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet])
       
  1296         and (((Ammo^.Data <> nil) and (PGear(Ammo^.Data) = Gear))
       
  1297              or (not UpdateHitOrder(Gear, Ammo^.WDTimer))) then
  1232         continue;
  1298         continue;
       
  1299 
  1233     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1300     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1234        (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1301     (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1235         Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
  1302         Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
  1236     tmpDmg:= ModifyDamage(Damage, Gear);
  1303     tmpDmg:= ModifyDamage(Damage, Gear);
  1237     if (Gear^.State and gstNoDamage) = 0 then
  1304     if (Gear^.State and gstNoDamage) = 0 then
  1238         begin
  1305         begin
  1239 
  1306 
  1240         if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then
  1307         if (not (Gear^.Kind in [gtMinigun, gtPortal])) and
       
  1308             (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) then
  1241             begin
  1309             begin
  1242             VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit);
  1310             VGear := AddVisualGear(t^.cX[i], t^.cY[i], vgtBulletHit);
  1243             if VGear <> nil then
  1311             if VGear <> nil then
  1244                 VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
  1312                 VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
  1245             end;
  1313             end;
  1246 
  1314 
  1247         if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
  1315         if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
  1249 
  1317 
  1250 
  1318 
  1251         case Gear^.Kind of
  1319         case Gear^.Kind of
  1252             gtHedgehog,
  1320             gtHedgehog,
  1253             gtMine,
  1321             gtMine,
       
  1322             gtAirMine,
  1254             gtSMine,
  1323             gtSMine,
  1255             gtKnife,
  1324             gtKnife,
  1256             gtTarget,
  1325             gtTarget,
  1257             gtCase,
  1326             gtCase,
  1258             gtExplosives: //,
  1327             gtExplosives: //,
  1266             if (Gear^.Kind <> gtHedgehog) or (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) then
  1335             if (Gear^.Kind <> gtHedgehog) or (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) then
  1267                 begin
  1336                 begin
  1268                 if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
  1337                 if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
  1269                     for j:= 1 to max(1,min(3,tmpDmg div 5)) do
  1338                     for j:= 1 to max(1,min(3,tmpDmg div 5)) do
  1270                         begin
  1339                         begin
  1271                         VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot);
  1340                         VGear:= AddVisualGear(
       
  1341                             t^.cX[i] - ((t^.cX[i] - hwround(Gear^.X)) div 2),
       
  1342                             t^.cY[i] - ((t^.cY[i] - hwround(Gear^.Y)) div 2),
       
  1343                             vgtStraightShot);
  1272                         if VGear <> nil then
  1344                         if VGear <> nil then
  1273                             with VGear^ do
  1345                             with VGear^ do
  1274                                 begin
  1346                                 begin
  1275                                 Tint:= $FFCC00FF;
  1347                                 Tint:= $FFCC00FF;
  1276                                 Angle:= random(360);
  1348                                 Angle:= random(360);
  1295                 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
  1367                 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
  1296                 end;
  1368                 end;
  1297 
  1369 
  1298             if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
  1370             if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
  1299                 begin
  1371                 begin
  1300                 Gear^.dX:= Ammo^.dX * Power * _0_005;
  1372                 Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_005;
  1301                 Gear^.dY:= Ammo^.dY * Power * _0_005
  1373                 Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_005
  1302                 end
  1374                 end
  1303             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1375             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1304                 begin
  1376                 begin
  1305                 Gear^.dX:= Ammo^.dX * Power * _0_01;
  1377                 Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_01;
  1306                 Gear^.dY:= Ammo^.dY * Power * _0_01
  1378                 Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_01
  1307                 end;
  1379                 end;
  1308 
  1380 
  1309             if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1381             if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1310                 begin
  1382                 begin
  1311                 Gear^.Active:= true;
  1383                 Gear^.Active:= true;
  1336     end;
  1408     end;
  1337 if i <> 0 then
  1409 if i <> 0 then
  1338     SetAllToActive
  1410     SetAllToActive
  1339 end;
  1411 end;
  1340 
  1412 
       
  1413 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
       
  1414 var t: PGearArray;
       
  1415 begin
       
  1416     t:= CheckAllGearsLineCollision(Ammo, oX, oY, tX, tY);
       
  1417     AmmoShoveImpl(Ammo, Damage, Power, t);
       
  1418 end;
       
  1419 
       
  1420 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
       
  1421 begin
       
  1422     AmmoShoveImpl(Ammo, Damage, Power,
       
  1423         CheckGearsCollision(Ammo));
       
  1424 end;
       
  1425 
  1341 
  1426 
  1342 function CountGears(Kind: TGearType): Longword;
  1427 function CountGears(Kind: TGearType): Longword;
  1343 var t: PGear;
  1428 var t: PGear;
  1344     count: Longword = 0;
  1429     count: Longword = 0;
  1345 begin
  1430 begin
  1421 
  1506 
  1422     GearsNear.size:= s;
  1507     GearsNear.size:= s;
  1423     GearsNear.ar:= @GearsNearArray
  1508     GearsNear.ar:= @GearsNearArray
  1424 end;
  1509 end;
  1425 
  1510 
  1426 
       
  1427 procedure SpawnBoxOfSmth;
  1511 procedure SpawnBoxOfSmth;
  1428 var t, aTot, uTot, a, h: LongInt;
  1512 var t, aTot, uTot, a, h: LongInt;
  1429     i: TAmmoType;
  1513     i: TAmmoType;
  1430 begin
  1514 begin
  1431 if (PlacingHogs) or
  1515 if (PlacingHogs) or
  1576 WorldWrap:= false;
  1660 WorldWrap:= false;
  1577 if WorldEdge = weNone then exit(false);
  1661 if WorldEdge = weNone then exit(false);
  1578 if (hwRound(Gear^.X) < LongInt(leftX)) or
  1662 if (hwRound(Gear^.X) < LongInt(leftX)) or
  1579    (hwRound(Gear^.X) > LongInt(rightX)) then
  1663    (hwRound(Gear^.X) > LongInt(rightX)) then
  1580     begin
  1664     begin
  1581     // bullets can now hurt the hog that fired them
       
  1582     if (WorldEdge <> weSea) and (Gear^.Kind in [gtDEagleShot, gtSniperRifleShot]) then
       
  1583         Gear^.Data:= nil;
       
  1584     if WorldEdge = weWrap then
  1665     if WorldEdge = weWrap then
  1585         begin
  1666         begin
  1586         if (hwRound(Gear^.X) < LongInt(leftX)) then
  1667         if (hwRound(Gear^.X) < LongInt(leftX)) then
  1587              Gear^.X:= Gear^.X + int2hwfloat(rightX - leftX)
  1668              Gear^.X:= Gear^.X + int2hwfloat(rightX - leftX)
  1588         else Gear^.X:= Gear^.X - int2hwfloat(rightX - leftX);
  1669         else Gear^.X:= Gear^.X - int2hwfloat(rightX - leftX);