Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
762 bw 1
unit LRLLevels;
2
 
3
{$mode objfpc}
4
 
5
 
6
interface
7
 
8
 
9
uses
10
  SysUtils,
11
  LRLRoutines, LRLSprites;
12
 
13
 
14
type
15
  TLRLPlayerPosition = packed record
16
    x, y:         Byte;
17
    xoffs, yoffs: ShortInt;
18
  end;
19
 
20
  TLRLPlayer = packed record
21
    Command:       Byte;
22
    { pictures:
23
      1 - running left <-
24
      2 - running right ->
25
      3 - climbing up ^
26
      4 - climbing down v
27
      5 - falling
28
      6 - ~~~~~ left <-
29
      7 - ~~~~~ right ->
30
      8 - firing left <-
31
      9 - firing right ->
32
    }
33
    NewCommandWas: Boolean;
34
    NewCommand:    Byte;
35
    Position:      TLRLPlayerPosition;
36
    Sprite:        Byte;
37
    SpriteData:    Byte;
38
    Controller:    Byte;
39
    {
40
      controllers:
41
 
42
      1 - human/keyboard
43
      2 - computer
44
    }
45
    Prizes:        Byte;
46
    {
47
      max 1 if computer player
48
      a) computer player leaves prize if falling into hole
49
      b) takes prize if he has no prizes
50
    }
51
    Colour:        Byte;
52
  end;
53
 
54
  TLRLBrick = packed record
55
    Image:     Byte;
56
    Count:     Byte;
57
    Flags:     Byte;
58
    { flags:
59
      bit 0 - needed to animate this brick 5 sprites then pause
60
        and then finnally 5 sprites
61
      bit 1 - set if fatal brick
62
      bit 2 - set if allowable to jump
63
      bit 3 - allowable to walk thru
64
      bit 4 - hidden
65
      bit 5 - background
66
      bit 6 - wait now
67
      bit 7 - not draw it
68
    }
69
    IdleCount: Byte;
70
  end;
71
 
72
  TLRLLevel = packed record
73
    Field:  array[1..30, 1..16] of TLRLBrick;
74
    Player: array[1..20] of TLRLPlayer;
75
  end;
76
 
77
 
78
const
79
  BrickFlags: array[1..20] of Byte = (
80
    48, 4 + 8 + 32 + 128,
81
    49, 8 + 32,
82
    50, 4 + 8 + 32,
83
    51, 4 + 8 + 32,
84
    52, 2,
85
    53, 4,
86
    54, 4 + 8,
87
    55, 2,
88
    56, 2,
89
    65, 4 + 8 + 16 + 32);
90
 
91
 
92
const
93
  KeyboardControls: array[1..21] of Word = (
94
    KEY_LEFT,  1, 1,
95
    KEY_RIGHT, 1, 2,
96
    KEY_UP,    1, 3,
97
    KEY_DOWN,  1, 4,
98
    KEY_GREY5, 1, 5,
99
    KEY_END,   1, 6,
100
    KEY_PGDN,  1, 7);
101
  ControlNumber = 7;
102
 
103
 
104
var
105
  ShowLives:        Boolean;
106
  ShowScore:        Boolean;
107
  ShowLevel:        Boolean;
108
  LRLLevel:         TLRLLevel;
109
  LRLLives:         Integer;
110
  LRLScore:         Longint;
111
  LRLCLevel:        Word;
112
  ComputerTurn:     Word;
113
  ComputerReaction: Word;
114
  TimeToRefresh:    Boolean;
115
  OldTimer:         Pointer;
116
  TotalPrizes:      Integer;
117
  GameStarted:      Boolean;
118
  EndOfGame:        Boolean;
119
  GameResult:       Word;
120
  Paused:           Boolean;
121
 
122
 
123
procedure LRLLoadLevel(Number: Byte);
124
procedure LRLUpdatePlayers;
125
procedure LRLDrawOrnamental(x1, y1, x2, y2, ornament: Byte);
126
procedure LRLPlayLevel(Number: Byte);
127
function LRLLevelCount: Word;
128
procedure LRLDeleteLevel(Count: Word);
129
procedure LRLInsertLevel(After: Word);
130
procedure LRLSaveLevel(Count: Word);
131
 
132
 
133
implementation
134
 
135
 
136
const
137
  LevelFileName = 'LRL.LEV';
138
  LevelFileHeader: ShortString = 'Lode Runner Live Levels'#26;
139
 
140
  ERR_OPENFILE = 'Невозможно открыть файл уровней';
141
  ERR_BADFILE  = 'Неверный или поврежденный файл уровней';
142
 
143
 
144
function LRLLevelCount: Word;
145
var
146
  LevelFile: File;
147
  c, k: Word;
148
begin
149
  c := 0;
150
  AssignFile(LevelFile, LevelFileName);
151
  Reset(LevelFile, 1);
152
  Seek(LevelFile, 24);
153
  BlockRead(LevelFile, c, 1, k);
154
  LRLLevelCount := c;
155
  Close(LevelFile);
156
end;
157
 
158
 
159
procedure LRLSaveLevel(Count: Word);
160
var
161
  LevelFile: File;
162
  i, j: Integer;
163
  k: Word;
164
  b: Pointer;
165
begin
166
  GetMem(b, 480);
167
  if (Count = 0) or (Count > LRLLevelCount) then
168
    Exit;
169
  FileMode := 2;
170
  AssignFile(LevelFile, LevelFileName);
171
  Reset(LevelFile, 1);
172
  Seek(LevelFile, Longint(25 + 520 * (Longint(Count) - 1)));
173
  for i := 1 to 10 do
174
  begin
175
    DataBytePut(b^, (i - 1) * 4, LRLLevel.Player[i].Position.x);
176
    DataBytePut(b^, (i - 1) * 4 + 1, LRLLevel.Player[i].Position.y);
