Subversion Repositories spacemission

Rev

Rev 48 | Rev 52 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 daniel-mar 1
unit ComLevelReader;
2
 
3
interface
4
 
40 daniel-mar 5
uses
6
  Classes;
7
 
27 daniel-mar 8
const
9
  NumEnemyTypes = 7;
10
 
14 daniel-mar 11
type
12
  TEnemyType = (
13
    etUnknown,
14
    etEnemyAttacker,
15
    etEnemyAttacker2,
16
    etEnemyAttacker3,
17
    etEnemyMeteor,
18
    etEnemyUFO,
19
    etEnemyUFO2,
20
    etEnemyBoss
21
  );
22
 
23
  TEnemyAdvent = record
24
    enemyType: TEnemyType;
25
    x: integer;
26
    y: integer;
27
    lifes: integer;
28
  end;
29
 
40 daniel-mar 30
  TLevelData = class(TPersistent)
27 daniel-mar 31
  strict private
32
    procedure SortEnemies;
40 daniel-mar 33
  strict protected
34
    procedure AssignTo(Dest: TPersistent); override;
14 daniel-mar 35
  public
40 daniel-mar 36
    RasterErzwingen: boolean;
14 daniel-mar 37
    LevelEditorLength: integer;
42 daniel-mar 38
    LevelName: string;
39
    LevelAuthor: string;
14 daniel-mar 40
    EnemyAdventTable: array of TEnemyAdvent;
27 daniel-mar 41
    function IndexOfEnemy(x,y:integer;enemyType:TEnemyType;lifes:integer): integer;
42
    procedure AddEnemy(x,y:integer;enemyType:TEnemyType;lifes:integer);
43
    procedure DeleteEnemy(i: integer); overload;
44
    procedure DeleteEnemy(x,y:integer;enemyType:TEnemyType;lifes:integer); overload;
45
    function CountEnemies: integer;
46
    function HasBoss: boolean;
14 daniel-mar 47
    procedure Clear;
40 daniel-mar 48
    procedure LoadFromStrings(sl: TStrings); // version 0.3 - version 1.2 files
49
    procedure LoadFromFile(filename: string); // version 0.2 - version 1.2 files
50
    procedure SaveToStrings(sl: TStrings);
51
    procedure SaveToFile(filename: string);
52
    destructor Destroy; override;
14 daniel-mar 53
  end;
54
 
40 daniel-mar 55
  TGameMode = (gmUnknown, gmLevels, gmRandom);
56
 
57
  TSaveData = class(TPersistent)
58
  strict protected
59
    procedure AssignTo(Dest: TPersistent); override;
60
  public
61
    Score: integer;
62
    Life: integer;
63
    Level: integer;
64
    GameMode: TGameMode;
65
    LevelData: TLevelData;
66
    procedure Clear;
67
    procedure LoadFromStrings(sl: TStrings);
68
    procedure LoadFromFile(filename: string);
69
    procedure SaveToStrings(sl: TStrings);
70
    procedure SaveToFile(filename: string);
71
    destructor Destroy; override;
72
  end;
73
 
51 daniel-mar 74
function GetLevelFileName(lev: integer; forceuserdir: boolean): string;
17 daniel-mar 75
 
14 daniel-mar 76
implementation
77
 
78
uses
51 daniel-mar 79
  SysUtils, StrUtils, Global, Windows;
14 daniel-mar 80
 
51 daniel-mar 81
function GetLevelFileName(lev: integer; forceuserdir: boolean): string;
27 daniel-mar 82
 
51 daniel-mar 83
  function _GetLevelVerzeichnisSystem: string;
84
  begin
85
    // Für die Auslieferungs-Levels
86
    result := OwnDirectory + 'Levels';
87
  end;
88
 
89
  function _GetLevelVerzeichnisUser: string;
90
  begin
91
    try
92
      result := GetKnownFolderPath(FOLDERID_SavedGames);
93
    except
94
      result := '';
95
    end;
96
    if result = '' then
