hedgewars/uGearsUtils.pas
branchtransitional_engine
changeset 15929 128ace913837
parent 15926 7f3d7f015aa5
child 16004 2146cb7be36f
equal deleted inserted replaced
15928:73cdc306888f 15929:128ace913837
    20 
    20 
    21 unit uGearsUtils;
    21 unit uGearsUtils;
    22 interface
    22 interface
    23 uses uTypes, uFloat;
    23 uses uTypes, uFloat;
    24 
    24 
    25 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline;
    25 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword);
    26 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
    26 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
    27 procedure AddSplashForGear(Gear: PGear; justSkipping: boolean);
    27 procedure AddSplashForGear(Gear: PGear; justSkipping: boolean);
    28 procedure AddBounceEffectForGear(Gear: PGear; imageScale: Single);
    28 procedure AddBounceEffectForGear(Gear: PGear; imageScale: Single);
    29 procedure AddBounceEffectForGear(Gear: PGear);
    29 procedure AddBounceEffectForGear(Gear: PGear);
    30 
    30 
    37 function IncHogHealth(Hedgehog: PHedgehog; healthBoost: LongInt): LongInt;
    37 function IncHogHealth(Hedgehog: PHedgehog; healthBoost: LongInt): LongInt;
    38 procedure CheckHHDamage(Gear: PGear);
    38 procedure CheckHHDamage(Gear: PGear);
    39 procedure CalcRotationDirAngle(Gear: PGear);
    39 procedure CalcRotationDirAngle(Gear: PGear);
    40 procedure ResurrectHedgehog(var gear: PGear);
    40 procedure ResurrectHedgehog(var gear: PGear);
    41 
    41 
    42 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
    42 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
    43 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
    43 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
    44 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity, deleteOnFail: boolean);
    44 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity, deleteOnFail: boolean);
    45 function CountLand(x, y, r, c: LongInt; mask, antimask: LongWord): LongInt;
    45 function CountLand(x, y, r, c: LongInt; mask, antimask: LongWord): LongInt;
    46 
    46 
    47 function  CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
    47 function  CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
    48 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
    48 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
    49 function  CheckGearDrowning(var Gear: PGear): boolean;
    49 function  CheckGearDrowning(var Gear: PGear): boolean;
    50 procedure CheckCollision(Gear: PGear); inline;
    50 procedure CheckCollision(Gear: PGear);
    51 procedure CheckCollisionWithLand(Gear: PGear); inline;
    51 procedure CheckCollisionWithLand(Gear: PGear);
    52 
    52 
    53 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
    53 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);
    54 procedure AmmoShoveCache(Ammo: PGear; Damage, Power: LongInt);
    54 procedure AmmoShoveCache(Ammo: PGear; Damage, Power: LongInt);
    55 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
    55 procedure AmmoShoveLine(Ammo: PGear; Damage, Power: LongInt; oX, oY, tX, tY: hwFloat);
    56 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    56 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): PGearArrayS;
    60 function  CountHogsInTeam(HHGear: PGear; countHidden: boolean): LongInt;
    60 function  CountHogsInTeam(HHGear: PGear; countHidden: boolean): LongInt;
    61 function  CanUseTardis(HHGear: PGear): boolean;
    61 function  CanUseTardis(HHGear: PGear): boolean;
    62 
    62 
    63 procedure SetAllToActive;
    63 procedure SetAllToActive;
    64 procedure SetAllHHToActive(Ice: boolean);
    64 procedure SetAllHHToActive(Ice: boolean);
    65 procedure SetAllHHToActive(); inline;
    65 procedure SetAllHHToActive();
    66 
    66 
    67 function  GetAmmo(Hedgehog: PHedgehog): TAmmoType;
    67 function  GetAmmo(Hedgehog: PHedgehog): TAmmoType;
    68 function  GetUtility(Hedgehog: PHedgehog): TAmmoType;
    68 function  GetUtility(Hedgehog: PHedgehog): TAmmoType;
    69 
    69 
    70 function WorldWrap(var Gear: PGear): boolean;
    70 function WorldWrap(var Gear: PGear): boolean;
    81 implementation
    81 implementation
    82 uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
    82 uses uSound, uCollisions, uUtils, uConsts, uVisualGears, uAIMisc,
    83     uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore,
    83     uVariables, uLandGraphics, uScript, uStats, uCaptions, uTeams, uStore,
    84     uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug,
    84     uLocale, uTextures, uRenderUtils, uRandom, SDLh, uDebug,
    85     uGearsList, Math, uVisualGearsList, uGearsHandlersMess,
    85     uGearsList, Math, uVisualGearsList, uGearsHandlersMess,
    86     uGearsHedgehog;
    86     uGearsHedgehog, uLandUtils;
    87 
    87 
    88 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline;
    88 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword);
    89 begin
    89 begin
    90     doMakeExplosion(X, Y, Radius, AttackingHog, Mask, $FFFFFFFF);
    90     doMakeExplosion(X, Y, Radius, AttackingHog, Mask, $FFFFFFFF);
    91 end;
    91 end;
    92 
    92 
    93 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
    93 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord);
   870 var i: LongInt;
   870 var i: LongInt;
   871     count: LongInt = 0;
   871     count: LongInt = 0;
   872 begin
   872 begin
   873     if (y and LAND_HEIGHT_MASK) = 0 then
   873     if (y and LAND_HEIGHT_MASK) = 0 then
   874         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 1) do
   874         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 1) do
   875             if (Land[y, i] and mask <> 0) and (Land[y, i] and antimask = 0) then
   875             if (LandGet(y, i) and mask <> 0) and (LandGet(y, i) and antimask = 0) then
   876                 begin
   876                 begin
   877                 inc(count);
   877                 inc(count);
   878                 if count = c then
   878                 if count = c then
   879                     begin
   879                     begin
   880                     CountLand:= count;
   880                     CountLand:= count;
   892 
   892 
   893     if ((y and LAND_HEIGHT_MASK) = 0) and (x - r >= 0) and (x + r < LAND_WIDTH) then
   893     if ((y and LAND_HEIGHT_MASK) = 0) and (x - r >= 0) and (x + r < LAND_WIDTH) then
   894     begin
   894     begin
   895         for i:= r - c + 2 to r do
   895         for i:= r - c + 2 to r do
   896         begin
   896         begin
   897             if (Land[y, x - i] and mask <> 0) then inc(cnt);
   897             if (LandGet(y, x - i) and mask <> 0) then inc(cnt);
   898             if (Land[y, x + i] and mask <> 0) then inc(cnt);
   898             if (LandGet(y, x + i) and mask <> 0) then inc(cnt);
   899 
   899 
   900             if cnt >= c then
   900             if cnt >= c then
   901             begin
   901             begin
   902                 isSteadyPosition:= true;
   902                 isSteadyPosition:= true;
   903                 exit
   903                 exit
   922     t:= t^.NextGear
   922     t:= t^.NextGear
   923     end;
   923     end;
   924 NoGearsToAvoid:= true
   924 NoGearsToAvoid:= true
   925 end;
   925 end;
   926 
   926 
   927 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
   927 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
   928 begin
   928 begin
   929     FindPlace(Gear, withFall, Left, Right, false, true);
   929     FindPlace(Gear, withFall, Left, Right, false, true);
   930 end;
   930 end;
   931 
   931 
   932 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean); inline;
   932 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
   933 begin
   933 begin
   934     FindPlace(Gear, withFall, Left, Right, skipProximity, true);
   934     FindPlace(Gear, withFall, Left, Right, skipProximity, true);
   935 end;
   935 end;
   936 
   936 
   937 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity, deleteOnFail: boolean);
   937 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity, deleteOnFail: boolean);
   957     delta:= LAND_WIDTH div 16;
   957     delta:= LAND_WIDTH div 16;
   958     cnt2:= 0;
   958     cnt2:= 0;
   959     repeat
   959     repeat
   960         if GetRandom(2) = 0 then dir:= -1 else dir:= 1;
   960         if GetRandom(2) = 0 then dir:= -1 else dir:= 1;
   961         x:= max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta)));
   961         x:= max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta)));
   962         if dir = 1 then x:= Left + x else x:= Right - x; 
   962         if dir = 1 then x:= Left + x else x:= Right - x;
   963         repeat
   963         repeat
   964             cnt:= 0;
   964             cnt:= 0;
   965             y:= min(1024, topY) - Gear^.Radius shl 1;
   965             y:= min(1024, topY) - Gear^.Radius shl 1;
   966             while y < cWaterLine do
   966             while y < cWaterLine do
   967                 begin
   967                 begin
   974                 sy:= y;
   974                 sy:= y;
   975 
   975 
   976                 repeat
   976                 repeat
   977                     inc(y);
   977                     inc(y);
   978                 until (y >= cWaterLine) or
   978                 until (y >= cWaterLine) or
   979                         (ignoreOverlap and 
   979                         (ignoreOverlap and
   980                                 (CountLand(x, y, Gear^.Radius - 1, 1, lfAll, 0) <> 0)) or
   980                                 (CountLand(x, y, Gear^.Radius - 1, 1, lfAll, 0) <> 0)) or
   981                         (not ignoreOverlap and 
   981                         (not ignoreOverlap and
   982                             (CountLand(x, y, Gear^.Radius - 1, 1, lfLandMask, 0) <> 0));
   982                             (CountLand(x, y, Gear^.Radius - 1, 1, lfLandMask, 0) <> 0));
   983 
   983 
   984                 if (y - sy > Gear^.Radius * 2) and (y < cWaterLine)
   984                 if (y - sy > Gear^.Radius * 2) and (y < cWaterLine)
   985                     and (((Gear^.Kind = gtExplosives)
   985                     and (((Gear^.Kind = gtExplosives)
   986                         and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
   986                         and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
  1164 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
  1164 function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
  1165 begin
  1165 begin
  1166     CheckGearNear := CheckGearNearImpl(Kind, Gear^.X, Gear^.Y, rX, rY, Gear);
  1166     CheckGearNear := CheckGearNearImpl(Kind, Gear^.X, Gear^.Y, rX, rY, Gear);
  1167 end;
  1167 end;
  1168 
  1168 
  1169 procedure CheckCollision(Gear: PGear); inline;
  1169 procedure CheckCollision(Gear: PGear);
  1170 begin
  1170 begin
  1171     if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0)
  1171     if (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0)
  1172     or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
  1172     or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then
  1173         Gear^.State := Gear^.State or gstCollision
  1173         Gear^.State := Gear^.State or gstCollision
  1174     else
  1174     else
  1175         Gear^.State := Gear^.State and (not gstCollision)
  1175         Gear^.State := Gear^.State and (not gstCollision)
  1176 end;
  1176 end;
  1177 
  1177 
  1178 procedure CheckCollisionWithLand(Gear: PGear); inline;
  1178 procedure CheckCollisionWithLand(Gear: PGear);
  1179 begin
  1179 begin
  1180     if (TestCollisionX(Gear, hwSign(Gear^.dX)) <> 0)
  1180     if (TestCollisionX(Gear, hwSign(Gear^.dX)) <> 0)
  1181     or (TestCollisionY(Gear, hwSign(Gear^.dY)) <> 0) then
  1181     or (TestCollisionY(Gear, hwSign(Gear^.dY)) <> 0) then
  1182         Gear^.State := Gear^.State or gstCollision
  1182         Gear^.State := Gear^.State or gstCollision
  1183     else
  1183     else
  1405     Gear:= t^.ar[i];
  1405     Gear:= t^.ar[i];
  1406     if (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet,
  1406     if (Ammo^.Kind in [gtDEagleShot, gtSniperRifleShot, gtMinigunBullet,
  1407                        gtFirePunch, gtKamikaze, gtWhip, gtShover])
  1407                        gtFirePunch, gtKamikaze, gtWhip, gtShover])
  1408         and (((Ammo^.Data <> nil) and (PGear(Ammo^.Data) = Gear))
  1408         and (((Ammo^.Data <> nil) and (PGear(Ammo^.Data) = Gear))
  1409             or (not UpdateHitOrder(
  1409             or (not UpdateHitOrder(
  1410                     Gear, 
  1410                     Gear,
  1411                     Ammo^.WDTimer, 
  1411                     Ammo^.WDTimer,
  1412                     (Ammo^.Kind = gtMinigunBullet) and (Ammo^.Pos <> 0)))) then
  1412                     (Ammo^.Kind = gtMinigunBullet) and (Ammo^.Pos <> 0)))) then
  1413         continue;
  1413         continue;
  1414 
  1414 
  1415     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1415     if ((Ammo^.Kind = gtFlame) or (Ammo^.Kind = gtBlowTorch)) and
  1416     (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1416     (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
  1494                 Gear^.dY:= Ammo^.dY * Power * _0_005
  1494                 Gear^.dY:= Ammo^.dY * Power * _0_005
  1495                 end
  1495                 end
  1496             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1496             else if ((Ammo^.Kind <> gtFlame) or (Gear^.Kind = gtHedgehog)) and (Power <> 0) then
  1497                 begin
  1497                 begin
  1498                 if (Ammo^.Kind in [gtMinigunBullet]) then
  1498                 if (Ammo^.Kind in [gtMinigunBullet]) then
  1499                     begin    
  1499                     begin
  1500                     Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_01;
  1500                     Gear^.dX:= Gear^.dX + Ammo^.dX * Power * _0_01;
  1501                     Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_01
  1501                     Gear^.dY:= Gear^.dY + Ammo^.dY * Power * _0_01
  1502                     end 
  1502                     end
  1503                 else
  1503                 else
  1504                     begin
  1504                     begin
  1505                     Gear^.dX:= Ammo^.dX * Power * _0_01;
  1505                     Gear^.dX:= Ammo^.dX * Power * _0_01;
  1506                     Gear^.dY:= Ammo^.dY * Power * _0_01
  1506                     Gear^.dY:= Ammo^.dY * Power * _0_01
  1507                     end
  1507                     end
  1583     t^.Active:= true;
  1583     t^.Active:= true;
  1584     t:= t^.NextGear
  1584     t:= t^.NextGear
  1585     end
  1585     end
  1586 end;
  1586 end;
  1587 
  1587 
  1588 procedure SetAllHHToActive; inline;
  1588 procedure SetAllHHToActive;
  1589 begin
  1589 begin
  1590 SetAllHHToActive(true)
  1590 SetAllHHToActive(true)
  1591 end;
  1591 end;
  1592 
  1592 
  1593 
  1593