hedgewars/uGearsUtils.pas
changeset 6531 c938a35588af
parent 6498 5678806aafca
child 6543 697e9b730189
equal deleted inserted replaced
6530:dc6ce7eb556b 6531:c938a35588af
    45     dmg, dmgRadius, dmgBase: LongInt;
    45     dmg, dmgRadius, dmgBase: LongInt;
    46     fX, fY: hwFloat;
    46     fX, fY: hwFloat;
    47     vg: PVisualGear;
    47     vg: PVisualGear;
    48     i, cnt: LongInt;
    48     i, cnt: LongInt;
    49 begin
    49 begin
    50     if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');
    50 if Radius > 4 then AddFileLog('Explosion: at (' + inttostr(x) + ',' + inttostr(y) + ')');
    51     if Radius > 25 then KickFlakes(Radius, X, Y);
    51 if Radius > 25 then KickFlakes(Radius, X, Y);
    52 
    52 
    53     if ((Mask and EXPLNoGfx) = 0) then
    53 if ((Mask and EXPLNoGfx) = 0) then
    54         begin
    54     begin
    55         vg:= nil;
    55     vg:= nil;
    56         if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion)
    56     if Radius > 50 then vg:= AddVisualGear(X, Y, vgtBigExplosion)
    57         else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion);
    57     else if Radius > 10 then vg:= AddVisualGear(X, Y, vgtExplosion);
    58         if vg <> nil then
    58     if vg <> nil then
    59             vg^.Tint:= Tint;
    59         vg^.Tint:= Tint;
       
    60     end;
       
    61 if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion);
       
    62 
       
    63 if (Mask and EXPLAllDamageInRadius) = 0 then
       
    64     dmgRadius:= Radius shl 1
       
    65 else
       
    66     dmgRadius:= Radius;
       
    67 dmgBase:= dmgRadius + cHHRadius div 2;
       
    68 fX:= int2hwFloat(X);
       
    69 fY:= int2hwFloat(Y);
       
    70 Gear:= GearsList;
       
    71 while Gear <> nil do
       
    72     begin
       
    73     dmg:= 0;
       
    74     //dmg:= dmgRadius  + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y)));
       
    75     //if (dmg > 1) and
       
    76     if (Gear^.State and gstNoDamage) = 0 then
       
    77         begin
       
    78         case Gear^.Kind of
       
    79             gtHedgehog,
       
    80                 gtMine,
       
    81                 gtBall,
       
    82                 gtMelonPiece,
       
    83                 gtGrenade,
       
    84                 gtClusterBomb,
       
    85             //    gtCluster, too game breaking I think
       
    86                 gtSMine,
       
    87                 gtCase,
       
    88                 gtTarget,
       
    89                 gtFlame,
       
    90                 gtExplosives,
       
    91                 gtStructure: begin
       
    92 // Run the calcs only once we know we have a type that will need damage
       
    93                         if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
       
    94                             dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius);
       
    95                         if dmg > 1 then
       
    96                             begin
       
    97                             dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
       
    98                             //AddFileLog('Damage: ' + inttostr(dmg));
       
    99                             if (Mask and EXPLNoDamage) = 0 then
       
   100                                 begin
       
   101                                 if not Gear^.Invulnerable then
       
   102                                     ApplyDamage(Gear, AttackingHog, dmg, dsExplosion)
       
   103                                 else
       
   104                                     Gear^.State:= Gear^.State or gstWinner;
       
   105                                 end;
       
   106                             if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then
       
   107                                 begin
       
   108                                 DeleteCI(Gear);
       
   109                                 Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/(Gear^.Density/_3);
       
   110                                 Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/(Gear^.Density/_3);
       
   111 
       
   112                                 Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser);
       
   113                                 if not Gear^.Invulnerable then
       
   114                                     Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner);
       
   115                                 Gear^.Active:= true;
       
   116                                 if Gear^.Kind <> gtFlame then FollowGear:= Gear
       
   117                                 end;
       
   118                             if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
       
   119                                 Gear^.Hedgehog^.Effects[hePoisoned] := true;
       
   120                             end;
       
   121 
       
   122                         end;
       
   123                 gtGrave: begin
       
   124 // Run the calcs only once we know we have a type that will need damage
       
   125                         if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
       
   126                             dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY));
       
   127                         if dmg > 1 then
       
   128                             begin
       
   129                             dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
       
   130                             Gear^.dY:= - _0_004 * dmg;
       
   131                             Gear^.Active:= true
       
   132                             end
       
   133                         end;
       
   134             end;
    60         end;
   135         end;
    61     if (Mask and EXPLAutoSound) <> 0 then PlaySound(sndExplosion);
   136     Gear:= Gear^.NextGear
    62 
   137     end;
    63     if (Mask and EXPLAllDamageInRadius) = 0 then
   138 
    64         dmgRadius:= Radius shl 1
   139 if (Mask and EXPLDontDraw) = 0 then
    65     else
   140     if (GameFlags and gfSolidLand) = 0 then
    66         dmgRadius:= Radius;
   141         begin
    67     dmgBase:= dmgRadius + cHHRadius div 2;
   142         cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk
    68     fX:= int2hwFloat(X);
   143         if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then
    69     fY:= int2hwFloat(Y);
   144             for i:= 0 to cnt do
    70     Gear:= GearsList;
   145                 AddVisualGear(X, Y, vgtChunk)
    71     while Gear <> nil do
       
    72         begin
       
    73         dmg:= 0;
       
    74         //dmg:= dmgRadius  + cHHRadius div 2 - hwRound(Distance(Gear^.X - int2hwFloat(X), Gear^.Y - int2hwFloat(Y)));
       
    75         //if (dmg > 1) and
       
    76         if (Gear^.State and gstNoDamage) = 0 then
       
    77             begin
       
    78             case Gear^.Kind of
       
    79                 gtHedgehog,
       
    80                     gtMine,
       
    81                     gtBall,
       
    82                     gtMelonPiece,
       
    83                     gtGrenade,
       
    84                     gtClusterBomb,
       
    85                 //    gtCluster, too game breaking I think
       
    86                     gtSMine,
       
    87                     gtCase,
       
    88                     gtTarget,
       
    89                     gtFlame,
       
    90                     gtExplosives,
       
    91                     gtStructure: begin
       
    92     // Run the calcs only once we know we have a type that will need damage
       
    93                             if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
       
    94                                 dmg:= dmgBase - max(hwRound(Distance(Gear^.X - fX, Gear^.Y - fY)),Gear^.Radius);
       
    95                             if dmg > 1 then
       
    96                                 begin
       
    97                                 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
       
    98                                 //AddFileLog('Damage: ' + inttostr(dmg));
       
    99                                 if (Mask and EXPLNoDamage) = 0 then
       
   100                                     begin
       
   101                                     if not Gear^.Invulnerable then
       
   102                                         ApplyDamage(Gear, AttackingHog, dmg, dsExplosion)
       
   103                                     else
       
   104                                         Gear^.State:= Gear^.State or gstWinner;
       
   105                                     end;
       
   106                                 if ((Mask and EXPLDoNotTouchAny) = 0) and (((Mask and EXPLDoNotTouchHH) = 0) or (Gear^.Kind <> gtHedgehog)) then
       
   107                                     begin
       
   108                                     DeleteCI(Gear);
       
   109                                     if Gear^.Kind <> gtHedgehog then
       
   110                                         begin
       
   111                                         Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX)/Gear^.Density;
       
   112                                         Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY)/Gear^.Density;
       
   113                                         end
       
   114                                     else
       
   115                                         begin
       
   116                                         Gear^.dX:= Gear^.dX + SignAs(_0_005 * dmg + cHHKick, Gear^.X - fX);
       
   117                                         Gear^.dY:= Gear^.dY + SignAs(_0_005 * dmg + cHHKick, Gear^.Y - fY);
       
   118                                         end;
       
   119 
       
   120                                     Gear^.State:= (Gear^.State or gstMoving) and (not gstLoser);
       
   121                                     if not Gear^.Invulnerable then
       
   122                                         Gear^.State:= (Gear^.State or gstMoving) and (not gstWinner);
       
   123                                     Gear^.Active:= true;
       
   124                                     if Gear^.Kind <> gtFlame then FollowGear:= Gear
       
   125                                     end;
       
   126                                 if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
       
   127                                     Gear^.Hedgehog^.Effects[hePoisoned] := true;
       
   128                                 end;
       
   129 
       
   130                             end;
       
   131                     gtGrave: begin
       
   132     // Run the calcs only once we know we have a type that will need damage
       
   133                             if hwRound(hwAbs(Gear^.X-fX)+hwAbs(Gear^.Y-fY)) < dmgBase then
       
   134                                 dmg:= dmgBase - hwRound(Distance(Gear^.X - fX, Gear^.Y - fY));
       
   135                             if dmg > 1 then
       
   136                                 begin
       
   137                                 dmg:= ModifyDamage(min(dmg div 2, Radius), Gear);
       
   138                                 Gear^.dY:= - _0_004 * dmg;
       
   139                                 Gear^.Active:= true
       
   140                                 end
       
   141                             end;
       
   142                 end;
       
   143             end;
       
   144         Gear:= Gear^.NextGear
       
   145         end;
   146         end;
   146 
   147 
   147     if (Mask and EXPLDontDraw) = 0 then
   148 uAIMisc.AwareOfExplosion(0, 0, 0)
   148         if (GameFlags and gfSolidLand) = 0 then
       
   149             begin
       
   150             cnt:= DrawExplosion(X, Y, Radius) div 1608; // approx 2 16x16 circles to erase per chunk
       
   151             if (cnt > 0) and (SpritesData[sprChunk].Texture <> nil) then
       
   152                 for i:= 0 to cnt do
       
   153                     AddVisualGear(X, Y, vgtChunk)
       
   154             end;
       
   155 
       
   156     uAIMisc.AwareOfExplosion(0, 0, 0)
       
   157 end;
   149 end;
   158 
   150 
   159 function ModifyDamage(dmg: Longword; Gear: PGear): Longword;
   151 function ModifyDamage(dmg: Longword; Gear: PGear): Longword;
   160 var i: hwFloat;
   152 var i: hwFloat;
   161 begin
   153 begin