177
    DataBytePut(b^, (i - 1) * 4 + 2, LRLLevel.Player[i].Colour);
178
    DataBytePut(b^, (i - 1) * 4 + 3, LRLLevel.Player[i].Controller);
179
  end;
180
  BlockWrite(LevelFile, b^, 40, k);
181
  for i := 1 to 16 do
182
  for j := 1 to 30 do
183
    DataBytePut(b^, (i - 1) * 30 + j - 1, LRLLevel.Field[j, i].Image + 47);
184
  BlockWrite(LevelFile, b^, 480, k);
185
  Close(LevelFile);
186
  FreeMem(b, 480);
187
end;
188
 
189
 
190
procedure LRLDeleteLevel(Count: Word);
191
var
192
  Buffer: Pointer;
193
  LevelFile: File;
194
  j: Integer;
195
  l: Longint;
196
  k: Word;
197
begin
198
  GetMem(Buffer, 1000);
199
  j := LRLLevelCount;
200
  if (j < Count) or (j < 2) or (Count = 0) then
201
    Exit;
202
  FileMode := 2;
203
  AssignFile(LevelFile, LevelFileName);
204
  Reset(LevelFile, 1);
205
  for l := Count + 1 to j do
206
  begin
207
    Seek(LevelFile, Longint(25 + 520 * (Longint(l) - 1)));
208
    BlockRead(LevelFile, Buffer^, 520, k);
209
    Seek(LevelFile, Longint(25 + 520 * (Longint(l - 1) - 1)));
210
    BlockWrite(LevelFile, Buffer^, 520, k);
211
  end;
212
  Seek(LevelFile, 24);
213
  Dec(j);
214
  BlockWrite(LevelFile, j, 1, k);
215
  Seek(LevelFile, FileSize(LevelFile) - 520);
216
  Truncate(LevelFile);
217
  Close(LevelFile);
218
  FreeMem(Buffer, 1000);
219
end;
220
 
221
 
222
procedure LRLInsertLevel(After: Word);
223
var
224
  Buffer: Pointer;
225
  LevelFile: File;
226
  j: Integer;
227
  l: Longint;
228
  k: Word;
229
begin
230
  GetMem(Buffer, 1000);
231
  j := LRLLevelCount;
232
  if (After > j) or (After = 0) then
233
    Exit;
234
  FileMode := 2;
235
  AssignFile(LevelFile, LevelFileName);
236
  Reset(LevelFile, 1);
237
  for l := j downto After + 1 do
238
  begin
239
    Seek(LevelFile, Longint(25 + 520 * (Longint(l) - 1)));
240
    BlockRead(LevelFile, Buffer^, 520, k);
241
    Seek(LevelFile, Longint(25 + 520 * (Longint(l + 1) - 1)));
242
    BlockWrite(LevelFile, Buffer^, 520, k);
243
  end;
244
  Seek(LevelFile, 24);
245
  Inc(j);
246
  BlockWrite(LevelFile, j, 1, k);
247
  Seek(LevelFile, Longint(25 + 520 * (Longint(After + 1) - 1)));
248
  DataFill(Buffer^, 40, 0, 0);
249
  DataFill(Buffer^, 480, 48, 40);
250
  BlockWrite(LevelFile, Buffer^, 520, k);
251
  Close(LevelFile);
252
  FreeMem(Buffer, 1000);
253
end;
254
 
255
 
256
procedure LRLLoadLevel(Number: Byte);
257
var
258
  LevelFile: File;
259
  InBuffer: Pointer;
260
  i, j, k: Word;
261
  a, b, c: Byte;
262
begin
263
  TotalPrizes := 0;
264
  GetMem(InBuffer, $FFF0);
265
 
266
  AssignFile(LevelFile, LevelFileName);
267
  Reset(LevelFile, 1);
268
  if IOResult <> 0 then
269
    raise Exception.Create(ERR_OPENFILE);
270
 
271
  BlockRead(LevelFile, InBuffer^, 24, k);
272
  BlockRead(LevelFile, c, 1, k);
273
  if (c = 0) or (IOResult <> 0) or (not DataIdentical(InBuffer^, LevelFileHeader[1], 24, 0, 0)) then
274
    raise Exception.Create(ERR_BADFILE);
275
 
276
  if (Number = 0) or (Number > c) then Number := 1;
277
  Seek(LevelFile, Longint(25 + 520 * (Longint(Number) - 1)));
278
  BlockRead(LevelFile, InBuffer^, 40, k);
279
 
280
  for i := 1 to 10 do
281
  with LRLLevel.Player[i] do
282
  begin
283
    Command := 10;
284
    NewCommandWas := False;
285
    NewCommand := 10;
286
    Position.x := DataByteGet(InBuffer^, (i - 1) * 4 + 0);
287
    Position.y := DataByteGet(InBuffer^, (i - 1) * 4 + 1);
288
    Position.xoffs := 0;
289
    Position.yoffs := 0;
290
    Sprite  := 1;
291
    SpriteData := 1;
292
    Controller := DataByteGet(InBuffer^, (i - 1) * 4 + 3);
293
    Prizes  := 0;
294
    Colour  := DataByteGet(InBuffer^, (i - 1) * 4 + 2);
295
  end;
296
 
297
  BlockRead(LevelFile, InBuffer^, 480, k);
298
  for i := 1 to 16 do for j := 1 to 30 do
299
  with LRLLevel.Field[j, i] do
300
  begin
301
    a := DataByteGet(InBuffer^, (i - 1) * 30 + (j - 1));
302
    for b := 1 to 10 do
303
    if BrickFlags[b * 2 - 1] = a then
304
      Flags := BrickFlags[b * 2];
305
    Count := 1;
306
    if a < 64 then
307
      a := a - 47 else
308
      a := a - 63;
309
    Image := a;
310
    IdleCount := 0;
