hedgewars/VGSHandlers.inc
changeset 3441 f31225f99a06
child 3443 14d12df0d363
equal deleted inserted replaced
3440:dee31c5149e0 3441:f31225f99a06
       
     1 (*
       
     2  * Hedgewars, a free turn based strategy game
       
     3  * Copyright (c) 2004-2010 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License as published by
       
     7  * the Free Software Foundation; version 2 of the License
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
       
    17  *)
       
    18 procedure doStepFlake(Gear: PVisualGear; Steps: Longword);
       
    19 var sign: hwFloat;
       
    20 begin
       
    21 sign:= _1;
       
    22 with Gear^ do
       
    23     begin
       
    24     inc(FrameTicks, Steps);
       
    25     if FrameTicks > vobFrameTicks then
       
    26         begin
       
    27         dec(FrameTicks, vobFrameTicks);
       
    28         inc(Frame);
       
    29         if Frame = vobFramesCount then Frame:= 0
       
    30         end;
       
    31     X:= X + (cWindSpeed * 200 + dX + tdX) * Steps;
       
    32     Y:= Y + (dY + tdY + cGravity * vobFallSpeed) * Steps;
       
    33     Angle:= Angle + dAngle * Steps;
       
    34   
       
    35     if (hwRound(X) >= -cScreenWidth - 64) and
       
    36        (hwRound(X) <= cScreenWidth + LAND_WIDTH) and
       
    37        (hwRound(Y) <= (LAND_HEIGHT + 75)) and 
       
    38        (Timer > 0) and (Timer-Steps > 0) then
       
    39         begin
       
    40         sign.isNegative:=tdX.isNegative;
       
    41         tdX:= tdX - _0_005*Steps*sign;
       
    42         if (sign.isNegative and (tdX > _0)) or (not sign.isNegative and (tdX < _0)) then tdX:= _0;
       
    43         sign.isNegative:=tdY.isNegative;
       
    44         tdY:= tdY - _0_005*Steps*sign;
       
    45         if (sign.isNegative and (tdY > _0)) or (not sign.isNegative and (tdY < _0)) then tdY:= _0;
       
    46         dec(Timer, Steps)
       
    47         end
       
    48     else
       
    49         begin
       
    50         if hwRound(X) < -cScreenWidth - 64 then X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else
       
    51         if hwRound(X) > cScreenWidth + LAND_WIDTH then X:= int2hwFloat(-cScreenWidth - 64);
       
    52         // if hwRound(Y) < (LAND_HEIGHT - 1024 - 75) then Y:= Y + int2hwFloat(25); // For if flag is set for flakes rising upwards?
       
    53         if hwRound(Y) > (LAND_HEIGHT + 75) then Y:= Y - int2hwFloat(1024 + 150); // TODO - configure in theme (jellies for example could use limited range)
       
    54         Timer:= 0;
       
    55         tdX:= _0;
       
    56         tdY:= _0
       
    57         end;
       
    58     end;
       
    59 
       
    60 end;
       
    61 
       
    62 ////////////////////////////////////////////////////////////////////////////////
       
    63 procedure doStepBeeTrace(Gear: PVisualGear; Steps: Longword);
       
    64 begin
       
    65 if Gear^.FrameTicks > Steps then
       
    66     dec(Gear^.FrameTicks, Steps)
       
    67 else
       
    68     DeleteVisualGear(Gear);
       
    69 end;
       
    70 
       
    71 ////////////////////////////////////////////////////////////////////////////////
       
    72 procedure doStepCloud(Gear: PVisualGear; Steps: Longword);
       
    73 var i: Longword;
       
    74 begin
       
    75 Gear^.X:= Gear^.X + (cWindSpeed * 200 + Gear^.dX) * Steps;
       
    76 
       
    77 for i:= 0 to Steps - 1 do
       
    78     begin
       
    79     if hwRound(Gear^.Y) > LAND_HEIGHT-1184 then // TODO - configure in theme
       
    80         Gear^.dY:= Gear^.dY - _1div50000
       
    81     else
       
    82         Gear^.dY:= Gear^.dY + _1div50000;
       
    83 
       
    84     Gear^.Y:= Gear^.Y + Gear^.dY
       
    85     end;
       
    86 
       
    87 if hwRound(Gear^.X) < -cScreenWidth - 256 then Gear^.X:= int2hwFloat(cScreenWidth + LAND_WIDTH) else
       
    88 if hwRound(Gear^.X) > cScreenWidth + LAND_WIDTH then Gear^.X:= int2hwFloat(-cScreenWidth - 256)
       
    89 end;
       
    90 
       
    91 ////////////////////////////////////////////////////////////////////////////////
       
    92 procedure doStepExpl(Gear: PVisualGear; Steps: Longword);
       
    93 begin
       
    94 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
    95 
       
    96 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
    97 //Gear^.dY:= Gear^.dY + cGravity;
       
    98 
       
    99 if Gear^.FrameTicks <= Steps then
       
   100     if Gear^.Frame = 0 then DeleteVisualGear(Gear)
       
   101     else
       
   102         begin
       
   103         dec(Gear^.Frame);
       
   104         Gear^.FrameTicks:= cExplFrameTicks
       
   105         end
       
   106     else dec(Gear^.FrameTicks, Steps)
       
   107 end;
       
   108 
       
   109 ////////////////////////////////////////////////////////////////////////////////
       
   110 procedure doStepEgg(Gear: PVisualGear; Steps: Longword);
       
   111 begin
       
   112 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   113 
       
   114 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
   115 Gear^.dY:= Gear^.dY + cGravity * Steps;
       
   116 
       
   117 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
       
   118 
       
   119 if Gear^.FrameTicks <= Steps then
       
   120     DeleteVisualGear(Gear)
       
   121 else
       
   122     dec(Gear^.FrameTicks, Steps)
       
   123 end;
       
   124 
       
   125 ////////////////////////////////////////////////////////////////////////////////
       
   126 procedure doStepFire(Gear: PVisualGear; Steps: Longword);
       
   127 begin
       
   128 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   129 
       
   130 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;// + cGravity * (Steps * Steps);
       
   131 Gear^.dY:= Gear^.dY + cGravity * Steps;
       
   132 
       
   133 if Gear^.FrameTicks <= Steps then
       
   134        DeleteVisualGear(Gear)
       
   135 else
       
   136     dec(Gear^.FrameTicks, Steps)
       
   137 end;
       
   138 
       
   139 ////////////////////////////////////////////////////////////////////////////////
       
   140 procedure doStepShell(Gear: PVisualGear; Steps: Longword);
       
   141 begin
       
   142 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   143 
       
   144 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
   145 Gear^.dY:= Gear^.dY + cGravity * Steps;
       
   146 
       
   147 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
       
   148 
       
   149 if Gear^.FrameTicks <= Steps then
       
   150     DeleteVisualGear(Gear)
       
   151 else
       
   152     dec(Gear^.FrameTicks, Steps)
       
   153 end;
       
   154 
       
   155 procedure doStepSmallDamage(Gear: PVisualGear; Steps: Longword);
       
   156 begin
       
   157 Gear^.Y:= Gear^.Y - _0_02 * Steps;
       
   158 
       
   159 if Gear^.FrameTicks <= Steps then
       
   160     DeleteVisualGear(Gear)
       
   161 else
       
   162     dec(Gear^.FrameTicks, Steps)
       
   163 end;
       
   164 
       
   165 ////////////////////////////////////////////////////////////////////////////////
       
   166 procedure doStepBubble(Gear: PVisualGear; Steps: Longword);
       
   167 begin
       
   168     Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
       
   169     Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
       
   170 
       
   171     if (Gear^.FrameTicks <= Steps) or (hwRound(Gear^.Y) < cWaterLine) then
       
   172         DeleteVisualGear(Gear)
       
   173     else
       
   174         dec(Gear^.FrameTicks, Steps)
       
   175 end;
       
   176 
       
   177 ////////////////////////////////////////////////////////////////////////////////
       
   178 procedure doStepHealth(Gear: PVisualGear; Steps: Longword);
       
   179 begin
       
   180 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   181 Gear^.Y:= Gear^.Y - Gear^.dY * Steps;
       
   182 
       
   183 if Gear^.FrameTicks <= Steps then
       
   184     DeleteVisualGear(Gear)
       
   185 else
       
   186     dec(Gear^.FrameTicks, Steps);
       
   187 end;
       
   188 
       
   189 ////////////////////////////////////////////////////////////////////////////////
       
   190 procedure doStepSteam(Gear: PVisualGear; Steps: Longword);
       
   191 begin
       
   192     Gear^.X:= Gear^.X + (cWindSpeed * 100 + Gear^.dX) * Steps;
       
   193     Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
       
   194 
       
   195     if Gear^.FrameTicks <= Steps then
       
   196         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
       
   197         else
       
   198             begin
       
   199             if Random(2) = 0 then dec(Gear^.Frame);
       
   200             Gear^.FrameTicks:= cExplFrameTicks
       
   201             end
       
   202         else dec(Gear^.FrameTicks, Steps)
       
   203 end;
       
   204 
       
   205 ////////////////////////////////////////////////////////////////////////////////
       
   206 procedure doStepAmmo(Gear: PVisualGear; Steps: Longword);
       
   207 begin
       
   208     Gear^.Y:= Gear^.Y - cDrownSpeed * Steps;
       
   209 
       
   210     Gear^.scale:= Gear^.scale + 0.0025 * Steps;
       
   211     Gear^.alpha:= Gear^.alpha - 0.0015 * Steps;
       
   212 
       
   213     if Gear^.alpha < 0 then DeleteVisualGear(Gear)
       
   214 end;
       
   215 
       
   216 ////////////////////////////////////////////////////////////////////////////////
       
   217 procedure doStepSmoke(Gear: PVisualGear; Steps: Longword);
       
   218 begin
       
   219     Gear^.X:= Gear^.X + (cWindSpeed + Gear^.dX) * Steps;
       
   220     Gear^.Y:= Gear^.Y - (cDrownSpeed + Gear^.dY) * Steps;
       
   221 
       
   222     Gear^.dX := Gear^.dX + (cWindSpeed * _0_3 * Steps);
       
   223     //Gear^.dY := Gear^.dY - (cDrownSpeed * _0_995);
       
   224 
       
   225     if Gear^.FrameTicks <= Steps then
       
   226         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
       
   227         else
       
   228             begin
       
   229             if Random(2) = 0 then dec(Gear^.Frame);
       
   230             Gear^.FrameTicks:= cExplFrameTicks
       
   231             end
       
   232         else dec(Gear^.FrameTicks, Steps)
       
   233 end;
       
   234 
       
   235 ////////////////////////////////////////////////////////////////////////////////
       
   236 procedure doStepDust(Gear: PVisualGear; Steps: Longword);
       
   237 begin
       
   238     Gear^.X:= Gear^.X + (cWindSpeed + (cWindSpeed * _0_03 * Steps) + Gear^.dX) * Steps;
       
   239     Gear^.Y:= Gear^.Y - (Gear^.dY) * Steps;
       
   240 
       
   241     Gear^.dX := Gear^.dX - (Gear^.dX * _0_005 * Steps);
       
   242     Gear^.dY := Gear^.dY - (cDrownSpeed * _0_001 * Steps);
       
   243 
       
   244     if Gear^.FrameTicks <= Steps then
       
   245         if Gear^.Frame = 0 then DeleteVisualGear(Gear)
       
   246         else
       
   247             begin
       
   248             dec(Gear^.Frame);
       
   249             Gear^.FrameTicks:= cExplFrameTicks
       
   250             end
       
   251         else dec(Gear^.FrameTicks, Steps)
       
   252 end;
       
   253 
       
   254 ////////////////////////////////////////////////////////////////////////////////
       
   255 procedure doStepSplash(Gear: PVisualGear; Steps: Longword);
       
   256 begin
       
   257   if Gear^.FrameTicks <= Steps then
       
   258       DeleteVisualGear(Gear)
       
   259   else
       
   260       dec(Gear^.FrameTicks, Steps);
       
   261 end;
       
   262 
       
   263 ////////////////////////////////////////////////////////////////////////////////
       
   264 procedure doStepDroplet(Gear: PVisualGear; Steps: Longword);
       
   265 begin
       
   266   Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   267 
       
   268   Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
   269   Gear^.dY:= Gear^.dY + cGravity * Steps;
       
   270 
       
   271   if hwRound(Gear^.Y) > cWaterLine then begin
       
   272     DeleteVisualGear(Gear);
       
   273     PlaySound(TSound(ord(sndDroplet1) + Random(3)));
       
   274     end;
       
   275 end;
       
   276 
       
   277 ////////////////////////////////////////////////////////////////////////////////
       
   278 procedure doStepSmokeRing(Gear: PVisualGear; Steps: Longword);
       
   279 begin
       
   280 inc(Gear^.Timer, Steps);
       
   281 if Gear^.Timer >= Gear^.FrameTicks then DeleteVisualGear(Gear)
       
   282 else
       
   283     begin
       
   284     Gear^.scale := 1.25 * (-power(2, -10 * Int(Gear^.Timer)/Gear^.FrameTicks) + 1) + 0.4;
       
   285     Gear^.alpha := 1 - power(Gear^.Timer / 350, 4);
       
   286     if Gear^.alpha < 0 then Gear^.alpha:= 0;
       
   287     end;
       
   288 end;
       
   289 
       
   290 ////////////////////////////////////////////////////////////////////////////////
       
   291 procedure doStepFeather(Gear: PVisualGear; Steps: Longword);
       
   292 begin
       
   293 Gear^.X:= Gear^.X + Gear^.dX * Steps;
       
   294 
       
   295 Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
   296 Gear^.dY:= Gear^.dY + cGravity * Steps;
       
   297 
       
   298 Gear^.Angle:= round(Gear^.Angle + Steps) mod cMaxAngle;
       
   299 
       
   300 if Gear^.FrameTicks <= Steps then
       
   301     DeleteVisualGear(Gear)
       
   302 else
       
   303     dec(Gear^.FrameTicks, Steps)
       
   304 end;
       
   305 
       
   306 ////////////////////////////////////////////////////////////////////////////////
       
   307 const cSorterWorkTime = 640;
       
   308 var thexchar: array[0..cMaxTeams] of
       
   309             record
       
   310             dy, ny, dw: LongInt;
       
   311             team: PTeam;
       
   312             SortFactor: QWord;
       
   313             end;
       
   314     currsorter: PVisualGear = nil;
       
   315 
       
   316 procedure doStepTeamHealthSorterWork(Gear: PVisualGear; Steps: Longword);
       
   317 var i, t: LongInt;
       
   318 begin
       
   319 for t:= 1 to Steps do
       
   320     begin
       
   321     dec(Gear^.Timer);
       
   322     if (Gear^.Timer and 15) = 0 then
       
   323         for i:= 0 to Pred(TeamsCount) do
       
   324             with thexchar[i] do
       
   325                 begin
       
   326                 {$WARNINGS OFF}
       
   327                 team^.DrawHealthY:= ny + dy * LongInt(Gear^.Timer) div 640;
       
   328                 team^.TeamHealthBarWidth:= team^.NewTeamHealthBarWidth + dw * LongInt(Gear^.Timer) div cSorterWorkTime;
       
   329                 {$WARNINGS ON}
       
   330                 end;
       
   331 
       
   332     if (Gear^.Timer = 0) or (currsorter <> Gear) then
       
   333         begin
       
   334         if currsorter = Gear then currsorter:= nil;
       
   335         DeleteVisualGear(Gear);
       
   336         exit
       
   337         end
       
   338     end
       
   339 end;
       
   340 
       
   341 procedure doStepTeamHealthSorter(Gear: PVisualGear; Steps: Longword);
       
   342 var i: Longword;
       
   343     b: boolean;
       
   344     t: LongInt;
       
   345 begin
       
   346 Steps:= Steps; // avoid compiler hint
       
   347 for t:= 0 to Pred(TeamsCount) do
       
   348     with thexchar[t] do
       
   349         begin
       
   350         dy:= TeamsArray[t]^.DrawHealthY;
       
   351         dw:= TeamsArray[t]^.TeamHealthBarWidth - TeamsArray[t]^.NewTeamHealthBarWidth;
       
   352         team:= TeamsArray[t];
       
   353         SortFactor:= TeamsArray[t]^.Clan^.ClanHealth;
       
   354         SortFactor:= (SortFactor shl  3) + TeamsArray[t]^.Clan^.ClanIndex;
       
   355         SortFactor:= (SortFactor shl 30) + TeamsArray[t]^.TeamHealth;
       
   356         end;
       
   357 
       
   358 if TeamsCount > 1 then
       
   359     repeat
       
   360     b:= true;
       
   361     for t:= 0 to TeamsCount - 2 do
       
   362         if (thexchar[t].SortFactor > thexchar[Succ(t)].SortFactor) then
       
   363             begin
       
   364             thexchar[cMaxTeams]:= thexchar[t];
       
   365             thexchar[t]:= thexchar[Succ(t)];
       
   366             thexchar[Succ(t)]:= thexchar[cMaxTeams];
       
   367             b:= false
       
   368             end
       
   369     until b;
       
   370 
       
   371 t:= - 4;
       
   372 for i:= 0 to Pred(TeamsCount) do
       
   373     with thexchar[i] do
       
   374         begin
       
   375         dec(t, team^.HealthTex^.h + 2);
       
   376         ny:= t;
       
   377         dy:= dy - ny
       
   378         end;
       
   379 
       
   380 Gear^.Timer:= cSorterWorkTime;
       
   381 Gear^.doStep:= @doStepTeamHealthSorterWork;
       
   382 currsorter:= Gear;
       
   383 //doStepTeamHealthSorterWork(Gear, Steps)
       
   384 end;
       
   385 
       
   386 ////////////////////////////////////////////////////////////////////////////////
       
   387 procedure doStepSpeechBubbleWork(Gear: PVisualGear; Steps: Longword);
       
   388 begin
       
   389 if Gear^.Timer > Steps then dec(Gear^.Timer, Steps) else Gear^.Timer:= 0;
       
   390 
       
   391 if (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
       
   392     begin
       
   393     Gear^.X:= PHedgehog(Gear^.Hedgehog)^.Gear^.X + int2hwFloat(Gear^.Tex^.w div 2  - Gear^.FrameTicks);
       
   394     Gear^.Y:= PHedgehog(Gear^.Hedgehog)^.Gear^.Y - int2hwFloat(16 + Gear^.Tex^.h);
       
   395     end;
       
   396 
       
   397 if Gear^.Timer = 0 then
       
   398     begin
       
   399     if PHedgehog(Gear^.Hedgehog)^.SpeechGear = Gear then
       
   400         PHedgehog(Gear^.Hedgehog)^.SpeechGear:= nil;
       
   401     DeleteVisualGear(Gear)
       
   402     end;
       
   403 end;
       
   404 
       
   405 procedure doStepSpeechBubble(Gear: PVisualGear; Steps: Longword);
       
   406 begin
       
   407 Steps:= Steps; // avoid compiler hint
       
   408 
       
   409 with PHedgehog(Gear^.Hedgehog)^ do
       
   410     if SpeechGear <> nil then SpeechGear^.Timer:= 0;
       
   411 
       
   412 PHedgehog(Gear^.Hedgehog)^.SpeechGear:= Gear;
       
   413 
       
   414 Gear^.Timer:= max(Length(Gear^.Text) * 150, 3000);
       
   415 
       
   416 Gear^.Tex:= RenderSpeechBubbleTex(Gear^.Text, Gear^.FrameTicks, fnt16);
       
   417 
       
   418 case Gear^.FrameTicks of
       
   419     1: Gear^.FrameTicks:= SpritesData[sprSpeechTail].Width-28;
       
   420     2: Gear^.FrameTicks:= SpritesData[sprThoughtTail].Width-20;
       
   421     3: Gear^.FrameTicks:= SpritesData[sprShoutTail].Width-10;
       
   422     end;
       
   423 
       
   424 Gear^.doStep:= @doStepSpeechBubbleWork;
       
   425 
       
   426 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h)
       
   427 end;
       
   428 
       
   429 ////////////////////////////////////////////////////////////////////////////////
       
   430 procedure doStepHealthTagWork(Gear: PVisualGear; Steps: Longword);
       
   431 begin
       
   432 //if Gear^.Kind = gtHealthTag then
       
   433 //    AllInactive:= false;
       
   434 
       
   435 if Steps > Gear^.Timer then
       
   436     begin
       
   437 //    if (Gear^.Kind = vgtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then
       
   438 //        PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die
       
   439     DeleteVisualGear(Gear);
       
   440     end
       
   441 else
       
   442     begin
       
   443     dec(Gear^.Timer, Steps);
       
   444     Gear^.Y:= Gear^.Y + Gear^.dY * Steps;
       
   445     end;
       
   446 end;
       
   447 
       
   448 procedure doStepHealthTagWorkUnderWater(Gear: PVisualGear; Steps: Longword);
       
   449 begin
       
   450 //AllInactive:= false;
       
   451 
       
   452 if hwRound(Gear^.Y) < cWaterLine + 10 then
       
   453     DeleteVisualGear(Gear)
       
   454 else
       
   455     Gear^.Y:= Gear^.Y - _0_08 * Steps;
       
   456 
       
   457 end;
       
   458 
       
   459 procedure doStepHealthTag(Gear: PVisualGear; Steps: Longword);
       
   460 var s: shortstring;
       
   461 begin
       
   462 //AllInactive:= false;
       
   463 
       
   464 s:= '';
       
   465 
       
   466 Gear^.dY:= -_0_08;
       
   467 
       
   468 str(Gear^.State, s);
       
   469 Gear^.Tex:= RenderStringTex(s, PHedgehog(Gear^.Hedgehog)^.Team^.Clan^.Color, fnt16);
       
   470 
       
   471 if hwRound(Gear^.Y) < cWaterLine then
       
   472     Gear^.doStep:= @doStepHealthTagWork
       
   473 else
       
   474     Gear^.doStep:= @doStepHealthTagWorkUnderWater;
       
   475 
       
   476 Gear^.Y:= Gear^.Y - int2hwFloat(Gear^.Tex^.h);
       
   477 
       
   478 if Steps > 1 then Gear^.doStep(Gear, Steps-1);
       
   479 end;
       
   480 
       
   481 ////////////////////////////////////////////////////////////////////////////////
       
   482 procedure doStepSmokeTrace(Gear: PVisualGear; Steps: Longword);
       
   483 var i: Longword;
       
   484 begin
       
   485 inc(Gear^.Timer, Steps );
       
   486 if Gear^.Timer > 64 then
       
   487     begin
       
   488     dec(Gear^.State, Gear^.Timer div 65);
       
   489     Gear^.Timer:= Gear^.Timer mod 65;
       
   490     end;
       
   491 for i:= 1 to Steps do
       
   492     begin
       
   493     Gear^.dX:= Gear^.dX + cWindSpeed;
       
   494     Gear^.X:= Gear^.X + Gear^.dX;
       
   495     end;
       
   496 if Gear^.State = 0 then DeleteVisualGear(Gear);
       
   497 end;
       
   498 
       
   499 ////////////////////////////////////////////////////////////////////////////////
       
   500 procedure doStepExplosionWork(Gear: PVisualGear; Steps: Longword);
       
   501 begin
       
   502 inc(Gear^.Timer, Steps);
       
   503 if Gear^.Timer > 75 then
       
   504     begin
       
   505     inc(Gear^.State, Gear^.Timer div 76);
       
   506     Gear^.Timer:= Gear^.Timer mod 76;
       
   507     if Gear^.State > 5 then DeleteVisualGear(Gear);
       
   508     end;
       
   509 end;
       
   510 
       
   511 procedure doStepExplosion(Gear: PVisualGear; Steps: Longword);
       
   512 var i: LongWord;
       
   513 begin
       
   514 
       
   515 for i:= 0 to 31 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire);
       
   516 for i:= 0 to 8 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplPart);
       
   517 for i:= 0 to 8 do AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtExplPart2);
       
   518 Gear^.doStep:= @doStepExplosionWork;
       
   519 if Steps > 1 then Gear^.doStep(Gear, Steps-1);
       
   520 end;
       
   521 
       
   522 
       
   523 ////////////////////////////////////////////////////////////////////////////////
       
   524 procedure doStepBigExplosionWork(Gear: PVisualGear; Steps: Longword);
       
   525 var maxMovement: LongInt;
       
   526 begin
       
   527 
       
   528 inc(Gear^.Timer, Steps);
       
   529 if (Gear^.Timer and 5) = 0 then
       
   530     begin
       
   531     maxMovement := max(1, 13 - ((Gear^.Timer * 15) div 250));
       
   532     ShakeCamera(maxMovement);
       
   533     end;
       
   534 if Gear^.Timer > 250 then DeleteVisualGear(Gear);
       
   535 end;
       
   536 
       
   537 procedure doStepBigExplosion(Gear: PVisualGear; Steps: Longword);
       
   538 var i: LongWord;
       
   539 gX,gY: LongInt;
       
   540 begin
       
   541 gX:= hwRound(Gear^.X);
       
   542 gY:= hwRound(Gear^.Y);
       
   543 AddVisualGear(gX, gY, vgtSmokeRing);
       
   544 for i:= 0 to 46 do AddVisualGear(gX, gY, vgtFire);
       
   545 for i:= 0 to 15 do AddVisualGear(gX, gY, vgtExplPart);
       
   546 for i:= 0 to 15 do AddVisualGear(gX, gY, vgtExplPart2);
       
   547 Gear^.doStep:= @doStepBigExplosionWork;
       
   548 if Steps > 1 then Gear^.doStep(Gear, Steps-1);
       
   549 end;