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