311
    if Image = 4 then Inc(TotalPrizes);
312
  end;
313
 
314
  BlockRead(LevelFile, InBuffer^, 480, k);
315
  Close(LevelFile);
316
  LRLCLevel := Number;
317
  FreeMem(InBuffer, $FFF0);
318
end;
319
 
320
 
321
procedure LRLDrawOrnamental(x1, y1, x2, y2, ornament: Byte);
322
var
323
  i: Integer;
324
begin
325
  ImagePut(LRLScreen^, LRLDecoration[ornament].Image[6].Data^, x1 * 10, y1 * 10, 0, 0, 319, 199);
326
  ImagePut(LRLScreen^, LRLDecoration[ornament].Image[7].Data^, x2 * 10, y1 * 10, 0, 0, 319, 199);
327
  ImagePut(LRLScreen^, LRLDecoration[ornament].Image[5].Data^, x1 * 10, y2 * 10, 0, 0, 319, 199);
328
  ImagePut(LRLScreen^, LRLDecoration[ornament].Image[8].Data^, x2 * 10, y2 * 10, 0, 0, 319, 199);
329
  for i := x1 + 1 to x2 - 1 do
330
  begin
331
    ImagePut(LRLScreen^, LRLDecoration[ornament].Image[3].Data^, i * 10, y1 * 10, 0, 0, 319, 199);
332
    ImagePut(LRLScreen^, LRLDecoration[ornament].Image[4].Data^, i * 10, y2 * 10, 0, 0, 319, 199);
333
  end;
334
  for i := y1 + 1 to y2 - 1 do
335
  begin
336
    ImagePut(LRLScreen^, LRLDecoration[ornament].Image[2].Data^, x1 * 10, i * 10, 0, 0, 319, 199);
337
    ImagePut(LRLScreen^, LRLDecoration[ornament].Image[1].Data^, x2 * 10, i * 10, 0, 0, 319, 199);
338
  end;
339
end;
340
 
341
 
342
procedure LRLRedrawLevel;
343
var
344
  i, j: Integer;
345
  s: string;
346
begin
347
  ImageClear(LRLScreen^);
348
  for i := 1 to 16 do for j := 1 to 30 do
349
  with LRLLevel.Field[j, i] do
350
  if ((Flags and 128) = 0) and ((Flags and 32) <> 0) and ((Flags and 16) = 0) then
351
    ImagePut(LRLScreen^, LRLEnvironment[Image].Image[Count].Data^,j * 10, i * 10, 0, 0, 319, 199);
352
 
353
  for i := 1 to 10 do
354
  with LRLLevel.Player[i] do
355
  if Controller <> 0 then
356
    ImagePutTransparent(LRLScreen^, LRLFigure[Colour, SpriteData].Image[Sprite].Data^,Position.x * 10 + Position.xoffs, Position.y * 10 + Position.yoffs, 0, 0, 319, 199);
357
 
358
  for i := 1 to 16 do for j := 1 to 30 do
359
  with LRLLevel.Field[j, i] do
360
  if ((Flags and 128) = 0) and ((Flags and 32) = 0) and ((Flags and 16) = 0) then
361
    ImagePutTransparent(LRLScreen^, LRLEnvironment[Image].Image[LRLLevel.Field[j, i].Count].Data^, j * 10, i * 10, 0, 0, 319, 199);
362
 
363
  if not Paused then
364
  begin
365
    if ShowScore then
366
    begin
367
      STR(LRLScore, s);
368
      ImageStringGet(s, LRLFont^, LRLFontBuffer^, 222);
369
      ImagePut(LRLScreen^, LRLFontBuffer^, 56, 185, 0, 0, 319, 199);
370
      ImageStringGet('Score: ', LRLFont^, LRLFontBuffer^, 254);
371
      ImagePut(LRLScreen^, LRLFontBuffer^, 10, 185, 0, 0, 319, 199);
372
    end;
373
    if ShowLives then
374
    begin
375
      STR(LRLLives, s);
376
      ImageStringGet(s, LRLFont^, LRLFontBuffer^, 222);
377
      ImagePut(LRLScreen^, LRLFontBuffer^, 177, 185, 0, 0, 319, 199);
378
      ImageStringGet('Lives: ', LRLFont^, LRLFontBuffer^, 254);
379
      ImagePut(LRLScreen^, LRLFontBuffer^, 135, 185, 0, 0, 319, 199);
380
    end;
381
    if ShowLevel then
382
    begin
383
      Str(LRLCLevel, s);
384
      ImageStringGet(s, LRLFont^, LRLFontBuffer^, 222);
385
      ImagePut(LRLScreen^, LRLFontBuffer^, 292, 185, 0, 0, 319, 199);
386
      ImageStringGet('Level: ', LRLFont^, LRLFontBuffer^, 254);
387
      ImagePut(LRLScreen^, LRLFontBuffer^, 250, 185, 0, 0, 319, 199);
388
    end;
389
  end
390
  else
391
  begin
392
    ImageStringGet('Game now paused', LRLFont^, LRLFontBuffer^, 254);
393
    ImagePut(LRLScreen^, LRLFontBuffer^, 160 - ImageSizex(LRLFontBuffer^) div
394
      2, 185, 0, 0, 319, 199);
395
  end;
396
  LRLDrawOrnamental(0, 0, 31, 17, 1);
397
end;
398
 
399
 
400
procedure LRLStartSequence;
401
var
402
  tmpScreen1: Pointer;
403
  tmpScreen2: Pointer;
404
  i: Integer;
405
begin
406
  GetMem(tmpScreen1, 64000);
407
  GetMem(tmpScreen2, 49000);
408
  ImageFill(tmpScreen2^, 300, 160, 0);
409
  LRLRedrawLevel;
410
  i := 0;
411
  while i < 100 do
412
  begin
413
    DataMove(LRLScreen^, tmpScreen1^, 64000, 0, 0);
