~ubuntu-branches/ubuntu/wily/hedgewars/wily

« back to all changes in this revision

Viewing changes to hedgewars/uVisualGears.pas

  • Committer: Package Import Robot
  • Author(s): Dmitry E. Oboukhov
  • Date: 2011-09-23 10:16:55 UTC
  • mfrom: (1.2.11 upstream)
  • Revision ID: package-import@ubuntu.com-20110923101655-3977th2gc5n0a3pv
Tags: 0.9.16-1
* New upstream version.
 + Downloadable content! Simply click to install any content.
   New voices, hats, maps, themes, translations, music, scripts...
   Hedgewars is now more customisable than ever before! As time goes
   by we will be soliciting community content to feature on this page,
   so remember to check it from time to time. If you decide you want
   to go back to standard Hedgewars, just remove the Data directory
   from your Hedgewars config directory.
 + 3-D rendering! Diorama-like rendering of the game in a variety
   of 3D modes. Let us know which ones work best for you, we didn't
   really have the equipment to test them all.
 + Resizable game window.
 + New utilities! The Time Box will remove one of your hedgehogs
   from the game for a while, protecting from attack until it returns,
   somewhere else on the map. Land spray will allow you to build bridges,
   seal up holes, or just make life unpleasant for your enemies.
 + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
   the Tree and multi-player: The Specialists, Space Invaders,
   Racer - scripts! And a ton more script hooks for scripters
 + New twists on old weapons. Drill strike, seduction and fire have
   been adjusted. Defective mines have been added, rope can attach to
   hogs/crates/barrels again, grenades now have variable bounce (use
   precise key + 1-5). Portal gun is now more usable in flight and
   all game actions are a lot faster.
 + New theme - Golf, dozens of new community hats and a new
   localised Default voice, Ukranian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
(*
2
2
 * Hedgewars, a free turn based strategy game
3
 
 * Copyright (c) 2008 Andrey Korotaev <unC0Rr@gmail.com>
 
3
 * Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com>
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License as published by
19
19
{$INCLUDE "options.inc"}
20
20
 
21
21
unit uVisualGears;
 
22
(*
 
23
 * This unit defines the behavior and the appearance of visual gears.
 
24
 *
 
25
 * Visual gears are "things"/"objects" in the game that do not need to be
 
26
 * perfectly synchronized over all clients since their effect is only
 
27
 * of visual nature.
 
28
 *
 
29
 * E.g.: background flakes, visual effects: explosion, smoke trails, etc.
 
30
 *)
22
31
interface
23
 
uses uConsts, uFloat, GLunit, uTypes;
 
32
uses uConsts, uFloat, GLunit, uTypes, uWorld;
24
33
 
25
34
procedure initModule;
26
35
procedure freeModule;
32
41
procedure DeleteVisualGear(Gear: PVisualGear);
33
42
function  VisualGearByUID(uid : Longword) : PVisualGear;
34
43
procedure AddClouds;
 
44
procedure ChangeToSDClouds;
 
45
procedure AddFlakes;
 
46
procedure ChangeToSDFlakes;
35
47
procedure AddDamageTag(X, Y, Damage, Color: LongWord);
36
48
 
37
49
implementation
38
 
uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils;
 
50
uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils, uStore;
39
51
 
40
52
const cExplFrameTicks = 110;
41
53
 
 
54
// For better maintainability the step handlers of visual gears are stored
 
55
// in a separate file.
42
56
{$INCLUDE "VGSHandlers.inc"}
43
57
 
44
58
procedure AddDamageTag(X, Y, Damage, Color: LongWord);
76
90
            @doStepAmmo,
77
91
            @doStepSmoke,
78
92
            @doStepSmoke,
79
 
            @doStepHealth,
80
93
            @doStepShell,
81
94
            @doStepDust,
82
95
            @doStepSplash,
94
107
            @doStepNote,
95
108
            @doStepLineTrail,
96
109
            @doStepBulletHit,
97
 
            @doStepCircle
 
110
            @doStepCircle,
 
111
            @doStepSmoothWindBar,
 
112
            @doStepStraightShot
98
113
        );
99
114
 
100
115
function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear;
103
118
    t: Longword;
104
119
    sp: real;
105
120
begin
106
 
if (GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet)) then // we are scrolling now
107
 
    if (Kind <> vgtCloud) and not Critical then
108
 
        begin
109
 
        AddVisualGear:= nil;
110
 
        exit
111
 
        end;
 
121
AddVisualGear:= nil;
 
122
if ((GameType = gmtSave) or (fastUntilLag and (GameType = gmtNet))) and // we are scrolling now
 
123
   ((Kind <> vgtCloud) and not Critical) then exit;
