hedgewars/uGearsUtils.pas
changeset 12898 8a40ce061d94
parent 12804 a889cb350930
child 12920 21827fc9ca98
equal deleted inserted replaced
12891:856570ddd409 12898:8a40ce061d94
    42 function  CheckGearDrowning(var Gear: PGear): boolean;
    42 function  CheckGearDrowning(var Gear: PGear): boolean;
    43 procedure CheckCollision(Gear: PGear); inline;
    43 procedure CheckCollision(Gear: PGear); inline;
    44 procedure CheckCollisionWithLand(Gear: PGear); inline;
    44 procedure CheckCollisionWithLand(Gear: PGear); inline;
    45 
    45 
    46 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
    46 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
       
    47 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
    47 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    48 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    48 procedure SpawnBoxOfSmth;
    49 procedure SpawnBoxOfSmth;
    49 procedure ShotgunShot(Gear: PGear);
    50 procedure ShotgunShot(Gear: PGear);
    50 function  CanUseTardis(HHGear: PGear): boolean;
    51 function  CanUseTardis(HHGear: PGear): boolean;
    51 
    52 
   661                 Gear^.State := gstDrowning;
   662                 Gear^.State := gstDrowning;
   662                 if Gear = CurrentHedgehog^.Gear then
   663                 if Gear = CurrentHedgehog^.Gear then
   663                     TurnTimeLeft := 0;
   664                     TurnTimeLeft := 0;
   664                 Gear^.RenderTimer := false;
   665                 Gear^.RenderTimer := false;
   665                 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot)
   666                 if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot)
   666                 and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
   667                 and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot)
       
   668                 and (Gear^.Kind <> gtMinigunBullet) then
   667                     if Gear^.Kind = gtHedgehog then
   669                     if Gear^.Kind = gtHedgehog then
   668                         begin
   670                         begin
   669                         if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
   671                         if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
   670                             begin
   672                             begin
   671                             // Gear could become nil after this, just exit to skip splashes
   673                             // Gear could become nil after this, just exit to skip splashes
  1202     if (cnt < 2) then
  1204     if (cnt < 2) then
  1203         usable:= false;
  1205         usable:= false;
  1204     CanUseTardis:= usable;
  1206     CanUseTardis:= usable;
  1205 end;
  1207 end;
  1206 
  1208 
  1207 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
  1209 procedure AmmoShoveImpl(Ammo: PGear; Damage, Power: LongInt; collisions: PGearArray);
  1208 var t: PGearArray;
  1210 var t: PGearArray;
  1209     Gear: PGear;
  1211     Gear: PGear;
  1210     i, j, tmpDmg: LongInt;
  1212     i, j, tmpDmg: LongInt;
  1211     VGear: PVisualGear;
  1213     VGear: PVisualGear;
  1212 begin
  1214 begin
  1213 t:= CheckGearsCollision(Ammo);
  1215 t:= collisions;
       
  1216 
  1214 // Just to avoid hogs on rope dodging fire.
  1217 // Just to avoid hogs on rope dodging fire.
  1215 if (CurAmmoGear <> nil) and ((CurAmmoGear^.Kind = gtRope) or (CurAmmoGear^.Kind = gtJetpack) or (CurAmmoGear^.Kind = gtBirdy))
  1218 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)
  1219 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
  1220 and (sqr(hwRound(Ammo^.X) - hwRound(CurrentHedgehog^.Gear^.X)) + sqr(hwRound(Ammo^.Y) - hwRound(CurrentHedgehog^.Gear^.Y)) <= sqr(cHHRadius + Ammo^.Radius)) then
  1218     begin
  1221     begin
  1226     Ammo^.Health:= 0;
  1229     Ammo^.Health:= 0;
  1227 while i > 0 do
  1230 while i > 0 do
  1228     begin
  1231     begin
  1229     dec(i);
  1232     dec(i);
  1230     Gear:= t^.ar[i];
  1233     Gear:= t^.ar[i];
  1231     if (Ammo^.Data <> nil) and (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot]) and (PGear(Ammo^.Data) = Gear) then
  1234     if (Ammo^.Data <> nil) and (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) and (PGear(Ammo^.Data) = Gear)
       
  1235     or ((Ammo^.Kind = gtMinigunBullet) and (not UpdateHitOrder(Gear, Ammo^.WDTimer))) then
  1232         continue;
  1236         continue;
       
  1237 
  1233     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1238     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1234        (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1239     (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1235         Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
  1240         Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
  1236     tmpDmg:= ModifyDamage(Damage, Gear);
  1241     tmpDmg:= ModifyDamage(Damage, Gear);
  1237     if (Gear^.State and gstNoDamage) = 0 then
  1242     if (Gear^.State and gstNoDamage) = 0 then
  1238         begin
  1243         begin
  1239 
  1244 
  1240         if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot) then
  1245         if (Ammo^.Kind = gtDEagleShot) or (Ammo^.Kind = gtSniperRifleShot)
       
  1246         or (Ammo^.Kind = gtMinigunBullet) then
  1241             begin
  1247             begin
  1242             VGear := AddVisualGear(hwround(Ammo^.X), hwround(Ammo^.Y), vgtBulletHit);
  1248             VGear := AddVisualGear(t^.cX[i], t^.cY[i], vgtBulletHit);
  1243             if VGear <> nil then
  1249             if VGear <> nil then
  1244                 VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
  1250                 VGear^.Angle := DxDy2Angle(-Ammo^.dX, Ammo^.dY);
  1245             end;
  1251             end;
  1246 
  1252 
  1247         if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
  1253         if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
  1266             if (Gear^.Kind <> gtHedgehog) or (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) then
  1272             if (Gear^.Kind <> gtHedgehog) or (Gear^.Hedgehog^.Effects[heInvulnerable] = 0) then
  1267                 begin
  1273                 begin
  1268                 if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
  1274                 if (Ammo^.Kind = gtKnife) and (tmpDmg > 0) then
  1269                     for j:= 1 to max(1,min(3,tmpDmg div 5)) do
  1275                     for j:= 1 to max(1,min(3,tmpDmg div 5)) do
  1270                         begin
  1276                         begin
  1271                         VGear:= AddVisualGear(hwRound(Ammo^.X-((Ammo^.X-Gear^.X)/_2)), hwRound(Ammo^.Y-((Ammo^.Y-Gear^.Y)/_2)), vgtStraightShot);
  1277                         VGear:= AddVisualGear(
       
  1278                             t^.cX[i] - ((t^.cX[i] - hwround(Gear^.X)) div 2),
       
  1279                             t^.cY[i] - ((t^.cY[i] - hwround(Gear^.Y)) div 2),
       
  1280                             vgtStraightShot);
  1272                         if VGear <> nil then
  1281                         if VGear <> nil then
  1273                             with VGear^ do
  1282                             with VGear^ do
  1274                                 begin
  1283                                 begin
  1275                                 Tint:= $FFCC00FF;
  1284                                 Tint:= $FFCC00FF;
  1276                                 Angle:= random(360);
  1285                                 Angle:= random(360);
  1295                 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
  1304                 ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
  1296                 end;
  1305                 end;
  1297 
  1306 
  1298             if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
  1307             if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
  1299                 begin
  1308                 begin
  1300                 Gear^.dX:= Ammo^.dX * Power * _0_005;
  1309                 Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_005;
  1301                 Gear^.dY:= Ammo^.dY * Power * _0_005
  1310                 Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_005
  1302                 end
  1311                 end
  1303             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1312             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1304                 begin
  1313                 begin
  1305                 Gear^.dX:= Ammo^.dX * Power * _0_01;
  1314                 Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_01;
  1306                 Gear^.dY:= Ammo^.dY * Power * _0_01
  1315                 Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_01
  1307                 end;
  1316                 end;
  1308 
  1317 
  1309             if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1318             if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1310                 begin
  1319                 begin
  1311                 Gear^.Active:= true;
  1320                 Gear^.Active:= true;
  1336     end;
  1345     end;
  1337 if i <> 0 then
  1346 if i <> 0 then
  1338     SetAllToActive
  1347     SetAllToActive
  1339 end;
  1348 end;
  1340 
  1349 
       
  1350 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
       
  1351 var t: PGearArray;
       
  1352 begin
       
  1353     if Ammo^.Kind = gtMinigunBullet then
       
  1354         t:= CheckAllGearsLineCollision(Ammo, oX, oY, tX, tY)
       
  1355     else
       
  1356         t:= CheckGearsLineCollision(Ammo, oX, oY, tX, tY);
       
  1357     AmmoShoveImpl(Ammo, Damage, Power, t);
       
  1358 end;
       
  1359 
       
  1360 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
       
  1361 begin
       
  1362     AmmoShoveImpl(Ammo, Damage, Power,
       
  1363         CheckGearsCollision(Ammo));
       
  1364 end;
       
  1365 
  1341 
  1366 
  1342 function CountGears(Kind: TGearType): Longword;
  1367 function CountGears(Kind: TGearType): Longword;
  1343 var t: PGear;
  1368 var t: PGear;
  1344     count: Longword = 0;
  1369     count: Longword = 0;
  1345 begin
  1370 begin
  1577 if WorldEdge = weNone then exit(false);
  1602 if WorldEdge = weNone then exit(false);
  1578 if (hwRound(Gear^.X) < LongInt(leftX)) or
  1603 if (hwRound(Gear^.X) < LongInt(leftX)) or
  1579    (hwRound(Gear^.X) > LongInt(rightX)) then
  1604    (hwRound(Gear^.X) > LongInt(rightX)) then
  1580     begin
  1605     begin
  1581     // bullets can now hurt the hog that fired them
  1606     // bullets can now hurt the hog that fired them
  1582     if (WorldEdge <> weSea) and (Gear^.Kind in [gtDEagleShot, gtSniperRifleShot]) then
  1607     if (WorldEdge <> weSea) and (Gear^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet]) then
  1583         Gear^.Data:= nil;
  1608         Gear^.Data:= nil;
  1584     if WorldEdge = weWrap then
  1609     if WorldEdge = weWrap then
  1585         begin
  1610         begin
  1586         if (hwRound(Gear^.X) < LongInt(leftX)) then
  1611         if (hwRound(Gear^.X) < LongInt(leftX)) then
  1587              Gear^.X:= Gear^.X + int2hwfloat(rightX - leftX)
  1612              Gear^.X:= Gear^.X + int2hwfloat(rightX - leftX)