414
    ImagePut(tmpScreen1^, tmpScreen2^, 10, 10, 0, i, 319, 199 - i);
415
    ScreenApply(tmpScreen1^);
416
    Sleep(20);
417
    i := i + 4;
418
  end;
419
  ScreenApply(LRLScreen^);
420
  FreeMem(tmpScreen1, 64000);
421
  FreeMem(tmpScreen2, 49000);
422
end;
423
 
424
 
425
procedure LRLEndSequence;
426
var
427
  tmpScreen1: Pointer;
428
  tmpScreen2: Pointer;
429
  i: Integer;
430
begin
431
  GetMem(tmpScreen1, 64000);
432
  GetMem(tmpScreen2, 49000);
433
  ImageFill(tmpScreen2^, 300, 160, 0);
434
  LRLRedrawLevel;
435
  i := 100;
436
  while i > 0 do
437
  begin
438
    DataMove(LRLScreen^, tmpScreen1^, 64000, 0, 0);
439
    ImagePut(tmpScreen1^, tmpScreen2^, 10, 10, 0, i, 319, 199 - i);
440
    ScreenApply(tmpScreen1^);
441
    Sleep(20);
442
    i := i - 4;
443
  end;
444
  ImagePut(LRLScreen^, tmpScreen2^, 10, 10, 0, 0, 319, 199);
445
  ScreenApply(LRLScreen^);
446
  FreeMem(tmpScreen1, 64000);
447
  FreeMem(tmpScreen2, 49000);
448
end;
449
 
450
 
451
{ GameResult:
452
  1 - замуровали
453
  2 - поймали
454
  10 - все сделано
455
  50 - нет больше уровней
456
  60 - нет человеческих юнитов
457
  100 - нажата Esc }
458
 
459
procedure LRLUpdatePlayers;
460
var
461
  i, k: Integer;
462
  spd: Word;
463
begin
464
  for i := 1 to 10 do
465
  begin
466
    with LRLLevel.Player[i] do
467
    begin
468
      if Controller <> 0 then
469
      begin
470
        if (LRLLevel.Field[Position.x, Position.y].Flags and 2 <> 0) then
471
        begin
472
          if i = 1 then
473
          begin
474
            EndOfGame  := True;
475
            GameResult := 1;
476
            Exit;
477
          end;
478
          if Prizes <> 0 then
479
          begin
480
            Prizes := 0;
481
            LRLLevel.Field[Position.x, Position.y - 1].Image := 4;
482
            LRLLevel.Field[Position.x, Position.y - 1].Flags := BrickFlags[8];
483
          end;
484
          repeat
485
            Position.y := Random(2) + 1;
486
            Position.x := Random(30) + 1;
487
          until (LRLLevel.Field[Position.x, Position.y].Image = 1) or
488
            (LRLLevel.Field[Position.x, Position.y].Image = 2) or
489
            (LRLLevel.Field[Position.x, Position.y].Image = 3) or
490
            (LRLLevel.Field[Position.x, Position.y].Image = 4);
491
          Command := 10;
492
          Continue;
493
        end;
494
 
495
        if LRLLevel.Field[Position.x, Position.y].Image = 4 then
496
        if Controller = 2 then
497
        if Prizes = 0 then
498
        begin
499
          Inc(Prizes);
500
          LRLLevel.Field[Position.x, Position.y].Image := 1;
501
          LRLLevel.Field[Position.x, Position.y].Flags := BrickFlags[2];
502
        end else else
503
        begin
504
          Dec(TotalPrizes);
505
          LRLScore := LRLScore + 100 * Longint(LRLCLevel);
506
          LRLLevel.Field[Position.x, Position.y].Image := 1;
507
          LRLLevel.Field[Position.x, Position.y].Flags := BrickFlags[2];
508
        end;
509
 
510
        if (i = 1) then
511
        begin
512
          if (TotalPrizes = 0) and (Position.y = 1) and
513
             (LRLLevel.Field[Position.x, Position.y].Image = 2) then
514
          begin
515
            EndOfGame  := True;
516
            GameResult := 10;
517
            Exit;
518
          end;
519
          for k := 2 to 10 do
520
            if (LRLLevel.Player[k].Controller <> 0) and
521
               (LRLLevel.Player[k].Position.x = Position.x) and
522
               (LRLLevel.Player[k].Position.y = Position.y) then
523
            begin
524
              EndOfGame  := True;
525
              GameResult := 2;
526
              Exit;
527
            end;
528
        end;
529
        if (LRLLevel.Field[Position.x, Position.y].Flags and 1 <> 0) then
530
        begin
531
          if (Controller = 2) then
532
          begin
533
            if Prizes <> 0 then
534
            begin
535
              Prizes := 0;
536
              LRLLevel.Field[Position.x, Position.y - 1].Image := 4;
537
              LRLLevel.Field[Position.x, Position.y - 1].Flags := BrickFlags[8];
538
            end;
539
          end;
540
        end;
541
        if Controller = 2 then
542
          spd := 2
543
        else
544
          spd := 3;
545
 
546
        if (LRLLevel.Field[Position.x, Position.y + 1].Flags and 4 <> 0) and
547
           (LRLLevel.Field[Position.x, Position.y].Image <> 3) and
548
           ((LRLLevel.Field[Position.x, Position.y].Image <> 2) or
549
            (LRLLevel.Field[Position.x, Position.y].Flags and 16 <> 0)) and
550
           (Position.y < 16) then
551
        begin
552
          k := 2;
553
          while k <= 10 do
554
          if (k <> i) and (LRLLevel.Player[k].Controller <> 0) and
555
             (LRLLevel.Player[k].Position.x = Position.x) and
556
             (LRLLevel.Player[k].Position.y = Position.y + 1) and
557
             (Position.y < 16) then
558
          begin
559
            k := 100;
560
            Break;