112
124
 
113
 
if ((cReducedQuality and rqFancyBoom) <> 0) and
 
125
if ((cReducedQuality and rqAntiBoom) <> 0) and
114
126
   not Critical and
115
127
   not (Kind in
116
128
   [vgtTeamHealthSorter,
120
132
    vgtExplosion,
121
133
    vgtSmokeTrace,
122
134
    vgtEvilTrace,
123
 
    vgtNote]) then
124
 
    begin
125
 
      AddVisualGear:= nil;
126
 
      exit
127
 
    end;
 
135
    vgtNote,
 
136
    vgtSmoothWindBar]) then exit;
128
137
 
129
138
inc(VGCounter);
130
139
New(gear);
143
152
                Timer:= 0;
144
153
                tdX:= 0;
145
154
                tdY:= 0;
146
 
                FrameTicks:= random(vobFrameTicks);
147
 
                Frame:= random(vobFramesCount);
 
155
                if SuddenDeathDmg then
 
156
                    begin
 
157
                    FrameTicks:= random(vobSDFrameTicks);
 
158
                    Frame:= random(vobSDFramesCount);
 
159
                    end
 
160
                else
 
161
                    begin
 
162
                    FrameTicks:= random(vobFrameTicks);
 
163
                    Frame:= random(vobFramesCount);
 
164
                    end;
148
165
                Angle:= random * 360;
149
166
                dx:= 0.0000038654705 * random(10000);
150
167
                dy:= 0.000003506096 * random(7000);
151
168
                if random(2) = 0 then dx := -dx;
152
 
                dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
 
169
                if SuddenDeathDmg then dAngle:= (random(2) * 2 - 1) * (1 + random) * vobSDVelocity / 1000
 
170
                else dAngle:= (random(2) * 2 - 1) * (1 + random) * vobVelocity / 1000
153
171
                end;
154
172
    vgtCloud: begin
155
173
                Frame:= random(4);
160
178
    vgtExplPart2: begin
161
179
                t:= random(1024);
162
180
                sp:= 0.001 * (random(95) + 70);
163
 
                dx:= AngleSin(t).QWordValue/4294967296 * sp;
164
 
                dy:= AngleCos(t).QWordValue/4294967296 * sp;
 
181
                dx:= hwFloat2Float(AngleSin(t)) * sp;
 
182
                dy:= hwFloat2Float(AngleCos(t)) * sp;
165
183
                if random(2) = 0 then dx := -dx;
166
184
                if random(2) = 0 then dy := -dy;
167
185
                Frame:= 7 - random(3);
170
188
        vgtFire: begin
171
189
                t:= random(1024);
172
190
                sp:= 0.001 * (random(85) + 95);
173
 
                dx:= AngleSin(t).QWordValue/4294967296 * sp;
174
 
                dy:= AngleCos(t).QWordValue/4294967296 * sp;
 
191
                dx:= hwFloat2Float(AngleSin(t)) * sp;
 
192
                dy:= hwFloat2Float(AngleCos(t)) * sp;
175
193
                if random(2) = 0 then dx := -dx;
176
194
                if random(2) = 0 then dy := -dy;
177
195
                FrameTicks:= 650 + random(250);
180
198
         vgtEgg: begin
181
199
                t:= random(1024);
182
200
                sp:= 0.001 * (random(85) + 95);
183
 
                dx:= AngleSin(t).QWordValue/4294967296 * sp;
184
 
                dy:= AngleCos(t).QWordValue/4294967296 * sp;
 
201
                dx:= hwFloat2Float(AngleSin(t)) * sp;
 
202
                dy:= hwFloat2Float(AngleCos(t)) * sp;
185
203
                if random(2) = 0 then dx := -dx;
186
204
                if random(2) = 0 then dy := -dy;
187
205
                FrameTicks:= 650 + random(250);
211
229
                end;
212
230
  vgtSmokeWhite,
213
231
  vgtSmoke: begin
 
232
                Scale:= 1.0;
214
233
                dx:= 0.0002 * (random(45) + 10);
215
234
                dy:= 0.0002 * (random(45) + 10);
216
235
                if random(2) = 0 then dx := -dx;
217
236
                Frame:= 7 - random(2);
218
237
                FrameTicks:= cExplFrameTicks * 2;
219
238
                end;
220
 
    vgtHealth: begin
221
 
                dx:= 0.001 * random(45);
222
 
                dy:= 0.001 * (random(20) + 25);
223
 
                if random(2) = 0 then dx := -dx;
224
 
                Frame:= 0;
225
 
                FrameTicks:= random(750) + 1250;
226
 
                end;
227
239
  vgtDust: begin
228
240
                dx:= 0.005 * (random(15) + 10);