97
    begin
98
      // Pre Vista
99
      result := OwnDirectory + 'Levels';
100
    end
101
    else
102
    begin
103
      result := IncludeTrailingPathDelimiter(result);
104
      result := result + 'SpaceMission';
105
    end;
106
    result := IncludeTrailingPathDelimiter(result);
107
    ForceDirectories(result);
108
  end;
109
 
110
  function _GetLevelFileNameUser(lev: integer): string;
111
  var
112
    old, new: string;
113
  begin
114
    new := IncludeTrailingPathDelimiter(_GetLevelVerzeichnisUser)+'Level '+inttostr(lev)+'.lev'; // Version 0.3+ Level Files
115
    old := IncludeTrailingPathDelimiter(_GetLevelVerzeichnisUser)+'Lev'+inttostr(lev)+'A1.lev'; // Version 0.2 Level Files
116
    if fileexists(new) then exit(new);
117
    if fileexists(old) then exit(old);
118
    exit(new);
119
  end;
120
 
121
  function _GetLevelFileNameSystem(lev: integer): string;
122
  var
123
    old, new: string;
124
  begin
125
    new := IncludeTrailingPathDelimiter(_GetLevelVerzeichnisSystem)+'Level '+inttostr(lev)+'.lev'; // Version 0.3+ Level Files
126
    old := IncludeTrailingPathDelimiter(_GetLevelVerzeichnisSystem)+'Lev'+inttostr(lev)+'A1.lev'; // Version 0.2 Level Files
127
    if fileexists(new) then exit(new);
128
    if fileexists(old) then exit(old);
129
    exit(new);
130
  end;
131
 
132
var
133
  usr, sys: string;
17 daniel-mar 134
begin
51 daniel-mar 135
  usr := _GetLevelFileNameUser(lev);
136
  sys := _GetLevelFileNameSystem(lev);
137
  if fileexists(usr) or forceuserdir then exit(usr);
138
  if fileexists(sys) then exit(sys);
139
  exit(usr);
17 daniel-mar 140
end;
141
 
14 daniel-mar 142
{ TLevelData }
143
 
40 daniel-mar 144
procedure TLevelData.AssignTo(Dest: TPersistent);
145
var
146
  DestLevelData: TLevelData;
147
  i: integer;
148
begin
149
  DestLevelData := Dest as TLevelData;
150
  if Assigned(DestLevelData) then
151
  begin
152
    DestLevelData.RasterErzwingen := Self.RasterErzwingen;
153
    DestLevelData.LevelEditorLength := Self.LevelEditorLength;
42 daniel-mar 154
    DestLevelData.LevelName := Self.LevelName;
155
    DestLevelData.LevelAuthor := Self.LevelAuthor;
40 daniel-mar 156
    SetLength(DestLevelData.EnemyAdventTable, Length(Self.EnemyAdventTable));
157
    for i := 0 to Length(Self.EnemyAdventTable) do
158
    begin
159
      DestLevelData.EnemyAdventTable[i] := Self.EnemyAdventTable[i];
160
    end;
161
  end
162
  else
163
  begin
164
    inherited;
165
  end;
166
end;
167
 
14 daniel-mar 168
procedure TLevelData.Clear;
169
begin
170
  SetLength(EnemyAdventTable, 0);
27 daniel-mar 171
  LevelEditorLength := DefaultLevelLength;
42 daniel-mar 172
  LevelName := '';
173
  LevelAuthor := '';
14 daniel-mar 174
end;
175
 
27 daniel-mar 176
function TLevelData.CountEnemies: integer;
177
begin
178
  result := Length(EnemyAdventTable);
179
end;
180
 
181
procedure TLevelData.DeleteEnemy(i: integer);
182
var
183
  j: integer;
184
begin
185
  for j := i+1 to CountEnemies-1 do
186
  begin
187
    EnemyAdventTable[j-1] := EnemyAdventTable[j];
188
  end;
189
  SetLength(EnemyAdventTable, Length(EnemyAdventTable)-1);