561
          end else
562
            Inc(k);
563
 
564
          if k <> 100 then
565
          begin
566
            NewCommand := 5;
567
            NewCommandWas := True;
568
          end;
569
        end;
570
 
571
        if NewCommandWas then
572
        begin
573
          if (NewCommand <> Command) and (Command <> 5) then
574
          begin
575
            Command := NewCommand;
576
            Sprite  := 1;
577
          end;
578
          NewCommandWas := False;
579
        end;
580
 
581
        if (Command = 1) then
582
        begin
583
          if (LRLLevel.Field[Position.x, Position.y].Image = 3) then
584
          begin
585
            if Position.xoffs < 1 then
586
            begin
587
              if ((LRLLevel.Field[Position.x - 1, Position.y].Flags and 8 = 0) and
588
                (LRLLevel.Field[Position.x - 1, Position.y].Image <> 3)) or
589
                (LRLLevel.Field[Position.x, Position.y].Image <> 3) or (Position.x = 1) then
590
              begin
591
                Command := 10;
592
                Position.xoffs := 0;
593
              end;
594
            end;
595
            if (Command <> 10) and (SpriteData <> 6) then
596
            begin
597
              SpriteData := 6;
598
              Sprite := 1;
599
            end;
600
          end else
601
          begin
602
            if Position.xoffs < 1 then
603
            begin
604
              if (LRLLevel.Field[Position.x - 1, Position.y].Flags and 8 = 0) or (Position.x = 1) then
605
              begin
606
                Command := 10;
607
                Position.xoffs := 0;
608
              end;
609
            end;
610
            if (Command <> 10) and (SpriteData <> 1) then SpriteData := 1;
611
          end;
612
 
613
          if Command <> 10 then
614
          begin
615
            k := 1;
616
            while (k > 0) do
617
            begin
618
              Inc(k);
619
              if k = 11 then
620
              begin
621
                if (SpriteData = 6) then
622
                begin
623
                  if (Sprite = 2) then Dec(Position.xoffs, 5) else
624
                  if (Sprite = 3) then Dec(Position.xoffs, 1);
625
                end else
626
                  Dec(Position.xoffs, spd);
627
                Break;
628
              end;
629
              if (k <> i) and (i <> 1) and
630
                 (LRLLevel.Player[k].Controller <> 0) and
631
                 (LRLLevel.Player[k].Position.x = Position.x - 1) and
632
                 (LRLLevel.Player[k].Position.y = Position.y) then
633
                begin
634
                  Command := 10;
635
                  Break;
636
                end;
637
            end;
638
          end;
639
        end;
640
 
641
        if (Command = 2) then
642
        begin
643
          if (LRLLevel.Field[Position.x, Position.y].Image = 3) then
644
          begin
645
            if Position.xoffs > -1 then
646
            begin
647
              if ((LRLLevel.Field[Position.x + 1, Position.y].Flags and 8 = 0) and
648
                (LRLLevel.Field[Position.x + 1, Position.y].Image <> 3)) or
649
                (LRLLevel.Field[Position.x, Position.y].Image <> 3) or (Position.x = 30) then
650
              begin
651
                Command := 10;
652
                Position.xoffs := 0;
653
              end;
654
            end;
655
            if (Command <> 10) and (SpriteData <> 7) then
656
            begin
657
              SpriteData := 7;
658
              Sprite := 1;
659
            end;
660
          end
661
          else
662
          begin
663
            if Position.xoffs > -1 then
664
            begin
665
              if (LRLLevel.Field[Position.x + 1, Position.y].Flags and 8 = 0) or (Position.x = 30) then
666
              begin
667
                Command := 10;
668
                Position.xoffs := 0;
669
              end;
670
            end;
671
            if (Command <> 10) and (SpriteData <> 2) then
672
              SpriteData := 2;
673
          end;
674
          if Command <> 10 then
675
          begin
676
            k := 1;
677
            while (k > 0) do
678
            begin
679
              Inc(k);
680
              if k = 11 then
681
              begin
682
                if (SpriteData = 7) then
683
                begin
684
                  if (Sprite = 2) then
685
                    Inc(Position.xoffs, 5);
686
                  if (Sprite = 3) then
687
                    Inc(Position.xoffs, 1);
688
                end
689
                else
690
                  Inc(Position.xoffs, spd);
691
                Break;
692
              end;
693
              if (k <> i) and (i <> 1) and (LRLLevel.Player[k].Controller <> 0) then
694
                if (LRLLevel.Player[k].Position.x = Position.x + 1) and
695
                  (LRLLevel.Player[k].Position.y = Position.y) then
696
                begin
697
                  Command := 10;
698
                  Break;
699
                end;
700
            end;
701
          end;
702
        end;
703
 
704
        if (Command = 3) then
705
        begin
706
          if Position.yoffs < 1 then
707
          begin
708
            if ((LRLLevel.Field[Position.x, Position.y].Image <> 2) or (LRLLevel.Field[Position.x, Position.y].Flags and 16 <> 0)) or
709
               ((LRLLevel.Field[Position.x, Position.y - 1].Flags and 4 = 0) and
710
                 ((LRLLevel.Field[Position.x, Position.y - 1].Image <> 2) or (LRLLevel.Field[Position.x, Position.y - 1].Flags and 16 <> 0))) or
711
               (Position.y < 2) then
712
            begin
713
              Command := 10;
714
              Position.yoffs := 0;
715
            end;
716
          end;
717
          if (Command <> 10) and (SpriteData <> 3) then
718
            SpriteData := 3;
719
          if Command <> 10 then
720
          begin
721
            k := 1;
722
            while (k > 0) do
723
            begin
724
              Inc(k);
725
              if k = 11 then
726
              begin
727
                Dec(Position.yoffs, spd);
728
                Break;
729
              end;
730
              if (k <> i) and (i <> 1) and (LRLLevel.Player[k].Controller <> 0) then