229
241
                dy:= 0.001 * (random(40) + 20);
261
273
     vgtFeather: begin
262
274
                t:= random(1024);
263
275
                sp:= 0.001 * (random(85) + 95);
264
 
                dx:= AngleSin(t).QWordValue/4294967296 * sp;
265
 
                dy:= AngleCos(t).QWordValue/4294967296 * sp;
 
276
                dx:= hwFloat2Float(AngleSin(t)) * sp;
 
277
                dy:= hwFloat2Float(AngleCos(t)) * sp;
266
278
                if random(2) = 0 then dx := -dx;
267
279
                if random(2) = 0 then dy := -dy;
268
280
                FrameTicks:= 650 + random(250);
269
281
                Frame:= 1
270
282
                end;
271
283
  vgtHealthTag: begin
272
 
                gear^.Timer:= 1500;
 
284
                Frame:= 0;
 
285
                Timer:= 1500;
 
286
                dY:= -0.08;
 
287
                dX:= 0;
273
288
                //gear^.Z:= 2002;
274
289
                end;
275
290
  vgtSmokeTrace,
286
301
                gear^.Frame:= random(4);
287
302
                t:= random(1024);
288
303
                sp:= 0.001 * (random(85) + 47);
289
 
                dx:= AngleSin(t).QWordValue/4294967296 * sp;
290
 
                dy:= AngleCos(t).QWordValue/4294967296 * sp * -2;
 
304
                dx:= hwFloat2Float(AngleSin(t)) * sp;
 
305
                dy:= hwFloat2Float(AngleCos(t)) * sp * -2;
291
306
                if random(2) = 0 then dx := -dx;
292
307
                end;
293
308
      vgtNote: begin
302
317
                dy:= 0;
303
318
                FrameTicks:= 350;
304
319
                Frame:= 7;
305
 
                Angle := 0;
 
320
                Angle:= 0;
 
321
                end;
 
322
vgtSmoothWindBar: Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
 
323
 vgtStraightShot: begin
 
324
                Angle:= 0;
 
325
                Scale:= 1.0;
 
326
                dx:= 0.001 * random(45);
 
327
                dy:= 0.001 * (random(20) + 25);
 
328
                State:= ord(sprHealth);
 
329
                if random(2) = 0 then dx := -dx;
 
330
                Frame:= 0;
 
331
                FrameTicks:= random(750) + 1250;
 
332
                State:= ord(sprSnowDust);
306
333
                end;
307
334
        end;
308
335
 
309
336
if State <> 0 then gear^.State:= State;
310
337
 
311
 
if VisualGearsList <> nil then
312
 
    begin
313
 
    VisualGearsList^.PrevGear:= gear;
314
 
    gear^.NextGear:= VisualGearsList
315
 
    end;
316
 
VisualGearsList:= gear;
 
338
case Gear^.Kind of
 
339
    // 0: this layer is very distant in the background when stereo
 
340
    vgtTeamHealthSorter,
 
341
    vgtSmoothWindBar,
 
342
    vgtFlake, 
 
343
    vgtCloud: begin
 
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
 
353
    vgtSmokeTrace,
 
354
    vgtEvilTrace,
 
355
    vgtLineTrail,
 
356
    vgtSmoke,
 
357
    vgtSmokeWhite,
 
358
    vgtDust,
 
359
    vgtFire,
 
360
    vgtSplash,
 
361
    vgtDroplet,
 
362
    vgtBubble: begin
 
363
              if VisualGearsLayer1 <> nil then
 
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
 
372
    vgtSpeechBubble,
 
373
    vgtSmallDamageTag,
 
374
    vgtHealthTag,
 
375
    vgtStraightShot,
 
376
    vgtChunk: begin
 
377
              if VisualGearsLayer3 <> nil then
 
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
 
386
    vgtExplosion,
 
387
    vgtBigExplosion,
 
388
    vgtExplPart,
 
389
    vgtExplPart2,
 
390
    vgtSteam,
 
391
    vgtAmmo,
 
392
    vgtShell,
 
393
    vgtFeather,
 
394
    vgtEgg,
 
395
    vgtBeeTrace,
 
396
    vgtSmokeRing,
 
397
    vgtNote,
 
398
    vgtBulletHit,
 
399
    vgtCircle: begin
 
400
              if VisualGearsLayer2 <> nil then
 
401
                  begin
 
402
                  VisualGearsLayer2^.PrevGear:= gear;
 
403
                  gear^.NextGear:= VisualGearsLayer2
 
404
                  end;
 
405
              gear^.Layer:= 2;
 
406
              VisualGearsLayer2:= gear
 
407
              end; 
 
408
end;
317
409
 