190
end;
191
 
192
procedure TLevelData.DeleteEnemy(x, y: integer; enemyType: TEnemyType;
193
  lifes: integer);
194
begin
195
  DeleteEnemy(IndexOfEnemy(x, y, enemyType, lifes));
196
end;
197
 
40 daniel-mar 198
destructor TLevelData.Destroy;
199
begin
200
  Clear;
201
  inherited;
202
end;
203
 
27 daniel-mar 204
function TLevelData.HasBoss: boolean;
205
var
206
  i: integer;
207
begin
208
  for i := 0 to Length(EnemyAdventTable) - 1 do
209
  begin
210
    if EnemyAdventTable[i].enemyType = etEnemyBoss then
211
    begin
212
      result := true;
213
      exit;
214
    end;
215
  end;
216
  result := false;
217
end;
218
 
219
procedure TLevelData.AddEnemy(x,y:integer;enemyType:TEnemyType;lifes:integer);
220
begin
221
  SetLength(EnemyAdventTable, Length(EnemyAdventTable)+1);
28 daniel-mar 222
 
223
  if enemyType = etEnemyMeteor then lifes := 0;
40 daniel-mar 224
  if RasterErzwingen then
225
  begin
226
    if x mod RasterW <> 0 then raise Exception.CreateFmt('X-Koordinate muss ohne Rest durch %d teilbar sein', [RasterW]);
227
    if y mod RasterH <> 0 then raise Exception.CreateFmt('Y-Koordinate muss ohne Rest durch %d teilbar sein', [RasterH]);
228
  end;
229
  if lifes > MaxPossibleEnemyLives then lifes := MaxPossibleEnemyLives;
28 daniel-mar 230
 
27 daniel-mar 231
  EnemyAdventTable[Length(EnemyAdventTable)-1].x         := x;
232
  EnemyAdventTable[Length(EnemyAdventTable)-1].y         := y;
233
  EnemyAdventTable[Length(EnemyAdventTable)-1].enemyType := enemyType;
234
  EnemyAdventTable[Length(EnemyAdventTable)-1].lifes     := lifes;
235
end;
236
 
237
function TLevelData.IndexOfEnemy(x, y: integer; enemyType: TEnemyType;
238
  lifes: integer): integer;
239
var
240
  i: integer;
241
begin
242
  for i := 0 to Length(EnemyAdventTable) - 1 do
243
  begin
244
    if (EnemyAdventTable[i].x = x) and
245
       (EnemyAdventTable[i].y = y) and
246
       (EnemyAdventTable[i].enemyType = enemyType) and
247
       (EnemyAdventTable[i].lifes = lifes) then
248
    begin
249
      result := i;
250
      exit;
251
    end;
252
  end;
253
  result := -1;
254
end;
255
 
40 daniel-mar 256
procedure TLevelData.LoadFromStrings(sl: TStrings);
14 daniel-mar 257
var
258
  curline: integer;
17 daniel-mar 259
  z, act: integer;
40 daniel-mar 260
  sl2: TStringList;
27 daniel-mar 261
  tmpX, tmpY, tmpLifes: integer;
262
  tmpEnemy: TEnemyType;
30 daniel-mar 263
  tmpRest: string;
40 daniel-mar 264
  ergebnis: string;
14 daniel-mar 265
begin
27 daniel-mar 266
  Clear;
267
 
42 daniel-mar 268
  LevelEditorLength := DefaultLevelLength;
269
  LevelName := '';
270
  LevelAuthor := '';
271
 
40 daniel-mar 272
  if sl.Strings[0] = '; SpaceMission 0.3' then
273
  begin
274
    {$REGION 'Backwards compatibility level format 0.3 (convert to 0.4)'}
275
    sl.Strings[0] := '; SpaceMission 0.4';
276
    sl.Insert(1, '; LEV-File');
277
    {$ENDREGION}
278
  end;
279
 
280
  if (sl.Strings[0] = '; SpaceMission 0.4') and
