hedgewars/uVisualGears.pas
changeset 6179 b529f88d37d0
parent 6117 2a4829172a29
child 6184 335ece2bce9c
equal deleted inserted replaced
6178:affa860f2983 6179:b529f88d37d0
   143 gear^.Kind := Kind;
   143 gear^.Kind := Kind;
   144 gear^.doStep:= doStepHandlers[Kind];
   144 gear^.doStep:= doStepHandlers[Kind];
   145 gear^.State:= 0;
   145 gear^.State:= 0;
   146 gear^.Tint:= $FFFFFFFF;
   146 gear^.Tint:= $FFFFFFFF;
   147 gear^.uid:= VGCounter;
   147 gear^.uid:= VGCounter;
       
   148 gear^.Layer:= 0;
   148 
   149 
   149 with gear^ do
   150 with gear^ do
   150     case Kind of
   151     case Kind of
   151     vgtFlake: begin
   152     vgtFlake: begin
   152                 Timer:= 0;
   153                 Timer:= 0;
   334         end;
   335         end;
   335 
   336 
   336 if State <> 0 then gear^.State:= State;
   337 if State <> 0 then gear^.State:= State;
   337 
   338 
   338 case Gear^.Kind of
   339 case Gear^.Kind of
       
   340     vgtFlake: if random(2) = 0 then gear^.Layer:= 0
       
   341               else gear^.Layer:= random(3)+1;
       
   342 
   339     // 0: this layer is very distant in the background when stereo
   343     // 0: this layer is very distant in the background when stereo
   340     vgtTeamHealthSorter,
   344     vgtTeamHealthSorter,
   341     vgtSmoothWindBar,
   345     vgtSmoothWindBar,
   342     vgtFlake, 
   346     vgtCloud: gear^.Layer:= 0;
   343     vgtCloud: begin
   347 
   344               if VisualGearsLayer0 <> nil then
       
   345                   begin
       
   346                   VisualGearsLayer0^.PrevGear:= gear;
       
   347                   gear^.NextGear:= VisualGearsLayer0
       
   348                   end;
       
   349               gear^.Layer:= 0;
       
   350               VisualGearsLayer0:= gear
       
   351               end; 
       
   352     // 1: this layer is on the land level (which is close but behind the screen plane) when stereo
   348     // 1: this layer is on the land level (which is close but behind the screen plane) when stereo
   353     vgtSmokeTrace,
   349     vgtSmokeTrace,
   354     vgtEvilTrace,
   350     vgtEvilTrace,
   355     vgtLineTrail,
   351     vgtLineTrail,
   356     vgtSmoke,
   352     vgtSmoke,
   357     vgtSmokeWhite,
   353     vgtSmokeWhite,
   358     vgtDust,
   354     vgtDust,
   359     vgtFire,
   355     vgtFire,
   360     vgtSplash,
   356     vgtSplash,
   361     vgtDroplet,
   357     vgtDroplet,
   362     vgtBubble: begin
   358     vgtBubble: gear^.Layer:= 1;
   363               if VisualGearsLayer1 <> nil then
   359 
   364                   begin
       
   365                   VisualGearsLayer1^.PrevGear:= gear;
       
   366                   gear^.NextGear:= VisualGearsLayer1
       
   367                   end;
       
   368               gear^.Layer:= 1;
       
   369               VisualGearsLayer1:= gear
       
   370               end; 
       
   371     // 3: this layer is on the screen plane (depth = 0) when stereo
   360     // 3: this layer is on the screen plane (depth = 0) when stereo
   372     vgtSpeechBubble,
   361     vgtSpeechBubble,
   373     vgtSmallDamageTag,
   362     vgtSmallDamageTag,
   374     vgtHealthTag,
   363     vgtHealthTag,
   375     vgtStraightShot,
   364     vgtStraightShot,
   376     vgtChunk: begin
   365     vgtChunk: gear^.Layer:= 3;
   377               if VisualGearsLayer3 <> nil then
   366 
   378                   begin
       
   379                   VisualGearsLayer3^.PrevGear:= gear;
       
   380                   gear^.NextGear:= VisualGearsLayer3
       
   381                   end;
       
   382               gear^.Layer:= 3;
       
   383               VisualGearsLayer3:= gear
       
   384               end; 
       
   385     // 2: this layer is outside the screen when stereo
   367     // 2: this layer is outside the screen when stereo
   386     vgtExplosion,
   368     vgtExplosion,
   387     vgtBigExplosion,
   369     vgtBigExplosion,
   388     vgtExplPart,
   370     vgtExplPart,
   389     vgtExplPart2,
   371     vgtExplPart2,
   394     vgtEgg,
   376     vgtEgg,
   395     vgtBeeTrace,
   377     vgtBeeTrace,
   396     vgtSmokeRing,
   378     vgtSmokeRing,
   397     vgtNote,
   379     vgtNote,
   398     vgtBulletHit,
   380     vgtBulletHit,
   399     vgtCircle: begin
   381     vgtCircle: gear^.Layer:= 2
   400               if VisualGearsLayer2 <> nil then
   382 end;
   401                   begin
   383 
   402                   VisualGearsLayer2^.PrevGear:= gear;
   384 if VisualGearLayers[gear^.Layer] <> nil then
   403                   gear^.NextGear:= VisualGearsLayer2
   385     begin
   404                   end;
   386     VisualGearLayers[gear^.Layer]^.PrevGear:= gear;
   405               gear^.Layer:= 2;
   387     gear^.NextGear:= VisualGearLayers[gear^.Layer]
   406               VisualGearsLayer2:= gear
   388     end;
   407               end; 
   389 VisualGearLayers[gear^.Layer]:= gear;
   408 end;
       
   409 
   390 
   410 AddVisualGear:= gear;
   391 AddVisualGear:= gear;
   411 end;
   392 end;
   412 
   393 
   413 procedure DeleteVisualGear(Gear: PVisualGear);
   394 procedure DeleteVisualGear(Gear: PVisualGear);
   416         FreeTexture(Gear^.Tex);
   397         FreeTexture(Gear^.Tex);
   417     Gear^.Tex:= nil;
   398     Gear^.Tex:= nil;
   418 
   399 
   419     if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   400     if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
   420     if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   401     if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
   421     else
   402     else VisualGearLayers[Gear^.Layer]:= Gear^.NextGear;
   422         case Gear^.Layer of
       
   423             0: VisualGearsLayer0:= Gear^.NextGear;
       
   424             1: VisualGearsLayer1:= Gear^.NextGear;
       
   425             2: VisualGearsLayer2:= Gear^.NextGear;
       
   426             3: VisualGearsLayer3:= Gear^.NextGear;
       
   427         end;
       
   428 
   403 
   429     if lastVisualGearByUID = Gear then lastVisualGearByUID:= nil;
   404     if lastVisualGearByUID = Gear then lastVisualGearByUID:= nil;
   430 
   405 
   431     Dispose(Gear);
   406     Dispose(Gear);
   432 end;
   407 end;
   433 
   408 
   434 procedure ProcessVisualGears(Steps: Longword);
   409 procedure ProcessVisualGears(Steps: Longword);
   435 var Gear, t: PVisualGear;
   410 var Gear, t: PVisualGear;
       
   411     i: LongWord;
   436 begin
   412 begin
   437 if Steps = 0 then exit;
   413 if Steps = 0 then exit;
   438 
   414 
   439 t:= VisualGearsLayer0;
   415 for i:= 0 to 3 do
       
   416     begin
       
   417     t:= VisualGearLayers[i];
       
   418     while t <> nil do
       
   419           begin
       
   420           Gear:= t;
       
   421           t:= Gear^.NextGear;
       
   422           Gear^.doStep(Gear, Steps)
       
   423           end;
       
   424     end
       
   425 end;
       
   426 
       
   427 procedure KickFlakes(Radius, X, Y: LongInt);
       
   428 var Gear, t: PVisualGear;
       
   429     dmg: LongInt;
       
   430 begin
       
   431 if (vobCount = 0) or (vobCount > 200) then exit;
       
   432 t:= VisualGearLayers[1];
   440 while t <> nil do
   433 while t <> nil do
   441       begin
   434       begin
   442       Gear:= t;
   435       Gear:= t;
   443       t:= Gear^.NextGear;
   436       if Gear^.Kind = vgtFlake then
   444       Gear^.doStep(Gear, Steps)
   437           begin
       
   438           // Damage calc from doMakeExplosion
       
   439           dmg:= Min(101, Radius + cHHRadius div 2 - LongInt(abs(round(Gear^.X) - X) + abs(round(Gear^.Y) - Y)) div 5);
       
   440           if dmg > 1 then
       
   441               begin
       
   442               Gear^.tdX:= 0.02 * dmg + 0.01;
       
   443               if Gear^.X - X < 0 then Gear^.tdX := -Gear^.tdX;
       
   444               Gear^.tdY:= 0.02 * dmg + 0.01;
       
   445               if Gear^.Y - Y < 0 then Gear^.tdY := -Gear^.tdY;
       
   446               Gear^.Timer:= 200
       
   447               end
       
   448           end;
       
   449       t:= Gear^.NextGear
   445       end;
   450       end;
   446 t:= VisualGearsLayer1;
   451 t:= VisualGearLayers[3];
   447 while t <> nil do
       
   448       begin
       
   449       Gear:= t;
       
   450       t:= Gear^.NextGear;
       
   451       Gear^.doStep(Gear, Steps)
       
   452       end;
       
   453 t:= VisualGearsLayer2;
       
   454 while t <> nil do
       
   455       begin
       
   456       Gear:= t;
       
   457       t:= Gear^.NextGear;
       
   458       Gear^.doStep(Gear, Steps)
       
   459       end;
       
   460 t:= VisualGearsLayer3;
       
   461 while t <> nil do
       
   462       begin
       
   463       Gear:= t;
       
   464       t:= Gear^.NextGear;
       
   465       Gear^.doStep(Gear, Steps)
       
   466       end
       
   467 end;
       
   468 
       
   469 procedure KickFlakes(Radius, X, Y: LongInt);
       
   470 var Gear, t: PVisualGear;
       
   471     dmg: LongInt;
       
   472 begin
       
   473 if (vobCount = 0) or (vobCount > 200) then exit;
       
   474 t:= VisualGearsLayer0;
       
   475 while t <> nil do
   452 while t <> nil do
   476       begin
   453       begin
   477       Gear:= t;
   454       Gear:= t;
   478       if Gear^.Kind = vgtFlake then
   455       if Gear^.Kind = vgtFlake then
   479           begin
   456           begin
   499     i: LongInt;
   476     i: LongInt;
   500 begin
   477 begin
   501 case Layer of
   478 case Layer of
   502     // this layer is very distant in the background when stereo
   479     // this layer is very distant in the background when stereo
   503     0: begin
   480     0: begin
   504        Gear:= VisualGearsLayer0;
   481        Gear:= VisualGearLayers[0];
   505        while Gear <> nil do
   482        while Gear <> nil do
   506            begin
   483            begin
   507            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   484            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   508            case Gear^.Kind of
   485            case Gear^.Kind of
   509                vgtFlake: if SuddenDeathDmg then
   486                vgtFlake: if SuddenDeathDmg then
   510                              if vobSDVelocity = 0 then
   487                              if vobSDVelocity = 0 then
   511                                  DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
   488                                  DrawTextureF(SpritesData[sprSDFlake].Texture, 0.5, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height)
   512                              else
   489                              else
   513                                  DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle)
   490                                  DrawRotatedTextureF(SpritesData[sprSDFlake].Texture, 0.5, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle)
   514                          else
   491                          else
   515                              if vobVelocity = 0 then
   492                              if vobVelocity = 0 then
   516                                  DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
   493                                  DrawTextureF(SpritesData[sprFlake].Texture, 0.5, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height)
   517                              else
   494                              else
   518                                  DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);
   495                                  DrawRotatedTextureF(SpritesData[sprFlake].Texture, 0.5, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle);
   519                vgtCloud: if SuddenDeathDmg then
   496                vgtCloud: if SuddenDeathDmg then
   520                              DrawSprite(sprSDCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
   497                              DrawSprite(sprSDCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
   521                          else
   498                          else
   522                              DrawSprite(sprCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame);
   499                              DrawSprite(sprCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame);
   523                end;
   500                end;
   525            Gear:= Gear^.NextGear
   502            Gear:= Gear^.NextGear
   526            end
   503            end
   527        end;
   504        end;
   528     // this layer is on the land level (which is close but behind the screen plane) when stereo
   505     // this layer is on the land level (which is close but behind the screen plane) when stereo
   529     1: begin
   506     1: begin
   530        Gear:= VisualGearsLayer1;
   507        Gear:= VisualGearLayers[1];
   531        while Gear <> nil do
   508        while Gear <> nil do
   532           begin
   509           begin
   533           //tinted:= false;
   510           //tinted:= false;
   534           if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   511           if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   535           case Gear^.Kind of
   512           case Gear^.Kind of
       
   513               vgtFlake: if SuddenDeathDmg then
       
   514                              if vobSDVelocity = 0 then
       
   515                                  DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
       
   516                              else
       
   517                                  DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle)
       
   518                          else
       
   519                              if vobVelocity = 0 then
       
   520                                  DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
       
   521                              else
       
   522                                  DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);
   536               vgtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
   523               vgtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
   537               vgtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
   524               vgtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
   538               vgtLineTrail: DrawLine(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 1.0, $FF, min(Gear^.Timer, $C0), min(Gear^.Timer, $80), min(Gear^.Timer, $FF));
   525               vgtLineTrail: DrawLine(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 1.0, $FF, min(Gear^.Timer, $C0), min(Gear^.Timer, $80), min(Gear^.Timer, $FF));
   539           end;
   526           end;
   540           if (cReducedQuality and rqAntiBoom) = 0 then
   527           if (cReducedQuality and rqAntiBoom) = 0 then
   564           Gear:= Gear^.NextGear
   551           Gear:= Gear^.NextGear
   565           end
   552           end
   566        end;
   553        end;
   567     // this layer is on the screen plane (depth = 0) when stereo
   554     // this layer is on the screen plane (depth = 0) when stereo
   568     3: begin
   555     3: begin
   569        Gear:= VisualGearsLayer3;
   556        Gear:= VisualGearLayers[3];
   570        while Gear <> nil do
   557        while Gear <> nil do
   571            begin
   558            begin
   572            tinted:= false;
   559            tinted:= false;
   573            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   560            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   574            case Gear^.Kind of
   561            case Gear^.Kind of
       
   562               vgtFlake: if SuddenDeathDmg then
       
   563                              if vobSDVelocity = 0 then
       
   564                                  DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
       
   565                              else
       
   566                                  DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle)
       
   567                          else
       
   568                              if vobVelocity = 0 then
       
   569                                  DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
       
   570                              else
       
   571                                  DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);
   575                vgtSpeechBubble: begin
   572                vgtSpeechBubble: begin
   576                                 if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then
   573                                 if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then
   577                                     begin
   574                                     begin
   578                                     tinted:= true;
   575                                     tinted:= true;
   579                                     Tint($FF, $FF, $FF,  $66);
   576                                     Tint($FF, $FF, $FF,  $66);
   608            Gear:= Gear^.NextGear
   605            Gear:= Gear^.NextGear
   609            end
   606            end
   610        end;
   607        end;
   611     // this layer is outside the screen when stereo
   608     // this layer is outside the screen when stereo
   612     2: begin
   609     2: begin
   613        Gear:= VisualGearsLayer2;
   610        Gear:= VisualGearLayers[2];
   614        while Gear <> nil do
   611        while Gear <> nil do
   615            begin
   612            begin
   616            tinted:= false;
   613            tinted:= false;
   617            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   614            if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
   618            case Gear^.Kind of
   615            case Gear^.Kind of
   666                                  end;
   663                                  end;
   667                    vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   664                    vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
   668                    vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle);
   665                    vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle);
   669                end;
   666                end;
   670            case Gear^.Kind of
   667            case Gear^.Kind of
       
   668                vgtFlake: if SuddenDeathDmg then
       
   669                              if vobSDVelocity = 0 then
       
   670                                  DrawTextureF(SpritesData[sprSDFlake].Texture, 1.5, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height)
       
   671                              else
       
   672                                  DrawRotatedTextureF(SpritesData[sprSDFlake].Texture, 1.5, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle)
       
   673                          else
       
   674                              if vobVelocity = 0 then
       
   675                                  DrawTextureF(SpritesData[sprFlake].Texture, 1.5, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height)
       
   676                              else
       
   677                                  DrawRotatedTextureF(SpritesData[sprFlake].Texture, 1.5, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, SpritesData[sprFlake].Width, SpritesData[sprFlake].Height, Gear^.Angle);
   671                vgtCircle: if gear^.Angle = 1 then
   678                vgtCircle: if gear^.Angle = 1 then
   672                               begin
   679                               begin
   673                               tmp:= Gear^.State / 100;
   680                               tmp:= Gear^.State / 100;
   674                               DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp)
   681                               DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp)
   675                               end
   682                               end
   682     end;
   689     end;
   683 end;
   690 end;
   684 
   691 
   685 function  VisualGearByUID(uid : Longword) : PVisualGear;
   692 function  VisualGearByUID(uid : Longword) : PVisualGear;
   686 var vg: PVisualGear;
   693 var vg: PVisualGear;
       
   694     i: LongWord;
   687 begin
   695 begin
   688 VisualGearByUID:= nil;
   696 VisualGearByUID:= nil;
   689 if uid = 0 then exit;
   697 if uid = 0 then exit;
   690 if (lastVisualGearByUID <> nil) and (lastVisualGearByUID^.uid = uid) then
   698 if (lastVisualGearByUID <> nil) and (lastVisualGearByUID^.uid = uid) then
   691     begin
   699     begin
   692     VisualGearByUID:= lastVisualGearByUID;
   700     VisualGearByUID:= lastVisualGearByUID;
   693     exit
   701     exit
   694     end;
   702     end;
   695 vg:= VisualGearsLayer0;
   703 // search in an order that is more likely to return layers they actually use.  Could perhaps track statistically AddVisualGear in uScript, since that is most likely the ones they want
   696 while vg <> nil do
   704 for i:= 2 to 5 do
   697     begin
   705     begin
   698     if vg^.uid = uid then
   706     vg:= VisualGearLayers[i mod 4];
       
   707     while vg <> nil do
   699         begin
   708         begin
   700         lastVisualGearByUID:= vg;
   709         if vg^.uid = uid then
   701         VisualGearByUID:= vg;
   710     	    begin
   702         exit
   711     	    lastVisualGearByUID:= vg;
   703         end;
   712     	    VisualGearByUID:= vg;
   704     vg:= vg^.NextGear
   713     	    exit
   705     end;
   714     	    end;
   706 vg:= VisualGearsLayer1;
   715         vg:= vg^.NextGear
   707 while vg <> nil do
   716         end
   708     begin
       
   709     if vg^.uid = uid then
       
   710         begin
       
   711         lastVisualGearByUID:= vg;
       
   712         VisualGearByUID:= vg;
       
   713         exit
       
   714         end;
       
   715     vg:= vg^.NextGear
       
   716     end;
       
   717 vg:= VisualGearsLayer2;
       
   718 while vg <> nil do
       
   719     begin
       
   720     if vg^.uid = uid then
       
   721         begin
       
   722         lastVisualGearByUID:= vg;
       
   723         VisualGearByUID:= vg;
       
   724         exit
       
   725         end;
       
   726     vg:= vg^.NextGear
       
   727     end;
       
   728 vg:= VisualGearsLayer3;
       
   729 while vg <> nil do
       
   730     begin
       
   731     if vg^.uid = uid then
       
   732         begin
       
   733         lastVisualGearByUID:= vg;
       
   734         VisualGearByUID:= vg;
       
   735         exit
       
   736         end;
       
   737     vg:= vg^.NextGear
       
   738     end
   717     end
   739 end;
   718 end;
   740 
   719 
   741 procedure AddClouds;
   720 procedure AddClouds;
   742 var i: LongInt;
   721 var i: LongInt;
   748 procedure ChangeToSDClouds;
   727 procedure ChangeToSDClouds;
   749 var       i: LongInt;
   728 var       i: LongInt;
   750     vg, tmp: PVisualGear;
   729     vg, tmp: PVisualGear;
   751 begin
   730 begin
   752 if cCloudsNumber = cSDCloudsNumber then exit;
   731 if cCloudsNumber = cSDCloudsNumber then exit;
   753 vg:= VisualGearsLayer0;
   732 vg:= VisualGearLayers[0];
   754 while vg <> nil do
   733 while vg <> nil do
   755     if vg^.Kind = vgtCloud then
   734     if vg^.Kind = vgtCloud then
   756         begin
   735         begin
   757         tmp:= vg^.NextGear;
   736         tmp:= vg^.NextGear;
   758         DeleteVisualGear(vg);
   737         DeleteVisualGear(vg);
   780 var       i: LongInt;
   759 var       i: LongInt;
   781     vg, tmp: PVisualGear;
   760     vg, tmp: PVisualGear;
   782 begin
   761 begin
   783 if (cReducedQuality and rqKillFlakes) <> 0 then exit;
   762 if (cReducedQuality and rqKillFlakes) <> 0 then exit;
   784 if vobCount = vobSDCount then exit;
   763 if vobCount = vobSDCount then exit;
   785 vg:= VisualGearsLayer0;
   764 for i:= 0 to 3 do
   786 while vg <> nil do
   765     begin
   787     if vg^.Kind = vgtFlake then
   766     vg:= VisualGearLayers[i];
       
   767     while vg <> nil do
       
   768         if vg^.Kind = vgtFlake then
   788         begin
   769         begin
   789         tmp:= vg^.NextGear;
   770         tmp:= vg^.NextGear;
   790         DeleteVisualGear(vg);
   771         DeleteVisualGear(vg);
   791         vg:= tmp
   772         vg:= tmp
   792         end
   773         end
   793     else vg:= vg^.NextGear;
   774         else vg:= vg^.NextGear;
       
   775     end;
   794 if ((GameFlags and gfBorder) <> 0) or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then
   776 if ((GameFlags and gfBorder) <> 0) or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then
   795     for i:= 0 to Pred(vobSDCount * cScreenSpace div LAND_WIDTH) do
   777     for i:= 0 to Pred(vobSDCount * cScreenSpace div LAND_WIDTH) do
   796         AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake)
   778         AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake)
   797 else
   779 else
   798     for i:= 0 to Pred((vobSDCount * cScreenSpace div LAND_WIDTH) div 3) do
   780     for i:= 0 to Pred((vobSDCount * cScreenSpace div LAND_WIDTH) div 3) do
   799         AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake);
   781         AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake);
   800 end;
   782 end;
   801 
   783 
   802 procedure initModule;
   784 procedure initModule;
   803 begin
   785 var i: LongWord;
   804     VisualGearsLayer0:= nil;
   786 begin
   805     VisualGearsLayer1:= nil;
   787 for i:= 0 to 3 do
   806     VisualGearsLayer2:= nil;
   788     VisualGearLayers[i]:= nil;
   807     VisualGearsLayer3:= nil;
       
   808 end;
   789 end;
   809 
   790 
   810 procedure freeModule;
   791 procedure freeModule;
   811 begin
   792 var i: LongWord;
   812     while VisualGearsLayer0 <> nil do DeleteVisualGear(VisualGearsLayer0);
   793 begin
   813     while VisualGearsLayer1 <> nil do DeleteVisualGear(VisualGearsLayer1);
   794 for i:= 0 to 3 do
   814     while VisualGearsLayer2 <> nil do DeleteVisualGear(VisualGearsLayer2);
   795     while VisualGearLayers[i] <> nil do DeleteVisualGear(VisualGearLayers[i]);
   815     while VisualGearsLayer3 <> nil do DeleteVisualGear(VisualGearsLayer3);
       
   816 end;
   796 end;
   817 
   797 
   818 end.
   798 end.