318
410
AddVisualGear:= gear;
319
411
end;
326
418
 
327
419
    if Gear^.NextGear <> nil then Gear^.NextGear^.PrevGear:= Gear^.PrevGear;
328
420
    if Gear^.PrevGear <> nil then Gear^.PrevGear^.NextGear:= Gear^.NextGear
329
 
    else VisualGearsList:= Gear^.NextGear;
 
421
    else
 
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
 
 
429
    if lastVisualGearByUID = Gear then lastVisualGearByUID:= nil;
330
430
 
331
431
    Dispose(Gear);
332
432
end;
336
436
begin
337
437
if Steps = 0 then exit;
338
438
 
339
 
t:= VisualGearsList;
 
439
t:= VisualGearsLayer0;
 
440
while t <> nil do
 
441
      begin
 
442
      Gear:= t;
 
443
      t:= Gear^.NextGear;
 
444
      Gear^.doStep(Gear, Steps)
 
445
      end;
 
446
t:= VisualGearsLayer1;
 
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;
340
461
while t <> nil do
341
462
      begin
342
463
      Gear:= t;
350
471
    dmg: LongInt;
351
472
begin
352
473
if (vobCount = 0) or (vobCount > 200) then exit;
353
 
t:= VisualGearsList;
 
474
t:= VisualGearsLayer0;
354
475
while t <> nil do
355
476
      begin
356
477
      Gear:= t;
375
496
var Gear: PVisualGear;
376
497
    tinted: boolean;
377
498
    tmp: real;
 
499
    i: LongInt;
378
500
begin
379
 
Gear:= VisualGearsList;
380
501
case Layer of
381
 
    0: while Gear <> nil do
382
 
        begin
383
 
        if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
384
 
        case Gear^.Kind of
385
 
            vgtFlake: if vobVelocity = 0 then
386
 
                          DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
387
 
                      else
388
 
                          DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);
389
 
            vgtCloud: DrawSprite(sprCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame);
390
 
            end;
391
 
        if Gear^.Tint <> $FFFFFFFF then Tint($FF,$FF,$FF,$FF);
392
 
        Gear:= Gear^.NextGear
393
 
        end;
394
 
    1: while Gear <> nil do
395
 
        begin
396
 
        tinted:= false;
397
 
        if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
398
 
        case Gear^.Kind of
399
 
            vgtSmokeTrace: if Gear^.State < 8 then DrawSprite(sprSmokeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
400
 
            vgtEvilTrace: if Gear^.State < 8 then DrawSprite(sprEvilTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State);
401
 
            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));
402
 
            vgtSpeechBubble: if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then 
403
 
                    begin
404
 
                    tinted:= true;
405
 
                    Tint($FF, $FF, $FF,  $66);
406
 
                    DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex)
407
 
                    end
408
 
        end;
409
 
            if (cReducedQuality and rqFancyBoom) = 0 then
410
 
                case Gear^.Kind of
411
 
                    vgtSmoke: DrawSprite(sprSmoke, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
412
 
                    vgtSmokeWhite: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
413
 
                    vgtDust: DrawSprite(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
414
 
                    vgtFeather: begin
415
 
                            if Gear^.FrameTicks < 255 then
416
 
                                begin
417
 
                                Tint($FF, $FF, $FF, Gear^.FrameTicks);
418
 
                                tinted:= true
419
 
                                end;
420
 
                            DrawRotatedF(sprFeather, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
421
 
                            end;
422
 
                 end;
423
 
        if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF);
424
 
        Gear:= Gear^.NextGear
425
 
        end;
426
 
    2: while Gear <> nil do
427
 
        begin
428
 
        tinted:= false;
429
 
        if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
430
 
        case Gear^.Kind of
431
 
            vgtExplosion: DrawSprite(sprExplosion50, round(Gear^.X) - 32 + WorldDx, round(Gear^.Y) - 32 + WorldDy, Gear^.State);
432
 
            vgtBigExplosion: begin
433
 
                             tinted:= true;
434
 
                             Tint($FF, $FF, $FF, round($FF * (1 - power(Gear^.Timer / 250, 4))));
435
 
                             DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle);
436
 
                             end;
437
 
            end;
438
 
        if (cReducedQuality and rqFancyBoom) = 0 then
439
 
            case Gear^.Kind of
440
 
                vgtExplPart: DrawSprite(sprExplPart, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
441
 
                vgtExplPart2: DrawSprite(sprExplPart2, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
442
 
                vgtFire: if (Gear^.State and gstTmpFlag) = 0 then
443
 
                             DrawSprite(sprFlame, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy, (RealTicks shr 6 + Gear^.Frame) mod 8)
444
 
                         else
445
 
                             DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16);
446
 
                vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
447
 
                vgtSteam: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
448
 
                vgtAmmo: begin
449
 
                        tinted:= true;
450
 
                        Tint($FF, $FF, $FF, round(Gear^.alpha * $FF));
451
 
                        DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32);
452
 
                        DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32);