281
     (sl.Strings[1] = '; LEV-File') then
282
  begin
283
    {$REGION 'Backwards compatibility level format 0.4 (convert to 1.0)'}
284
    sl2 := TStringList.Create;
285
    try
286
      z := 0;
287
      act := 0;
288
      while z < sl.Count do
289
      begin
290
        inc(z);
291
        if z > 2 then inc(act);
292
        if act = 5 then act := 1;
293
        ergebnis := sl.Strings[z-1];
294
        if ergebnis = '; SpaceMission 0.4' then
295
          sl2.Add('; SpaceMission 1.0')
296
        else
297
        begin
298
          if (ergebnis = '30000') and (z = 3) then
299
            sl2.Add(IntTostr(DefaultLevelLength))
300
          else
301
          begin
302
            //if not (((ergebnis = '0') and (z = 4)) or ((ergebnis = '-624') and (z = 5)) or ((ergebnis = '222') and (z = 6)) or ((ergebnis = '3') and (z = 7))) then
303
            if (z < 4) or (z > 7) then
304
            begin
305
              if act = 4 then
306
                sl2.Add(inttostr(strtoint(ergebnis) + 32 - (5 * (strtoint(ergebnis) div 37))))
307
              else
308
                sl2.Add(Ergebnis);
309
            end;
310
          end;
311
        end;
312
      end;
313
      sl.Text := sl2.Text;
314
    finally
315
      FreeAndNil(sl2);
316
    end;
317
    {$ENDREGION}
318
  end;
319
 
320
  if (sl.Strings[0] = '; SpaceMission 1.0') and
321
     (sl.Strings[1] = '; LEV-File') then
322
  begin
323
    {$REGION 'Level format 1.0'}
324
    LevelEditorLength := StrToInt(sl.Strings[2]);
325
    curline := 3;
326
    while curline < sl.Count do
327
    begin
328
      tmpEnemy := TEnemyType(strtoint(sl.Strings[curline]));
329
      Inc(curline);
330
      tmpX := strtoint(sl.Strings[curline]);
331
      Inc(curline);
332
      tmpY := strtoint(sl.Strings[curline]);
333
      Inc(curline);
334
      tmpLifes := strtoint(sl.Strings[curline]);
335
      Inc(curline);
336
      AddEnemy(tmpX, tmpY, tmpEnemy, tmpLifes);
337
    end;
338
    {$ENDREGION}
339
  end
340
  else if (SameText(sl.Strings[0], '[SpaceMission Level, Format 1.2]')) or
341
          (SameText(sl.Strings[0], '[SpaceMission Savegame, Format 1.2]')) then
342
  begin
343
    {$REGION 'Level format 1.2'}
344
    for curline := 1 to sl.Count-1 do
345
    begin
346
      // 1234567890123456789012345678901234567890
347
      // 123456 123456 123456 123456 123456 ; Kommentar
348
      if (sl.Strings[curline].Trim = '') or
349
         (Copy(sl.Strings[curline], 1, 1) = ';') then
350
        // Do nothing
351
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Width' then
352
      begin
353
        LevelEditorLength := StrToInt(TrimRight(Copy(sl.Strings[curline], 8, 6)))
354
      end
42 daniel-mar 355
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Name' then
356
      begin
357
        LevelName := TrimRight(Copy(sl.Strings[curline], 8, Length(sl.Strings[curline])))
358
      end
359
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Author' then
360
      begin
361
        LevelAuthor := TrimRight(Copy(sl.Strings[curline], 8, Length(sl.Strings[curline])))
362
      end
40 daniel-mar 363
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Enemy' then
364
      begin
365
        tmpEnemy := TEnemyType(strtoint(TrimRight(Copy(sl.Strings[curline], 8, 6))));
366
        tmpX     := strtoint(TrimRight(Copy(sl.Strings[curline], 15, 6)));
367
        tmpY     := strtoint(TrimRight(Copy(sl.Strings[curline], 22, 6)));