731
                if (LRLLevel.Player[k].Position.y = Position.y - 1) and
732
                  (LRLLevel.Player[k].Position.x = Position.x) then
733
                begin
734
                  Command := 10;
735
                  Break;
736
                end;
737
            end;
738
          end;
739
        end;
740
 
741
        if (Command = 4) then
742
        begin
743
          if (LRLLevel.Field[Position.x, Position.y].Image = 3) and
744
             ((LRLLevel.Field[Position.x, Position.y + 1].Image <> 2) or
745
              (LRLLevel.Field[Position.x, Position.y + 1].Flags and 16 <> 0)) and
746
             (Position.y < 16) then
747
          begin
748
            Command := 5;
749
            Sprite  := 1;
750
            if (LRLLevel.Field[Position.x, Position.y + 1].Flags and 4 <> 0) then
751
              Inc(Position.yoffs);
752
          end
753
          else
754
          begin
755
            if Position.yoffs > -1 then
756
            begin
757
              if (((LRLLevel.Field[Position.x, Position.y + 1].Image <> 2) or
758
                (LRLLevel.Field[Position.x, Position.y + 1].Flags and 16 <> 0)) and
759
                (LRLLevel.Field[Position.x, Position.y + 1].Flags and 4 = 0)) or
760
                (Position.y = 16) then
761
              begin
762
                Command := 10;
763
                Position.yoffs := 0;
764
              end;
765
            end;
766
            if (Command <> 10) and (SpriteData <> 4) then
767
              SpriteData := 4;
768
            if Command <> 10 then
769
            begin
770
              k := 1;
771
              while (k > 0) do
772
              begin
773
                Inc(k);
774
                if k = 11 then
775
                begin
776
                  Inc(Position.yoffs, spd);
777
                  Break;
778
                end;
779
                if (k <> i) and (i <> 1) and (LRLLevel.Player[k].Controller <> 0) then
780
                  if (LRLLevel.Player[k].Position.y = Position.y + 1) and
781
                    (LRLLevel.Player[k].Position.x = Position.x) then
782
                  begin
783
                    Command := 10;
784
                    Break;
785
                  end;
786
              end;
787
            end;
788
          end;
789
        end;
790
 
791
        if (Command = 5) then
792
        begin
793
          if Position.yoffs < 1 then
794
          begin
795
            if (LRLLevel.Field[Position.x, Position.y + 1].Flags and 4 = 0) or
796
              (Position.y = 16) or (LRLLevel.Field[Position.x, Position.y].Image = 3) or
797
              ((LRLLevel.Field[Position.x, Position.y].Flags and 1 <> 0) and (i <> 1)) then
798
            begin
799
              Command := 10;
800
              if (LRLLevel.Field[Position.x, Position.y].Image = 3) then
801
                SpriteData := 5;
802
              Position.yoffs := 0;
803
              Position.xoffs := 0;
804
            end;
805
            for k := 2 to 10 do
806
              if (k <> i) and (LRLLevel.Player[k].Controller <> 0) then
807
                if (LRLLevel.Player[k].Position.x = Position.x) and
808
                  (LRLLevel.Player[k].Position.y = Position.y + 1) and
809
                  (LRLLevel.Field[Position.x, Position.y + 1].Flags and 1 <> 0) and
810
                  (Position.y < 16) then
811
                begin
812
                  Command := 10;
813
                  Position.yoffs := 0;
814
                  Break;
815
                end;
816
          end;
817
          if (Command <> 10) and (SpriteData <> 5) then
818
          begin
819
            SpriteData := 5;
820
            Sprite := 1;
821
          end;
822
          if Command <> 10 then
823
          begin
824
            Inc(Position.yoffs, 2);
825
          end;
826
        end;
827
 
828
        if (Command = 6) then
829
        begin
830
          if (Position.y < 16) and (Position.x > 1) and
831
            (LRLLevel.Field[Position.x - 1, Position.y + 1].Image = 9) and
832
            (LRLLevel.Field[Position.x - 1, Position.y + 1].Flags and 1 = 0) and
833
            (((LRLLevel.Field[Position.x - 1, Position.y].Image = 1) or
834
            (LRLLevel.Field[Position.x - 1, Position.y].Flags and 1 <> 0)) or
835
            (LRLLevel.Field[Position.x - 1, Position.y].Flags and 16 <> 0)) then
836
          begin
837
            NewCommandWas := True;
838
            for k := 2 to 10 do
839
              if (k <> i) and (LRLLevel.Player[k].Controller <> 0) then
840
                if (LRLLevel.Player[k].Position.x = Position.x - 1) and
841
                  (LRLLevel.Player[k].Position.y = Position.y) then
842
                begin
843
                  NewCommandWas := False;
844
                  Break;
845
                end;
846
            if NewCommandWas then
847
            begin
848
              LRLLevel.Field[Position.x - 1, Position.y + 1].Flags :=
849
                LRLLevel.Field[Position.x - 1, Position.y + 1].Flags or 1;
850
              Position.xoffs := 0;
851
              SpriteData := 8;
852
              NewCommandWas := False;
853
            end;
854
          end;
855
          Command := 10;
856
        end;
857
 
858
        if (Command = 7) then
859
        begin
860
          if (Position.y < 16) and (Position.x < 30) and
861
            (LRLLevel.Field[Position.x + 1, Position.y + 1].Image = 9) and
862
            (LRLLevel.Field[Position.x + 1, Position.y + 1].Flags and 1 = 0) and
863
            (((LRLLevel.Field[Position.x + 1, Position.y].Image = 1) or
864
            (LRLLevel.Field[Position.x + 1, Position.y].Flags and 1 <> 0)) or
865
            (LRLLevel.Field[Position.x + 1, Position.y].Flags and 16 <> 0)) then
866
          begin