453
 
                        end;
454
 
                vgtHealth:  begin
455
 
                            tinted:= true;
456
 
                            case Gear^.Frame div 10 of
457
 
                                0:Tint(0, $FF, 0, round(Gear^.FrameTicks * $FF / 1000));
458
 
                                1:Tint($FF, 0, 0, round(Gear^.FrameTicks * $FF / 1000));
459
 
                            end;
460
 
                            DrawSprite(sprHealth, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, 0);
461
 
                            end;
462
 
                vgtShell: begin
463
 
                            if Gear^.FrameTicks < $FF then
464
 
                                begin
465
 
                                Tint($FF, $FF, $FF, Gear^.FrameTicks);
466
 
                                tinted:= true
467
 
                                end;
468
 
                            DrawRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
469
 
                            end;
470
 
                  vgtEgg: begin
471
 
                            if Gear^.FrameTicks < $FF then
472
 
                                begin
473
 
                                Tint($FF, $FF, $FF, Gear^.FrameTicks);
474
 
                                tinted:= true
475
 
                                end;
476
 
                            DrawRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
477
 
                            end;
478
 
                vgtSplash: DrawSprite(sprSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37));
479
 
                vgtDroplet: DrawSprite(sprDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);
480
 
               vgtBeeTrace: begin
481
 
                            if Gear^.FrameTicks < $FF then
482
 
                                Tint($FF, $FF, $FF, Gear^.FrameTicks div 2)
483
 
                            else
484
 
                                Tint($FF, $FF, $FF, $80);
485
 
                            tinted:= true;
486
 
                            DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle);
487
 
                            end;
488
 
                vgtSmokeRing: begin
 
502
    // this layer is very distant in the background when stereo
 
503
    0: begin
 
504
       Gear:= VisualGearsLayer0;
 
505
       while Gear <> nil do
 
506
           begin
 
507
           if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
 
508
           case Gear^.Kind of
 
509
               vgtFlake: if SuddenDeathDmg then
 
510
                             if vobSDVelocity = 0 then
 
511
                                 DrawSprite(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
 
512
                             else
 
513
                                 DrawRotatedF(sprSDFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle)
 
514
                         else
 
515
                             if vobVelocity = 0 then
 
516
                                 DrawSprite(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
 
517
                             else
 
518
                                 DrawRotatedF(sprFlake, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame, 1, Gear^.Angle);
 
519
               vgtCloud: if SuddenDeathDmg then
 
520
                             DrawSprite(sprSDCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame)
 
521
                         else
 
522
                             DrawSprite(sprCloud, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy + SkyOffset, Gear^.Frame);
 
523
               end;
 
524
           if Gear^.Tint <> $FFFFFFFF then Tint($FF,$FF,$FF,$FF);
 
525
           Gear:= Gear^.NextGear
 
526
           end
 
527
       end;
 
528
    // this layer is on the land level (which is close but behind the screen plane) when stereo
 
529
    1: begin
 
530
       Gear:= VisualGearsLayer1;
 
531
       while Gear <> nil do
 
532
          begin
 
533
          //tinted:= false;
 
534
          if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
 
535
          case Gear^.Kind of
 
536
              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);
 
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));
 
539
          end;
 
540
          if (cReducedQuality and rqAntiBoom) = 0 then
 
541
              case Gear^.Kind of
 
542
                  vgtSmoke: DrawTextureF(SpritesData[sprSmoke].Texture, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 7 - Gear^.Frame, 0, SpritesData[sprSmoke].Width, SpritesData[sprSmoke].Height);
 
543
                  vgtSmokeWhite: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
 
544
                  vgtDust: if Gear^.State = 1 then
 
545
                               DrawSprite(sprSnowDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame)
 
546
                           else
 
547
                               DrawSprite(sprDust, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
 
548
                  vgtFire: if (Gear^.State and gstTmpFlag) = 0 then
 
549
                               DrawSprite(sprFlame, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy, (RealTicks shr 6 + Gear^.Frame) mod 8)
 
550
                           else
 
551
                               DrawTextureF(SpritesData[sprFlame].Texture, Gear^.FrameTicks / 900, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, (RealTicks shr 7 + Gear^.Frame) mod 8, 1, 16, 16);
 
552
                  vgtSplash: if SuddenDeathDmg then
 
553
                                 DrawSprite(sprSDSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37))
 
554
                             else
 