368
        tmpLifes := strtoint(TrimRight(Copy(sl.Strings[curline], 29, 6)));
369
        tmpRest  := Copy(sl.Strings[curline], 36, Length(sl.Strings[curline])-36+1);
370
        if (Copy(tmpRest, 1, 1) <> ';') and (Trim(tmpRest) <> '') then
371
          raise Exception.CreateFmt('Zeile %d ist ungültig (Zusatzinfo am Ende)', [curline+1]);
372
        AddEnemy(tmpX, tmpY, tmpEnemy, tmpLifes);
373
      end;
374
    end;
375
    {$ENDREGION}
376
  end
377
  else
378
  begin
379
    raise Exception.Create('Level-Format nicht unterstützt oder Datei ist beschädigt');
380
  end;
381
 
382
  SortEnemies; // Sortierung nach X-Koordinate ist sehr wichtig für das Spiel!
383
end;
384
 
385
procedure TLevelData.LoadFromFile(filename: string);
386
var
387
  sl: TStringList;
388
  i, j: integer;
389
  temp: string;
390
  m: array[1..6] of tstrings;
391
begin
15 daniel-mar 392
  sl := TStringList.Create;
14 daniel-mar 393
  try
17 daniel-mar 394
    if EndsText('A1.lev', filename) then
395
    begin
30 daniel-mar 396
      {$REGION 'Backwards compatibility level format 0.2 (split into 5-6 files; convert to 0.3)'}
17 daniel-mar 397
      m[1] := TStringList.create;
398
      m[2] := TStringList.create;
399
      m[3] := TStringList.create;
400
      m[4] := TStringList.create;
401
      m[5] := TStringList.create;
402
      m[6] := TStringList.create;
403
      try
404
        for i := 1 to 6 do
405
        begin
406
          filename[Length(filename)-4] := IntToStr(i)[1]; // ...A2.sav, ...A3.sav, etc.
407
          if FileExists(filename) then
408
            m[i].loadfromfile(filename);
409
        end;
410
        m[1].strings[0] := '-624';
411
        if m[6].Text = '' then m[6].Text := '30000';
14 daniel-mar 412
 
17 daniel-mar 413
        sl.Add('; SpaceMission 0.3');
414
        sl.Add(temp);
415
        for j := 0 to m[1].count-2 do
416
        begin
417
          for i := 0 to m[1].count-2 do
418
          begin
419
            if strtoint(m[1].strings[i]) > strtoint(m[1].strings[i+1]) then
420
            begin
421
              m[1].exchange(i, i+1);
422
              m[2].exchange(i, i+1);
423
              m[3].exchange(i, i+1);
424
              m[4].exchange(i, i+1);
425
              m[5].exchange(i, i+1);
426
            end;
427
          end;
428
        end;
429
        for i := 0 to m[3].count-1 do
430
        begin
431
          for j := 1 to 4 do
432
          begin
433
            if j = 1 then sl.Add(m[3].strings[i]);
434
            if j = 2 then sl.Add(m[1].strings[i]);
435
            if j = 3 then sl.Add(m[2].strings[i]);
436
            if j = 4 then sl.Add(m[4].strings[i]);
437
          end;
438
        end;
439
      finally
440
        FreeAndNil(m[1]);
441
        FreeAndNil(m[2]);
442
        FreeAndNil(m[3]);
443
        FreeAndNil(m[4]);
444
        FreeAndNil(m[5]);
445
        FreeAndNil(m[6]);
446
      end;
447
      {$ENDREGION}
448
    end
449
    else
14 daniel-mar 450
    begin
17 daniel-mar 451
      sl.LoadFromFile(filename);
452
    end;
453
 
40 daniel-mar 454
    LoadFromStrings(sl);
14 daniel-mar 455
  finally
15 daniel-mar 456
    FreeAndNil(sl);
14 daniel-mar 457
  end;
458
end;
459
 
