DEADSOFTWARE

no more old mapreader: use textmap reader both for text and for binary maps
[d2df-sdl.git] / src / game / g_saveload.pas
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 unit g_saveload;
19 interface
21 uses
22 e_graphics, g_phys, g_textures, BinEditor;
24 function g_GetSaveName(n: Integer): String;
25 function g_SaveGame(n: Integer; Name: String): Boolean;
26 function g_LoadGame(n: Integer): Boolean;
27 procedure Obj_SaveState(o: PObj; var Mem: TBinMemoryWriter);
28 procedure Obj_LoadState(o: PObj; var Mem: TBinMemoryReader);
30 type
31 TLoadSaveHook = procedure ();
33 procedure g_SetPreLoadHook (ahook: TLoadSaveHook);
34 procedure g_SetPostLoadHook (ahook: TLoadSaveHook);
36 procedure g_CallPreLoadHooks ();
37 procedure g_CallPostLoadHooks ();
40 implementation
42 uses
43 g_game, g_items, g_map, g_monsters, g_triggers,
44 g_basic, g_main, SysUtils, Math, wadreader,
45 MAPDEF, g_weapons, g_player, g_console,
46 e_log, g_language;
48 const
49 SAVE_SIGNATURE = $56534644; // 'DFSV'
50 SAVE_VERSION = $03;
51 END_MARKER_STRING = 'END';
52 PLAYER_VIEW_SIGNATURE = $57564C50; // 'PLVW'
53 OBJ_SIGNATURE = $4A424F5F; // '_OBJ'
56 var
57 preloadHooks: array of TLoadSaveHook = nil;
58 postloadHooks: array of TLoadSaveHook = nil;
61 procedure g_SetPreLoadHook (ahook: TLoadSaveHook);
62 begin
63 if not assigned(ahook) then exit;
64 SetLength(preloadHooks, Length(preloadHooks)+1);
65 preloadHooks[High(preloadHooks)] := ahook;
66 end;
69 procedure g_SetPostLoadHook (ahook: TLoadSaveHook);
70 begin
71 if not assigned(ahook) then exit;
72 SetLength(postloadHooks, Length(postloadHooks)+1);
73 postloadHooks[High(postloadHooks)] := ahook;
74 end;
77 procedure g_CallPreLoadHooks ();
78 var
79 f: Integer;
80 begin
81 for f := 0 to High(preloadHooks) do preloadHooks[f]();
82 end;
85 procedure g_CallPostLoadHooks ();
86 var
87 f: Integer;
88 begin
89 for f := 0 to High(postloadHooks) do postloadHooks[f]();
90 end;
93 procedure Obj_SaveState(o: PObj; var Mem: TBinMemoryWriter);
94 var
95 sig: DWORD;
96 begin
97 if Mem = nil then
98 Exit;
100 // Ñèãíàòóðà îáúåêòà:
101 sig := OBJ_SIGNATURE; // '_OBJ'
102 Mem.WriteDWORD(sig);
103 // Ïîëîæåíèå ïî-ãîðèçîíòàëè:
104 Mem.WriteInt(o^.X);
105 // Ïîëîæåíèå ïî-âåðòèêàëè:
106 Mem.WriteInt(o^.Y);
107 // Îãðàíè÷èâàþùèé ïðÿìîóãîëüíèê:
108 Mem.WriteInt(o^.Rect.X);
109 Mem.WriteInt(o^.Rect.Y);
110 Mem.WriteWord(o^.Rect.Width);
111 Mem.WriteWord(o^.Rect.Height);
112 // Ñêîðîñòü:
113 Mem.WriteInt(o^.Vel.X);
114 Mem.WriteInt(o^.Vel.Y);
115 // Ïðèáàâêà ê ñêîðîñòè:
116 Mem.WriteInt(o^.Accel.X);
117 Mem.WriteInt(o^.Accel.Y);
118 end;
120 procedure Obj_LoadState(o: PObj; var Mem: TBinMemoryReader);
121 var
122 sig: DWORD;
123 begin
124 if Mem = nil then
125 Exit;
127 // Ñèãíàòóðà îáúåêòà:
128 Mem.ReadDWORD(sig);
129 if sig <> OBJ_SIGNATURE then // '_OBJ'
130 begin
131 raise EBinSizeError.Create('Obj_LoadState: Wrong Object Signature');
132 end;
133 // Ïîëîæåíèå ïî-ãîðèçîíòàëè:
134 Mem.ReadInt(o^.X);
135 // Ïîëîæåíèå ïî-âåðòèêàëè:
136 Mem.ReadInt(o^.Y);
137 // Îãðàíè÷èâàþùèé ïðÿìîóãîëüíèê:
138 Mem.ReadInt(o^.Rect.X);
139 Mem.ReadInt(o^.Rect.Y);
140 Mem.ReadWord(o^.Rect.Width);
141 Mem.ReadWord(o^.Rect.Height);
142 // Ñêîðîñòü:
143 Mem.ReadInt(o^.Vel.X);
144 Mem.ReadInt(o^.Vel.Y);
145 // Ïðèáàâêà ê ñêîðîñòè:
146 Mem.ReadInt(o^.Accel.X);
147 Mem.ReadInt(o^.Accel.Y);
148 end;
150 function g_GetSaveName(n: Integer): String;
151 var
152 bFile: TBinFileReader;
153 bMem: TBinMemoryReader;
154 str: String;
155 begin
156 Result := '';
157 str := '';
158 bMem := nil;
159 bFile := nil;
161 try
162 // Îòêðûâàåì ôàéë ñîõðàíåíèé:
163 bFile := TBinFileReader.Create();
164 if bFile.OpenFile(DataDir + 'SAVGAME' + IntToStr(n) + '.DAT',
165 SAVE_SIGNATURE, SAVE_VERSION) then
166 begin
167 // ×èòàåì ïåðâûé áëîê - ñîñòîÿíèå èãðû:
168 bMem := TBinMemoryReader.Create();
169 bFile.ReadMemory(bMem);
170 // Èìÿ èãðû:
171 bMem.ReadString(str);
173 // Çàêðûâàåì ôàéë:
174 bFile.Close();
175 end;
177 except
178 on E1: EInOutError do
179 e_WriteLog('GetSaveName I/O Error: '+E1.Message, MSG_WARNING);
180 on E2: EBinSizeError do
181 e_WriteLog('GetSaveName Size Error: '+E2.Message, MSG_WARNING);
182 end;
184 bMem.Free();
185 bFile.Free();
187 Result := str;
188 end;
190 function g_SaveGame(n: Integer; Name: String): Boolean;
191 var
192 bFile: TBinFileWriter;
193 bMem: TBinMemoryWriter;
194 sig: DWORD;
195 str: String;
196 nPlayers: Byte;
197 i, k: Integer;
198 PID1, PID2: Word;
199 begin
200 Result := False;
201 bMem := nil;
202 bFile := nil;
204 try
205 // Ñîçäàåì ôàéë ñîõðàíåíèÿ:
206 bFile := TBinFileWriter.Create();
207 bFile.OpenFile(DataDir + 'SAVGAME' + IntToStr(n) + '.DAT',
208 SAVE_SIGNATURE, SAVE_VERSION);
210 ///// Ïîëó÷àåì ñîñòîÿíèå èãðû: /////
211 bMem := TBinMemoryWriter.Create(256);
212 // Èìÿ èãðû:
213 bMem.WriteString(Name, 32);
214 // Ïóòü ê êàðòå:
215 str := gGameSettings.WAD;
216 bMem.WriteString(str, 128);
217 // Èìÿ êàðòû:
218 str := g_ExtractFileName(gMapInfo.Map);
219 bMem.WriteString(str, 32);
220 // Êîëè÷åñòâî èãðîêîâ:
221 nPlayers := g_Player_GetCount();
222 bMem.WriteByte(nPlayers);
223 // Èãðîâîå âðåìÿ:
224 bMem.WriteDWORD(gTime);
225 // Òèï èãðû:
226 bMem.WriteByte(gGameSettings.GameType);
227 // Ðåæèì èãðû:
228 bMem.WriteByte(gGameSettings.GameMode);
229 // Ëèìèò âðåìåíè:
230 bMem.WriteWord(gGameSettings.TimeLimit);
231 // Ëèìèò î÷êîâ:
232 bMem.WriteWord(gGameSettings.GoalLimit);
233 // Ëèìèò æèçíåé:
234 bMem.WriteByte(gGameSettings.MaxLives);
235 // Èãðîâûå îïöèè:
236 bMem.WriteDWORD(gGameSettings.Options);
237 // Äëÿ êîîïà:
238 bMem.WriteWord(gCoopMonstersKilled);
239 bMem.WriteWord(gCoopSecretsFound);
240 bMem.WriteWord(gCoopTotalMonstersKilled);
241 bMem.WriteWord(gCoopTotalSecretsFound);
242 bMem.WriteWord(gCoopTotalMonsters);
243 bMem.WriteWord(gCoopTotalSecrets);
244 // Ñîõðàíÿåì ñîñòîÿíèå èãðû:
245 bFile.WriteMemory(bMem);
246 bMem.Free();
247 bMem := nil;
248 ///// /////
250 ///// Ñîõðàíÿåì ñîñòîÿíèå îáëàñòåé ïðîñìîòðà: /////
251 bMem := TBinMemoryWriter.Create(8);
252 sig := PLAYER_VIEW_SIGNATURE;
253 bMem.WriteDWORD(sig); // 'PLVW'
254 PID1 := 0;
255 PID2 := 0;
256 if gPlayer1 <> nil then
257 PID1 := gPlayer1.UID;
258 if gPlayer2 <> nil then
259 PID2 := gPlayer2.UID;
260 bMem.WriteWord(PID1);
261 bMem.WriteWord(PID2);
262 bFile.WriteMemory(bMem);
263 bMem.Free();
264 bMem := nil;
265 ///// /////
267 ///// Ïîëó÷àåì ñîñòîÿíèå êàðòû: /////
268 g_Map_SaveState(bMem);
269 // Ñîõðàíÿåì ñîñòîÿíèå êàðòû:
270 bFile.WriteMemory(bMem);
271 bMem.Free();
272 bMem := nil;
273 ///// /////
275 ///// Ïîëó÷àåì ñîñòîÿíèå ïðåäìåòîâ: /////
276 g_Items_SaveState(bMem);
277 // Ñîõðàíÿåì ñîñòîÿíèå ïðåäìåòîâ:
278 bFile.WriteMemory(bMem);
279 bMem.Free();
280 bMem := nil;
281 ///// /////
283 ///// Ïîëó÷àåì ñîñòîÿíèå òðèããåðîâ: /////
284 g_Triggers_SaveState(bMem);
285 // Ñîõðàíÿåì ñîñòîÿíèå òðèããåðîâ:
286 bFile.WriteMemory(bMem);
287 bMem.Free();
288 bMem := nil;
289 ///// /////
291 ///// Ïîëó÷àåì ñîñòîÿíèå îðóæèÿ: /////
292 g_Weapon_SaveState(bMem);
293 // Ñîõðàíÿåì ñîñòîÿíèå îðóæèÿ:
294 bFile.WriteMemory(bMem);
295 bMem.Free();
296 bMem := nil;
297 ///// /////
299 ///// Ïîëó÷àåì ñîñòîÿíèå ìîíñòðîâ: /////
300 g_Monsters_SaveState(bMem);
301 // Ñîõðàíÿåì ñîñòîÿíèå ìîíñòðîâ:
302 bFile.WriteMemory(bMem);
303 bMem.Free();
304 bMem := nil;
305 ///// /////
307 ///// Ïîëó÷àåì ñîñòîÿíèå òðóïîâ: /////
308 g_Player_Corpses_SaveState(bMem);
309 // Ñîõðàíÿåì ñîñòîÿíèå òðóïîâ:
310 bFile.WriteMemory(bMem);
311 bMem.Free();
312 bMem := nil;
313 ///// /////
315 ///// Ñîõðàíÿåì èãðîêîâ (â òîì ÷èñëå áîòîâ): /////
316 if nPlayers > 0 then
317 begin
318 k := 0;
319 for i := 0 to High(gPlayers) do
320 if gPlayers[i] <> nil then
321 begin
322 // Ïîëó÷àåì ñîñòîÿíèå èãðîêà:
323 gPlayers[i].SaveState(bMem);
324 // Ñîõðàíÿåì ñîñòîÿíèå èãðîêà:
325 bFile.WriteMemory(bMem);
326 bMem.Free();
327 bMem := nil;
328 Inc(k);
329 end;
331 // Âñå ëè èãðîêè íà ìåñòå:
332 if k <> nPlayers then
333 begin
334 raise EInOutError.Create('g_SaveGame: Wrong Players Count');
335 end;
336 end;
337 ///// /////
339 ///// Ìàðêåð îêîí÷àíèÿ: /////
340 bMem := TBinMemoryWriter.Create(4);
341 // Ñòðîêà - îáîçíà÷åíèå êîíöà:
342 str := END_MARKER_STRING; // 'END'
343 bMem.WriteString(str, 3);
344 // Ñîõðàíÿåì ìàðêåð îêîí÷àíèÿ:
345 bFile.WriteMemory(bMem);
346 bMem.Free();
347 bMem := nil;
348 ///// /////
350 // Çàêðûâàåì ôàéë ñîõðàíåíèÿ:
351 bFile.Close();
352 Result := True;
354 except
355 on E1: EInOutError do
356 begin
357 g_Console_Add(_lc[I_GAME_ERROR_SAVE]);
358 e_WriteLog('SaveState I/O Error: '+E1.Message, MSG_WARNING);
359 end;
360 on E2: EBinSizeError do
361 begin
362 g_Console_Add(_lc[I_GAME_ERROR_SAVE]);
363 e_WriteLog('SaveState Size Error: '+E2.Message, MSG_WARNING);
364 end;
365 end;
367 bMem.Free();
368 bFile.Free();
369 end;
371 function g_LoadGame(n: Integer): Boolean;
372 var
373 bFile: TBinFileReader;
374 bMem: TBinMemoryReader;
375 sig: DWORD;
376 str, WAD_Path, Map_Name: String;
377 nPlayers, Game_Type, Game_Mode, Game_MaxLives: Byte;
378 Game_TimeLimit, Game_GoalLimit: Word;
379 Game_Time, Game_Options: Cardinal;
380 Game_CoopMonstersKilled,
381 Game_CoopSecretsFound,
382 Game_CoopTotalMonstersKilled,
383 Game_CoopTotalSecretsFound,
384 Game_CoopTotalMonsters,
385 Game_CoopTotalSecrets,
386 PID1, PID2: Word;
387 i: Integer;
388 begin
389 Result := False;
390 bMem := nil;
391 bFile := nil;
393 try
394 // Îòêðûâàåì ôàéë ñ ñîõðàíåíèåì:
395 bFile := TBinFileReader.Create();
396 if not bFile.OpenFile(DataDir + 'SAVGAME' + IntToStr(n) + '.DAT',
397 SAVE_SIGNATURE, SAVE_VERSION) then
398 begin
399 bFile.Free();
400 Exit;
401 end;
403 e_WriteLog('Loading saved game...', MSG_NOTIFY);
404 g_Game_Free();
406 g_Game_ClearLoading();
407 g_Game_SetLoadingText(_lc[I_LOAD_SAVE_FILE], 0, False);
408 gLoadGameMode := True;
410 g_CallPreLoadHooks();
412 ///// Çàãðóæàåì ñîñòîÿíèå èãðû: /////
413 bMem := TBinMemoryReader.Create();
414 bFile.ReadMemory(bMem);
415 // Èìÿ èãðû:
416 bMem.ReadString(str);
417 // Ïóòü ê êàðòå:
418 bMem.ReadString(WAD_Path);
419 // Èìÿ êàðòû:
420 bMem.ReadString(Map_Name);
421 // Êîëè÷åñòâî èãðîêîâ:
422 bMem.ReadByte(nPlayers);
423 // Èãðîâîå âðåìÿ:
424 bMem.ReadDWORD(Game_Time);
425 // Òèï èãðû:
426 bMem.ReadByte(Game_Type);
427 // Ðåæèì èãðû:
428 bMem.ReadByte(Game_Mode);
429 // Ëèìèò âðåìåíè:
430 bMem.ReadWord(Game_TimeLimit);
431 // Ëèìèò î÷êîâ:
432 bMem.ReadWord(Game_GoalLimit);
433 // Ëèìèò æèçíåé:
434 bMem.ReadByte(Game_MaxLives);
435 // Èãðîâûå îïöèè:
436 bMem.ReadDWORD(Game_Options);
437 // Äëÿ êîîïà:
438 bMem.ReadWord(Game_CoopMonstersKilled);
439 bMem.ReadWord(Game_CoopSecretsFound);
440 bMem.ReadWord(Game_CoopTotalMonstersKilled);
441 bMem.ReadWord(Game_CoopTotalSecretsFound);
442 bMem.ReadWord(Game_CoopTotalMonsters);
443 bMem.ReadWord(Game_CoopTotalSecrets);
444 // Cîñòîÿíèå èãðû çàãðóæåíî:
445 bMem.Free();
446 bMem := nil;
447 ///// /////
449 ///// Çàãðóæàåì ñîñòîÿíèå îáëàñòåé ïðîñìîòðà: /////
450 bMem := TBinMemoryReader.Create();
451 bFile.ReadMemory(bMem);
452 bMem.ReadDWORD(sig);
453 if sig <> PLAYER_VIEW_SIGNATURE then // 'PLVW'
454 begin
455 raise EInOutError.Create('g_LoadGame: Wrong Player View Signature');
456 end;
457 bMem.ReadWord(PID1);
458 bMem.ReadWord(PID2);
459 bMem.Free();
460 bMem := nil;
461 ///// /////
463 // Çàãðóæàåì êàðòó:
464 ZeroMemory(@gGameSettings, SizeOf(TGameSettings));
465 gAimLine := False;
466 gShowMap := False;
467 if (Game_Type = GT_NONE) or (Game_Type = GT_SINGLE) then
468 begin
469 // Íàñòðîéêè èãðû:
470 gGameSettings.GameType := GT_SINGLE;
471 gGameSettings.MaxLives := 0;
472 gGameSettings.Options := gGameSettings.Options + GAME_OPTION_ALLOWEXIT;
473 gGameSettings.Options := gGameSettings.Options + GAME_OPTION_MONSTERS;
474 gGameSettings.Options := gGameSettings.Options + GAME_OPTION_BOTVSMONSTER;
475 gSwitchGameMode := GM_SINGLE;
476 end
477 else
478 begin
479 // Íàñòðîéêè èãðû:
480 gGameSettings.GameType := GT_CUSTOM;
481 gGameSettings.GameMode := Game_Mode;
482 gSwitchGameMode := Game_Mode;
483 gGameSettings.TimeLimit := Game_TimeLimit;
484 gGameSettings.GoalLimit := Game_GoalLimit;
485 gGameSettings.MaxLives := IfThen(Game_Mode = GM_CTF, 0, Game_MaxLives);
486 gGameSettings.Options := Game_Options;
487 end;
488 g_Game_ExecuteEvent('ongamestart');
490 // Óñòàíîâêà ðàçìåðîâ îêîí èãðîêîâ:
491 g_Game_SetupScreenSize();
493 // Çàãðóçêà è çàïóñê êàðòû:
494 if not g_Game_StartMap(WAD_Path + ':\' + Map_Name, True) then
495 begin
496 g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [WAD_Path + ':\' + Map_Name]));
497 Exit;
498 end;
500 // Íàñòðîéêè èãðîêîâ è áîòîâ:
501 g_Player_Init();
503 // Óñòàíàâëèâàåì âðåìÿ:
504 gTime := Game_Time;
505 // Âîçâðàùàåì ñòàòû:
506 gCoopMonstersKilled := Game_CoopMonstersKilled;
507 gCoopSecretsFound := Game_CoopSecretsFound;
508 gCoopTotalMonstersKilled := Game_CoopTotalMonstersKilled;
509 gCoopTotalSecretsFound := Game_CoopTotalSecretsFound;
510 gCoopTotalMonsters := Game_CoopTotalMonsters;
511 gCoopTotalSecrets := Game_CoopTotalSecrets;
513 ///// Çàãðóæàåì ñîñòîÿíèå êàðòû: /////
514 bMem := TBinMemoryReader.Create();
515 bFile.ReadMemory(bMem);
516 // Ñîñòîÿíèå êàðòû:
517 g_Map_LoadState(bMem);
518 bMem.Free();
519 bMem := nil;
520 ///// /////
522 ///// Çàãðóæàåì ñîñòîÿíèå ïðåäìåòîâ: /////
523 bMem := TBinMemoryReader.Create();
524 bFile.ReadMemory(bMem);
525 // Ñîñòîÿíèå ïðåäìåòîâ:
526 g_Items_LoadState(bMem);
527 bMem.Free();
528 bMem := nil;
529 ///// /////
531 ///// Çàãðóæàåì ñîñòîÿíèå òðèããåðîâ: /////
532 bMem := TBinMemoryReader.Create();
533 bFile.ReadMemory(bMem);
534 // Ñîñòîÿíèå òðèããåðîâ:
535 g_Triggers_LoadState(bMem);
536 bMem.Free();
537 bMem := nil;
538 ///// /////
540 ///// Çàãðóæàåì ñîñòîÿíèå îðóæèÿ: /////
541 bMem := TBinMemoryReader.Create();
542 bFile.ReadMemory(bMem);
543 // Ñîñòîÿíèå îðóæèÿ:
544 g_Weapon_LoadState(bMem);
545 bMem.Free();
546 bMem := nil;
547 ///// /////
549 ///// Çàãðóæàåì ñîñòîÿíèå ìîíñòðîâ: /////
550 bMem := TBinMemoryReader.Create();
551 bFile.ReadMemory(bMem);
552 // Ñîñòîÿíèå ìîíñòðîâ:
553 g_Monsters_LoadState(bMem);
554 bMem.Free();
555 bMem := nil;
556 ///// /////
558 ///// Çàãðóæàåì ñîñòîÿíèå òðóïîâ: /////
559 bMem := TBinMemoryReader.Create();
560 bFile.ReadMemory(bMem);
561 // Ñîñòîÿíèå òðóïîâ:
562 g_Player_Corpses_LoadState(bMem);
563 bMem.Free();
564 bMem := nil;
565 ///// /////
567 ///// Çàãðóæàåì èãðîêîâ (â òîì ÷èñëå áîòîâ): /////
568 if nPlayers > 0 then
569 begin
570 // Çàãðóæàåì:
571 for i := 0 to nPlayers-1 do
572 begin
573 // Çàãðóæàåì ñîñòîÿíèå èãðîêà:
574 bMem := TBinMemoryReader.Create();
575 bFile.ReadMemory(bMem);
576 // Ñîñòîÿíèå èãðîêà/áîòà:
577 g_Player_CreateFromState(bMem);
578 bMem.Free();
579 bMem := nil;
580 end;
581 end;
582 // Ïðèâÿçûâàåì îñíîâíûõ èãðîêîâ ê îáëàñòÿì ïðîñìîòðà:
583 gPlayer1 := g_Player_Get(PID1);
584 gPlayer2 := g_Player_Get(PID2);
585 if gPlayer1 <> nil then
586 begin
587 gPlayer1.Name := gPlayer1Settings.Name;
588 gPlayer1.FPreferredTeam := gPlayer1Settings.Team;
589 gPlayer1.FActualModelName := gPlayer1Settings.Model;
590 gPlayer1.SetModel(gPlayer1.FActualModelName);
591 gPlayer1.SetColor(gPlayer1Settings.Color);
592 end;
593 if gPlayer2 <> nil then
594 begin
595 gPlayer2.Name := gPlayer2Settings.Name;
596 gPlayer2.FPreferredTeam := gPlayer2Settings.Team;
597 gPlayer2.FActualModelName := gPlayer2Settings.Model;
598 gPlayer2.SetModel(gPlayer2.FActualModelName);
599 gPlayer2.SetColor(gPlayer2Settings.Color);
600 end;
601 ///// /////
603 ///// Ìàðêåð îêîí÷àíèÿ: /////
604 bMem := TBinMemoryReader.Create();
605 bFile.ReadMemory(bMem);
606 // Ñòðîêà - îáîçíà÷åíèå êîíöà:
607 bMem.ReadString(str);
608 if str <> END_MARKER_STRING then // 'END'
609 begin
610 raise EInOutError.Create('g_LoadGame: No END Marker');
611 end;
612 // Ìàðêåð îêîí÷àíèÿ çàãðóæåí:
613 bMem.Free();
614 bMem := nil;
615 ///// /////
617 // Èùåì òðèããåðû ñ óñëîâèåì ñìåðòè ìîíñòðîâ:
618 if {(gMonsters <> nil) and} (gTriggers <> nil) then
619 g_Map_ReAdd_DieTriggers();
621 // Çàêðûâàåì ôàéë çàãðóçêè:
622 bFile.Close();
623 gLoadGameMode := False;
624 g_CallPostLoadHooks();
625 Result := True;
627 except
628 on E1: EInOutError do
629 begin
630 g_Console_Add(_lc[I_GAME_ERROR_LOAD]);
631 e_WriteLog('LoadState I/O Error: '+E1.Message, MSG_WARNING);
632 end;
633 on E2: EBinSizeError do
634 begin
635 g_Console_Add(_lc[I_GAME_ERROR_LOAD]);
636 e_WriteLog('LoadState Size Error: '+E2.Message, MSG_WARNING);
637 end;
638 end;
640 bMem.Free();
641 bFile.Free();
642 end;
644 end.