555
                                 DrawSprite(sprSplash, round(Gear^.X) + WorldDx - 40, round(Gear^.Y) + WorldDy - 58, 19 - (Gear^.FrameTicks div 37));
 
556
                  vgtDroplet: if SuddenDeathDmg then
 
557
                                  DrawSprite(sprSDDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame)
 
558
                              else
 
559
                                  DrawSprite(sprDroplet, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);
 
560
                  vgtBubble: DrawSprite(sprBubbles, round(Gear^.X) + WorldDx - 8, round(Gear^.Y) + WorldDy - 8, Gear^.Frame);//(RealTicks div 64 + Gear^.Frame) mod 8);
 
561
              end;
 
562
          //if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF);
 
563
          if (Gear^.Tint <> $FFFFFFFF) then Tint($FF,$FF,$FF,$FF);
 
564
          Gear:= Gear^.NextGear
 
565
          end
 
566
       end;
 
567
    // this layer is on the screen plane (depth = 0) when stereo
 
568
    3: begin
 
569
       Gear:= VisualGearsLayer3;
 
570
       while Gear <> nil do
 
571
           begin
 
572
           tinted:= false;
 
573
           if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
 
574
           case Gear^.Kind of
 
575
               vgtSpeechBubble: begin
 
576
                                if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team <> CurrentTeam)) or (Gear^.State = 1)) then
 
577
                                    begin
 
578
                                    tinted:= true;
 
579
                                    Tint($FF, $FF, $FF,  $66);
 
580
                                    DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex)
 
581
                                    end
 
582
                                else if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team = CurrentTeam)) or (Gear^.State = 2)) then
 
583
                                    DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
 
584
                                end;
 
585
               vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
 
586
               vgtHealthTag: if Gear^.Tex <> nil then 
 
587
                               begin
 
588
                               if Gear^.Frame = 0 then 
 
589
                                   DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex)
 
590
                               else
 
591
                                   begin
 
592
                                   SetScale(cDefaultZoomLevel);
 
593
                                   if Gear^.Angle = 0 then DrawTexture(round(Gear^.X), round(Gear^.Y), Gear^.Tex)
 
594
                                   else DrawTexture(round(Gear^.X), round(Gear^.Y), Gear^.Tex, Gear^.Angle); 
 
595
                                   SetScale(zoom)
 
596
                                   end
 
597
                               end;
 
598
               vgtStraightShot: begin 
 
599
                                if Gear^.dX < 0 then i:= -1 else i:= 1;
 
600
                                DrawRotatedTextureF(SpritesData[TSprite(Gear^.State)].Texture, Gear^.Scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, i, SpritesData[TSprite(Gear^.State)].Width, SpritesData[TSprite(Gear^.State)].Height, Gear^.Angle);
 
601
                                end;
 
602
           end;
 
603
           if (cReducedQuality and rqAntiBoom) = 0 then
 
604
               case Gear^.Kind of
 
605
                   vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
 
606
               end;
 
607
           if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF);
 
608
           Gear:= Gear^.NextGear
 
609
           end
 
610
       end;
 
611
    // this layer is outside the screen when stereo
 
612
    2: begin
 
613
       Gear:= VisualGearsLayer2;
 
614
       while Gear <> nil do
 
615
           begin
 
616
           tinted:= false;
 
617
           if Gear^.Tint <> $FFFFFFFF then Tint(Gear^.Tint);
 
618
           case Gear^.Kind of
 
619
               vgtExplosion: DrawSprite(sprExplosion50, round(Gear^.X) - 32 + WorldDx, round(Gear^.Y) - 32 + WorldDy, Gear^.State);
 
620
               vgtBigExplosion: begin
 
621
                                tinted:= true;
 
622
                                Tint($FF, $FF, $FF, round($FF * (1 - power(Gear^.Timer / 250, 4))));
 
623
                                DrawRotatedTextureF(SpritesData[sprBigExplosion].Texture, 0.85 * (-power(2, -10 * Int(Gear^.Timer)/250) + 1) + 0.4, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 385, 385, Gear^.Angle);
 
624
                                end;
 
625
           end;
 
626
           if (cReducedQuality and rqAntiBoom) = 0 then
 
627
               case Gear^.Kind of
 
628
                   vgtExplPart: DrawSprite(sprExplPart, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
 
629
                   vgtExplPart2: DrawSprite(sprExplPart2, round(Gear^.X) + WorldDx - 16, round(Gear^.Y) + WorldDy - 16, 7 - Gear^.Frame);
 
630
                   vgtSteam: DrawSprite(sprSmokeWhite, round(Gear^.X) + WorldDx - 11, round(Gear^.Y) + WorldDy - 11, 7 - Gear^.Frame);
 
631
                   vgtAmmo: begin
489
632
                            tinted:= true;
490
633
                            Tint($FF, $FF, $FF, round(Gear^.alpha * $FF));
491
 
                            DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle);
 