867
            NewCommandWas := True;
868
            for k := 2 to 10 do
869
              if (k <> i) and (LRLLevel.Player[k].Controller <> 0) then
870
                if (LRLLevel.Player[k].Position.x = Position.x + 1) and
871
                  (LRLLevel.Player[k].Position.y = Position.y) then
872
                begin
873
                  NewCommandWas := False;
874
                  Break;
875
                end;
876
            if NewCommandWas then
877
            begin
878
              LRLLevel.Field[Position.x + 1, Position.y + 1].Flags :=
879
                LRLLevel.Field[Position.x + 1, Position.y + 1].Flags or 1;
880
              Position.xoffs := 0;
881
              SpriteData := 9;
882
              NewCommandWas := False;
883
            end;
884
          end;
885
          Command := 10;
886
        end;
887
 
888
        if (Command = 1) or (Command = 2) then
889
          if Position.yoffs < 0 then Inc(Position.yoffs) else
890
          if Position.yoffs > 0 then  Dec(Position.yoffs);
891
 
892
        if (Command = 3) or (Command = 4) or (Command = 5) then
893
          if Position.xoffs < 0 then Inc(Position.xoffs) else
894
          if Position.xoffs > 0 then Dec(Position.xoffs);
895
 
896
        if Command < 6 then
897
        begin
898
          Inc(Sprite);
899
          if Sprite > LRLFigure[Colour, SpriteData].ImageCount then Sprite := 1;
900
          if Position.xoffs < -4 then
901
          begin
902
            Dec(Position.x);
903
            Position.xoffs := 10 + Position.xoffs;
904
          end;
905
          if Position.xoffs > 5 then
906
          begin
907
            Inc(Position.x);
908
            Position.xoffs := Position.xoffs - 10;
909
          end;
910
          if Position.yoffs < -4 then
911
          begin
912
            Dec(Position.y);
913
            Position.yoffs := 10 + Position.yoffs;
914
          end;
915
          if Position.yoffs > 5 then
916
          begin
917
            Inc(Position.y);
918
            Position.yoffs := Position.yoffs - 10;
919
          end;
920
        end;
921
      end;
922
    end;
923
  end;
924
end;
925
 
926
 
927
procedure LRLUpdateBricks;
928
var
929
  i, j, k: Integer;
930
begin
931
  for i := 1 to 16 do
932
    for j := 1 to 30 do
933
    begin
934
      if LRLLevel.Field[j, i].Flags and 1 <> 0 then
935
      begin
936
        if LRLLevel.Field[j, i].Count = 1 then
937
        begin
938
          LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags and $FF - 2;
939
          LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags or 4 + 8;
940
        end;
941
        if LRLLevel.Field[j, i].IdleCount = 0 then
942
        begin
943
          Inc(LRLLevel.Field[j, i].Count);
944
          if LRLLevel.Field[j, i].Count < 6 then
945
          begin
946
            for k := 2 to 10 do
947
              if (LRLLevel.Player[k].Controller <> 0) then
948
                if (LRLLevel.Player[k].Position.x = j) and
949
                  (LRLLevel.Player[k].Position.y = i - 1) then
950
                begin
951
                  LRLLevel.Field[j, i].Count := 13 - LRLLevel.Field[j, i].Count;
952
                  LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags or 2;
953
                  LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags and $FE - 4 - 8;
954
                  LRLLevel.Field[j, i].Count := 1;
955
                  Break;
956
                end;
957
          end;
958
          if LRLLevel.Field[j, i].Count = 6 then
959
          begin
960
            LRLLevel.Field[j, i].IdleCount := 100;
961
          end;
962
        end
963
        else
964
          Dec(LRLLevel.Field[j, i].IdleCount);
965
        if LRLLevel.Field[j, i].Count = 12 then
966
        begin
967
          LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags or 2;
968
          LRLLevel.Field[j, i].Flags := LRLLevel.Field[j, i].Flags and $FE - 4 - 8;
969
          LRLLevel.Field[j, i].Count := 1;
970
        end;
971
      end;
972
    end;
973
end;
974
 
975
 
976
procedure LRLComputerPlayer;
977
var
978
  k, l, m, f1, f2, i: Integer;
979
begin
980
  if ComputerTurn >= ComputerReaction then
981
  begin
982
    ComputerTurn := 0;
983
    for k := 1 to 10 do
984
    begin
985
      with LRLLevel.Player[k] do
986
      begin
987
        if Controller = 2 then
988
        begin
989
          NewCommandWas := True;
990
          NewCommand := 10;
991
          if (Position.y > LRLLevel.Player[1].Position.y) then
992
          begin
993
            if ((LRLLevel.Field[Position.x, Position.y].Image = 2) and
994
              (LRLLevel.Field[Position.x, Position.y].Flags and 16 = 0) and
995
              ((LRLLevel.Field[Position.x, Position.y - 1].Image = 2) or
996
              (LRLLevel.Field[Position.x, Position.y - 1].Flags and 4 <> 0)) and
997
              (Position.y > 1)) then
998
            begin
999
              NewCommand := 3;
1000
            end
1001
            else
1002
            begin
1003
              m := 1;
1004
              l := Position.x;
1005
              i := 1;
1006
              while i <> 0 do
1007
              begin
1008
                l := l + i;
1009
                if ((LRLLevel.Field[l, Position.y].Image = 2) and
1010
                  (LRLLevel.Field[l, Position.y].Flags and 16 = 0)) and
1011
                  ((LRLLevel.Field[l, Position.y - 1].Image = 2) and
1012
                  (LRLLevel.Field[l, Position.y - 1].Flags and 16 = 0)) and (Position.y <> 1) then
1013
                begin
1014
                  if m = 0 then
1015
                  begin
1016
                    f2 := Position.x - l;
1017
                    Break;
1018
                  end;
1019
                  m  := 0;