40 daniel-mar 460
procedure TLevelData.SaveToStrings(sl: TStrings);
15 daniel-mar 461
var
462
  i: integer;
14 daniel-mar 463
begin
40 daniel-mar 464
  sl.Clear;
465
  sl.Add('[SpaceMission Level, Format 1.2]');
42 daniel-mar 466
  if LevelName   <> '' then sl.Add('Name   ' + LevelName);
467
  if LevelAuthor <> '' then sl.Add('Author ' + LevelAuthor);
43 daniel-mar 468
  sl.Add('Width  ' + IntToStr(LevelEditorLength));
40 daniel-mar 469
  SortEnemies;
48 daniel-mar 470
  sl.Add(';      Type   XCoord YCoord Lives');
40 daniel-mar 471
  for i := 0 to Length(EnemyAdventTable)-1 do
472
  begin
30 daniel-mar 473
    sl.Add(
40 daniel-mar 474
      'Enemy'.PadRight(6, ' ')+
30 daniel-mar 475
      ' '+
40 daniel-mar 476
      IntToStr(Ord(EnemyAdventTable[i].enemyType)).PadRight(6, ' ')+
477
      ' '+
478
      IntToStr(EnemyAdventTable[i].x).PadRight(6, ' ')+
479
      ' '+
480
      IntToStr(EnemyAdventTable[i].y).PadRight(6, ' ')+
481
      ' '+
482
      IntToStr(EnemyAdventTable[i].lifes).PadRight(6, ' ')+
30 daniel-mar 483
      ' '
484
    );
40 daniel-mar 485
  end;
486
end;
487
 
488
procedure TLevelData.SaveToFile(filename: string);
489
var
490
  sl: TStringList;
491
begin
492
  sl := TStringList.Create;
493
  try
494
    SaveToStrings(sl);
15 daniel-mar 495
    sl.SaveToFile(filename);
496
  finally
497
    FreeAndNil(sl);
498
  end;
14 daniel-mar 499
end;
500
 
27 daniel-mar 501
procedure TLevelData.SortEnemies;
502
var
503
  i, n: integer;
504
  e: TEnemyAdvent;
505
begin
506
  // Bubble Sort Algorithmus
507
  for n := Length(EnemyAdventTable) downto 2 do
508
  begin
509
    for i := 0 to n - 2 do
510
    begin
511
      if
512
        // Sort by X-coord (important for the game!)
513
        (EnemyAdventTable[i].x > EnemyAdventTable[i+1].x)
514
        or
515
        // Sort by Y-coord (just cosmetics)
516
        ((EnemyAdventTable[i].x = EnemyAdventTable[i+1].x) and (EnemyAdventTable[i].y > EnemyAdventTable[i+1].y))
517
      then
518
      begin
519
        e := EnemyAdventTable[i];
520
        EnemyAdventTable[i] := EnemyAdventTable[i + 1];
521
        EnemyAdventTable[i + 1] := e;
522
      end;
523
    end;
524
  end;
525
end;
526
 
40 daniel-mar 527
{ TSaveData }
528
 
529
procedure TSaveData.AssignTo(Dest: TPersistent);
530
var
531
  DestSaveData: TSaveData;
532
begin
533
  DestSaveData := Dest as TSaveData;
534
  if Assigned(DestSaveData) then
535
  begin
536
    DestSaveData.Score := Self.Score;
537
    DestSaveData.Life := Self.Life;
538
    DestSaveData.Level := Self.Level;
539
    DestSaveData.GameMode := Self.GameMode;
540
    if not Assigned(DestSaveData.LevelData) then DestSaveData.LevelData := TLevelData.Create;
541
    DestSaveData.LevelData.Assign(Self.LevelData);
542
  end
543
  else
544
  begin
545
    inherited;
546
  end;
547
end;
548
 
549
procedure TSaveData.Clear;
550
begin
551
  Score := 0;
552
  Life := 0;
553
  Level := 0;
554
  GameMode := gmUnknown;
555
  FreeAndNil(LevelData);
556
end;
557
 
