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