1020
                  i  := not i + 1;
1021
                  f1 := l - Position.x;
1022
                  l  := Position.x;
1023
                end
1024
                else
1025
                if (LRLLevel.Field[l, Position.y].Flags and 8 = 0) or (l > 30) or (l < 1) then
1026
                begin
1027
                  if m = 0 then
1028
                  begin
1029
                    f2 := 100;
1030
                    Break;
1031
                  end;
1032
                  m  := 0;
1033
                  i  := not i + 1;
1034
                  l  := Position.x;
1035
                  f1 := 100;
1036
                end;
1037
              end;
1038
              if (f1 = 100) and (f2 = 100) then
1039
                NewCommand := 10
1040
              else
1041
              begin
1042
                if f1 > f2 then
1043
                  NewCommand := 1
1044
                else
1045
                  NewCommand := 2;
1046
              end;
1047
            end;
1048
          end else
1049
 
1050
          if (Position.y < LRLLevel.Player[1].Position.y) then
1051
          begin
1052
            if (((LRLLevel.Field[Position.x, Position.y + 1].Image = 2) and
1053
              (LRLLevel.Field[Position.x, Position.y + 1].Flags and 16 = 0)) or
1054
              (LRLLevel.Field[Position.x, Position.y + 1].Flags and 4 <> 0)) and
1055
              (Position.y < 16) and (LRLLevel.Field[Position.x, Position.y + 1].Flags and 1 = 0) then
1056
            begin
1057
              NewCommand := 4;
1058
            end
1059
            else
1060
            begin
1061
              m := 1;
1062
              l := Position.x;
1063
              i := 1;
1064
              while i <> 0 do
1065
              begin
1066
                l := l + i;
1067
                if ((LRLLevel.Field[l, Position.y + 1].Image = 2) and
1068
                  (LRLLevel.Field[l, Position.y + 1].Flags and 16 = 0)) or
1069
                  ((LRLLevel.Field[l, Position.y + 1].Flags and 4 <> 0) and
1070
                  (LRLLevel.Field[l, Position.y + 1].Flags and 1 = 0)) then
1071
                begin
1072
                  if m = 0 then
1073
                  begin
1074
                    f2 := Position.x - l;
1075
                    Break;
1076
                  end;
1077
                  m  := 0;
1078
                  i  := not i + 1;
1079
                  f1 := l - Position.x;
1080
                  l  := Position.x;
1081
                end
1082
                else
1083
                if (LRLLevel.Field[l, Position.y].Flags and 8 = 0) or (l > 30) or (l < 1) then
1084
                begin
1085
                  if m = 0 then
1086
                  begin
1087
                    f2 := 100;
1088
                    Break;
1089
                  end;
1090
                  m  := 0;
1091
                  i  := not i + 1;
1092
                  l  := Position.x;
1093
                  f1 := 100;
1094
                end;
1095
              end;
1096
              if (f1 = 100) and (f2 = 100) then
1097
                NewCommand := 10
1098
              else
1099
              begin
1100
                if f1 > f2 then
1101
                  NewCommand := 1
1102
                else
1103
                  NewCommand := 2;
1104
              end;
1105
            end;
1106
          end
1107
          else
1108
          begin
1109
            if (Position.x > LRLLevel.Player[1].Position.x) then
1110
              NewCommand := 1;
1111
            if (Position.x < LRLLevel.Player[1].Position.x) then
1112
              NewCommand := 2;
1113
          end;
1114
        end;
1115
      end;
1116
    end;
1117
  end else
1118
    Inc(ComputerTurn);
1119
end;
1120
 
1121
 
1122
procedure LRLPlayLevel(Number: Byte);
1123
var
1124
  Keypress: Word;
1125
  i: Word;
1126
  L, C: Longword;
1127
begin
1128
  Randomize;
1129
  ComputerReaction := 1;
1130
  LRLLoadLevel(Number);
1131
 
1132
  if LRLCLevel <> Number then
1133
  begin
1134
    GameResult := 50;
1135
    Exit;
1136
  end;
1137
  if LRLLevel.Player[1].Controller <> 1 then
1138
  begin
1139
    GameResult := 60;
1140
    Exit;
1141
  end;
1142
 
1143
  TimeToRefresh := True;
1144
  GameStarted := False;
1145
  GameResult := 0;
1146
  Paused := False;
1147
  EndOfGame := False;
1148
 
1149
  LRLStartSequence;
1150
 
1151
  Keypress := 0;
1152
  L := 0;
1153
 
1154
  repeat
1155
    C := LastDosTick();
1156
    if L <> C then
1157
    begin
1158
      L := C;
1159
      if GameStarted and not Paused then
1160
      begin
1161
        LRLComputerPlayer;
1162
        LRLUpdatePlayers;
1163
        LRLUpdateBricks;
1164
      end;
1165
      LRLRedrawLevel;
1166
      ScreenApply(LRLScreen^);
1167
    end else
1168
      Sleep(20);
1169
 
1170
    if Keypressed then
1171
    begin
1172
      Keypress := ReadKey;
1173
      GameStarted := True;
1174
      Paused := False;
1175
 
1176
      for i := 0 to ControlNumber - 1 do
1177
      if KeyboardControls[i * 3 + 1] = Keypress then
1178
      begin
1179
        LRLLevel.Player[KeyboardControls[i * 3 + 2]].NewCommand := KeyboardControls[i * 3 + 3];
1180
        LRLLevel.Player[KeyboardControls[i * 3 + 2]].NewCommandWas := True;
1181
      end;
1182
 
1183
      if Keypress = KEY_P then
1184
        Paused := True;
1185
    end;
1186
  until (Keypress = KEY_ESC) or EndOfGame;
1187
 
1188
  if EndOfGame then
1189
    LRLEndSequence else
1190
    GameResult := 100;
1191
end;
1192
 
1193
 
1194
end.