558
destructor TSaveData.Destroy;
559
begin
560
  Clear;
561
  inherited;
562
end;
563
 
564
procedure TSaveData.SaveToStrings(sl: TStrings);
565
var
566
  sl2: TStringList;
567
begin
568
  sl2 := TStringList.Create;
569
  try
570
    sl.Add('[SpaceMission Savegame, Format 1.2]');
571
    sl.Add('Score  ' + IntToStr(Score));
572
    sl.Add('Lives  ' + IntToStr(Life));
573
    sl.Add('Level  ' + IntToStr(Level));
574
    sl.Add('Mode   ' + IntToStr(Ord(GameMode)));
575
    LevelData.SaveToStrings(sl2);
576
    sl2.Delete(0); // Signature
577
    sl.AddStrings(sl2);
578
  finally
579
    FreeAndNil(sl2);
580
  end;
581
end;
582
 
583
procedure TSaveData.LoadFromStrings(sl: TStrings);
584
var
585
  curline: Integer;
586
begin
587
  if (sl.Strings[0] = '; SpaceMission 1.0') and
588
     (sl.Strings[1] = '; SAV-File') then
589
  begin
590
    Score    := StrToInt(sl.Strings[2]);
591
    Life     := StrToInt(sl.Strings[3]);
592
    Level    := StrToInt(sl.Strings[4]);
593
    GameMode := TGameMode(StrToInt(sl.Strings[5]));
594
    if Assigned(LevelData) then FreeAndNil(LevelData);
595
  end
596
  else if SameText(sl.Strings[0], '[SpaceMission Savegame, Format 1.2]') then
597
  begin
598
    Score    := 0;
599
    Life     := 0;
600
    Level    := 0;
601
    GameMode := gmUnknown;
602
    for curline := 1 to sl.Count-1 do
603
    begin
604
      // 1234567890123456789012345678901234567890
605
      // 123456 123456 123456 123456 123456 ; Kommentar
606
      if (sl.Strings[curline].Trim = '') or
607
         (Copy(sl.Strings[curline], 1, 1) = ';') then
608
        // Do nothing
609
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Score' then
610
      begin
611
        Score := StrToInt(TrimRight(Copy(sl.Strings[curline], 8, 6)))
612
      end
613
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Lives' then
614
      begin
615
        Life := StrToInt(TrimRight(Copy(sl.Strings[curline], 8, 6)))
616
      end
617
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Level' then
618
      begin
619
        Level := StrToInt(TrimRight(Copy(sl.Strings[curline], 8, 6)))
620
      end
621
      else if Copy(sl.Strings[curline], 1, 6).TrimRight = 'Mode' then
622
      begin
623
        GameMode := TGameMode(StrToInt(TrimRight(Copy(sl.Strings[curline], 8, 6))))
624
      end;
625
    end;
626
    if Assigned(LevelData) then FreeAndNil(LevelData);
627
    LevelData := TLevelData.Create;
44 daniel-mar 628
    LevelData.RasterErzwingen := false;
40 daniel-mar 629
    LevelData.LoadFromStrings(sl);
630
  end
631
  else
632
  begin
633
    raise Exception.Create('Spielstand-Format nicht unterstützt oder Datei beschädigt');
634
  end;
635
end;
636
 
637
procedure TSaveData.LoadFromFile(filename: string);
638
var
639
  sl: TStringList;
640
begin
641
  sl := TStringList.Create;
642
  try
643
    sl.LoadFromFile(filename);
644
    LoadFromStrings(sl);
645
  finally
646
    FreeAndNil(sl);
647
  end;
648
end;
649
 
650
procedure TSaveData.SaveToFile(filename: string);
651
var
652
  sl: TStringList;
653
begin
654
  sl := TStringList.Create;
655
  try
656
    SaveToStrings(sl);
657
    sl.SaveToFile(filename);
658
  finally
659
    FreeAndNil(sl);
660
  end;
661
end;
662
 
14 daniel-mar 663
end.