634
                            DrawTextureF(ropeIconTex, Gear^.scale, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 32, 32);
 
635
                            DrawTextureF(SpritesData[sprAMAmmos].Texture, Gear^.scale * 0.90, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame - 1, 1, 32, 32);
492
636
                            end;
493
 
                vgtChunk: DrawRotatedF(sprChunk, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
494
 
                 vgtNote: DrawRotatedF(sprNote, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
495
 
                vgtBulletHit: DrawRotatedF(sprBulletHit, round(Gear^.X) + WorldDx - 0, round(Gear^.Y) + WorldDy - 0, 7 - (Gear^.FrameTicks div 50), 1, Gear^.Angle);
496
 
            end;
497
 
        case Gear^.Kind of
498
 
            vgtSmallDamageTag: DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
499
 
            vgtSpeechBubble: if (Gear^.Tex <> nil) and (((Gear^.State = 0) and (Gear^.Hedgehog^.Team = CurrentTeam)) or (Gear^.State = 2)) then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
500
 
            vgtHealthTag: if Gear^.Tex <> nil then DrawCentered(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Tex);
501
 
            vgtCircle:  if gear^.Angle = 1 then 
502
 
                            begin
503
 
                            tmp:= Gear^.State / 100;
504
 
                            DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp)
505
 
                            end
506
 
                        else DrawCircle(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State, Gear^.Timer);
507
 
        end;
508
 
        if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF);
509
 
        Gear:= Gear^.NextGear
510
 
        end
 
637
                   vgtShell: begin
 
638
                             if Gear^.FrameTicks < $FF then
 
639
                                 begin
 
640
                                 Tint($FF, $FF, $FF, Gear^.FrameTicks);
 
641
                                 tinted:= true
 
642
                                 end;
 
643
                             DrawRotatedF(sprShell, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
 
644
                             end;
 
645
                   vgtFeather: begin
 
646
                               if Gear^.FrameTicks < 255 then
 
647
                                   begin
 
648
                                   Tint($FF, $FF, $FF, Gear^.FrameTicks);
 
649
                                   tinted:= true
 
650
                                   end;
 
651
                               DrawRotatedF(sprFeather, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
 
652
                             end;
 
653
                   vgtEgg: DrawRotatedF(sprEgg, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, Gear^.Angle);
 
654
                   vgtBeeTrace: begin
 
655
                                if Gear^.FrameTicks < $FF then
 
656
                                    Tint($FF, $FF, $FF, Gear^.FrameTicks div 2)
 
657
                                else
 
658
                                    Tint($FF, $FF, $FF, $80);
 
659
                                tinted:= true;
 
660
                                DrawRotatedF(sprBeeTrace, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.Frame, 1, (RealTicks shr 4) mod cMaxAngle);
 
661
                                end;
 
662
                   vgtSmokeRing: begin
 
663
                                 tinted:= true;
 
664
                                 Tint($FF, $FF, $FF, round(Gear^.alpha * $FF));
 
665
                                 DrawRotatedTextureF(SpritesData[sprSmokeRing].Texture, Gear^.scale, 0, 0, round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, 0, 1, 200, 200, Gear^.Angle);
 
666
                                 end;
 
667
                   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);
 
669
               end;
 
670
           case Gear^.Kind of
 
671
               vgtCircle: if gear^.Angle = 1 then
 
672
                              begin
 
673
                              tmp:= Gear^.State / 100;
 
674
                              DrawTexture(round(Gear^.X-24*tmp) + WorldDx, round(Gear^.Y-24*tmp) + WorldDy, SpritesData[sprVampiric].Texture, tmp)
 
675
                              end
 
676
                          else DrawCircle(round(Gear^.X) + WorldDx, round(Gear^.Y) + WorldDy, Gear^.State, Gear^.Timer);
 
677
           end;
 
678
           if (Gear^.Tint <> $FFFFFFFF) or tinted then Tint($FF,$FF,$FF,$FF);
 
679
           Gear:= Gear^.NextGear
 
680
           end
 
681
       end
511
682
    end;
512
683
end;
513
684
 
515
686
var vg: PVisualGear;
516
687
begin
517
688
VisualGearByUID:= nil;
518
 
vg:= VisualGearsList;
519
 
while vg <> nil do
520
 
    begin
521
 
    if vg^.uid = uid then
522
 
        begin
523
 
            VisualGearByUID:= vg;
524
 
            exit
 
689
if uid = 0 then exit;
 
690
if (lastVisualGearByUID <> nil) and (lastVisualGearByUID^.uid = uid) then
 
691
    begin
 
692
    VisualGearByUID:= lastVisualGearByUID;
 
693
    exit
 
694
    end;
 
695
vg:= VisualGearsLayer0;
 
696
while vg <> nil do
 
697
    begin
 
698
    if vg^.uid = uid then
 
699
        begin
 
700
        lastVisualGearByUID:= vg;
 
701
        VisualGearByUID:= vg;
 
702
        exit
 
703
        end;
 
704
    vg:= vg^.NextGear
 
705
    end;
 
706
vg:= VisualGearsLayer1;
 
707
while vg <> nil do
 
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
525
736
        end;
526
737
    vg:= vg^.NextGear
527
738
    end
531
742
var i: LongInt;
532
743
begin
533
744
for i:= 0 to cCloudsNumber - 1 do
534
 
    AddVisualGear(cLeftScreenBorder + i * cScreenSpace div (cCloudsNumber + 1), LAND_HEIGHT-1184, vgtCloud)
 
745
    AddVisualGear(cLeftScreenBorder + i * LongInt(cScreenSpace div (cCloudsNumber + 1)), LAND_HEIGHT-1184, vgtCloud)
 
746
end;
 
747
 
 
748
procedure ChangeToSDClouds;
 
749
var       i: LongInt;
 
750
    vg, tmp: PVisualGear;
 
751
begin
 
752
if cCloudsNumber = cSDCloudsNumber then exit;
 
753
vg:= VisualGearsLayer0;
 
754
while vg <> nil do
 
755
    if vg^.Kind = vgtCloud then
 
756
        begin
 
757
        tmp:= vg^.NextGear;
 
758
        DeleteVisualGear(vg);
 
759
        vg:= tmp
 
760
        end
 
761
    else vg:= vg^.NextGear;
 
762
for i:= 0 to cSDCloudsNumber - 1 do
 
763
    AddVisualGear(cLeftScreenBorder + i * LongInt(cScreenSpace div (cSDCloudsNumber + 1)), LAND_HEIGHT-1184, vgtCloud)
 
764
end;
 
765
 
 
766
procedure AddFlakes;
 
767
var i: LongInt;
 
768
begin
 
769
if (cReducedQuality and rqKillFlakes) <> 0 then exit;
 
770
 
 
771
if ((GameFlags and gfBorder) <> 0) or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then
 
772
    for i:= 0 to Pred(vobCount * cScreenSpace div LAND_WIDTH) do
 
773
        AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake)
 
774
else
 
775
    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);
 
777
end;
 
778
 
 
779
procedure ChangeToSDFlakes;
 
780
var       i: LongInt;
 
781
    vg, tmp: PVisualGear;
 
782
begin
 
783
if (cReducedQuality and rqKillFlakes) <> 0 then exit;
 
784
if vobCount = vobSDCount then exit;
 
785
vg:= VisualGearsLayer0;
 
786
while vg <> nil do
 
787
    if vg^.Kind = vgtFlake then
 
788
        begin
 
789
        tmp:= vg^.NextGear;
 
790
        DeleteVisualGear(vg);
 
791
        vg:= tmp
 
792
        end
 
793
    else vg:= vg^.NextGear;
 
794
if ((GameFlags and gfBorder) <> 0) or ((Theme <> 'Snow') and (Theme <> 'Christmas')) then
 
795
    for i:= 0 to Pred(vobSDCount * cScreenSpace div LAND_WIDTH) do
 
796
        AddVisualGear(cLeftScreenBorder + random(cScreenSpace), random(1024+200) - 100 + LAND_HEIGHT, vgtFlake)
 
797
else
 
798
    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);
535
800
end;
536
801
 
537
802
procedure initModule;
538
803
begin
539
 
    VisualGearsList:= nil;
 
804
    VisualGearsLayer0:= nil;
 
805
    VisualGearsLayer1:= nil;
 
806
    VisualGearsLayer2:= nil;
 
807
    VisualGearsLayer3:= nil;
540
808
end;
541
809
 
542
810
procedure freeModule;
543
811
begin
544
 
    while VisualGearsList <> nil do DeleteVisualGear(VisualGearsList);
 
812
    while VisualGearsLayer0 <> nil do DeleteVisualGear(VisualGearsLayer0);
 
813
    while VisualGearsLayer1 <> nil do DeleteVisualGear(VisualGearsLayer1);
 
814
    while VisualGearsLayer2 <> nil do DeleteVisualGear(VisualGearsLayer2);
 
815
    while VisualGearsLayer3 <> nil do DeleteVisualGear(VisualGearsLayer3);
545
816
end;
546
817
 
547
818
end.