7 e_graphics
, g_phys
, g_textures
, BinEditor
;
9 function g_GetSaveName(n
: Integer): String;
10 function g_SaveGame(n
: Integer; Name
: String): Boolean;
11 function g_LoadGame(n
: Integer): Boolean;
12 procedure Obj_SaveState(o
: PObj
; var Mem
: TBinMemoryWriter
);
13 procedure Obj_LoadState(o
: PObj
; var Mem
: TBinMemoryReader
);
18 g_game
, g_items
, g_map
, g_monsters
, g_triggers
,
19 g_basic
, g_main
, SysUtils
, Math
, wadreader
,
20 MAPSTRUCT
, MAPDEF
, g_weapons
, g_player
, g_console
,
24 SAVE_SIGNATURE
= $56534644; // 'DFSV'
26 END_MARKER_STRING
= 'END';
27 PLAYER_VIEW_SIGNATURE
= $57564C50; // 'PLVW'
28 OBJ_SIGNATURE
= $4A424F5F; // '_OBJ'
30 procedure Obj_SaveState(o
: PObj
; var Mem
: TBinMemoryWriter
);
38 sig
:= OBJ_SIGNATURE
; // '_OBJ'
40 // Ïîëîæåíèå ïî-ãîðèçîíòàëè:
42 // Ïîëîæåíèå ïî-âåðòèêàëè:
44 // Îãðàíè÷èâàþùèé ïðÿìîóãîëüíèê:
45 Mem
.WriteInt(o
^.Rect
.X
);
46 Mem
.WriteInt(o
^.Rect
.Y
);
47 Mem
.WriteWord(o
^.Rect
.Width
);
48 Mem
.WriteWord(o
^.Rect
.Height
);
50 Mem
.WriteInt(o
^.Vel
.X
);
51 Mem
.WriteInt(o
^.Vel
.Y
);
52 // Ïðèáàâêà ê ñêîðîñòè:
53 Mem
.WriteInt(o
^.Accel
.X
);
54 Mem
.WriteInt(o
^.Accel
.Y
);
57 procedure Obj_LoadState(o
: PObj
; var Mem
: TBinMemoryReader
);
66 if sig
<> OBJ_SIGNATURE
then // '_OBJ'
68 raise EBinSizeError
.Create('Obj_LoadState: Wrong Object Signature');
70 // Ïîëîæåíèå ïî-ãîðèçîíòàëè:
72 // Ïîëîæåíèå ïî-âåðòèêàëè:
74 // Îãðàíè÷èâàþùèé ïðÿìîóãîëüíèê:
75 Mem
.ReadInt(o
^.Rect
.X
);
76 Mem
.ReadInt(o
^.Rect
.Y
);
77 Mem
.ReadWord(o
^.Rect
.Width
);
78 Mem
.ReadWord(o
^.Rect
.Height
);
80 Mem
.ReadInt(o
^.Vel
.X
);
81 Mem
.ReadInt(o
^.Vel
.Y
);
82 // Ïðèáàâêà ê ñêîðîñòè:
83 Mem
.ReadInt(o
^.Accel
.X
);
84 Mem
.ReadInt(o
^.Accel
.Y
);
87 function g_GetSaveName(n
: Integer): String;
89 bFile
: TBinFileReader
;
90 bMem
: TBinMemoryReader
;
99 // Îòêðûâàåì ôàéë ñîõðàíåíèé:
100 bFile
:= TBinFileReader
.Create();
101 if bFile
.OpenFile(DataDir
+ 'SAVGAME' + IntToStr(n
) + '.DAT',
102 SAVE_SIGNATURE
, SAVE_VERSION
) then
104 // ×èòàåì ïåðâûé áëîê - ñîñòîÿíèå èãðû:
105 bMem
:= TBinMemoryReader
.Create();
106 bFile
.ReadMemory(bMem
);
108 bMem
.ReadString(str
);
115 on E1
: EInOutError
do
116 e_WriteLog('GetSaveName I/O Error: '+E1
.Message, MSG_WARNING
);
117 on E2
: EBinSizeError
do
118 e_WriteLog('GetSaveName Size Error: '+E2
.Message, MSG_WARNING
);
127 function g_SaveGame(n
: Integer; Name
: String): Boolean;
129 bFile
: TBinFileWriter
;
130 bMem
: TBinMemoryWriter
;
142 // Ñîçäàåì ôàéë ñîõðàíåíèÿ:
143 bFile
:= TBinFileWriter
.Create();
144 bFile
.OpenFile(DataDir
+ 'SAVGAME' + IntToStr(n
) + '.DAT',
145 SAVE_SIGNATURE
, SAVE_VERSION
);
147 ///// Ïîëó÷àåì ñîñòîÿíèå èãðû: /////
148 bMem
:= TBinMemoryWriter
.Create(256);
150 bMem
.WriteString(Name
, 32);
152 str
:= gGameSettings
.WAD
;
153 bMem
.WriteString(str
, 128);
155 g_ProcessResourceStr(gMapInfo
.Map
, nil, nil, @str
);
156 bMem
.WriteString(str
, 32);
157 // Êîëè÷åñòâî èãðîêîâ:
158 nPlayers
:= g_Player_GetCount();
159 bMem
.WriteByte(nPlayers
);
161 bMem
.WriteDWORD(gTime
);
163 bMem
.WriteByte(gGameSettings
.GameType
);
165 bMem
.WriteByte(gGameSettings
.GameMode
);
167 bMem
.WriteWord(gGameSettings
.TimeLimit
);
169 bMem
.WriteWord(gGameSettings
.GoalLimit
);
171 bMem
.WriteByte(gGameSettings
.MaxLives
);
173 bMem
.WriteDWORD(gGameSettings
.Options
);
175 bMem
.WriteWord(gCoopMonstersKilled
);
176 bMem
.WriteWord(gCoopSecretsFound
);
177 bMem
.WriteWord(gCoopTotalMonstersKilled
);
178 bMem
.WriteWord(gCoopTotalSecretsFound
);
179 bMem
.WriteWord(gCoopTotalMonsters
);
180 bMem
.WriteWord(gCoopTotalSecrets
);
181 // Ñîõðàíÿåì ñîñòîÿíèå èãðû:
182 bFile
.WriteMemory(bMem
);
187 ///// Ñîõðàíÿåì ñîñòîÿíèå îáëàñòåé ïðîñìîòðà: /////
188 bMem
:= TBinMemoryWriter
.Create(8);
189 sig
:= PLAYER_VIEW_SIGNATURE
;
190 bMem
.WriteDWORD(sig
); // 'PLVW'
193 if gPlayer1
<> nil then
194 PID1
:= gPlayer1
.UID
;
195 if gPlayer2
<> nil then
196 PID2
:= gPlayer2
.UID
;
197 bMem
.WriteWord(PID1
);
198 bMem
.WriteWord(PID2
);
199 bFile
.WriteMemory(bMem
);
204 ///// Ïîëó÷àåì ñîñòîÿíèå êàðòû: /////
205 g_Map_SaveState(bMem
);
206 // Ñîõðàíÿåì ñîñòîÿíèå êàðòû:
207 bFile
.WriteMemory(bMem
);
212 ///// Ïîëó÷àåì ñîñòîÿíèå ïðåäìåòîâ: /////
213 g_Items_SaveState(bMem
);
214 // Ñîõðàíÿåì ñîñòîÿíèå ïðåäìåòîâ:
215 bFile
.WriteMemory(bMem
);
220 ///// Ïîëó÷àåì ñîñòîÿíèå òðèããåðîâ: /////
221 g_Triggers_SaveState(bMem
);
222 // Ñîõðàíÿåì ñîñòîÿíèå òðèããåðîâ:
223 bFile
.WriteMemory(bMem
);
228 ///// Ïîëó÷àåì ñîñòîÿíèå îðóæèÿ: /////
229 g_Weapon_SaveState(bMem
);
230 // Ñîõðàíÿåì ñîñòîÿíèå îðóæèÿ:
231 bFile
.WriteMemory(bMem
);
236 ///// Ïîëó÷àåì ñîñòîÿíèå ìîíñòðîâ: /////
237 g_Monsters_SaveState(bMem
);
238 // Ñîõðàíÿåì ñîñòîÿíèå ìîíñòðîâ:
239 bFile
.WriteMemory(bMem
);
244 ///// Ïîëó÷àåì ñîñòîÿíèå òðóïîâ: /////
245 g_Player_Corpses_SaveState(bMem
);
246 // Ñîõðàíÿåì ñîñòîÿíèå òðóïîâ:
247 bFile
.WriteMemory(bMem
);
252 ///// Ñîõðàíÿåì èãðîêîâ (â òîì ÷èñëå áîòîâ): /////
256 for i
:= 0 to High(gPlayers
) do
257 if gPlayers
[i
] <> nil then
259 // Ïîëó÷àåì ñîñòîÿíèå èãðîêà:
260 gPlayers
[i
].SaveState(bMem
);
261 // Ñîõðàíÿåì ñîñòîÿíèå èãðîêà:
262 bFile
.WriteMemory(bMem
);
268 // Âñå ëè èãðîêè íà ìåñòå:
269 if k
<> nPlayers
then
271 raise EInOutError
.Create('g_SaveGame: Wrong Players Count');
276 ///// Ìàðêåð îêîí÷àíèÿ: /////
277 bMem
:= TBinMemoryWriter
.Create(4);
278 // Ñòðîêà - îáîçíà÷åíèå êîíöà:
279 str
:= END_MARKER_STRING
; // 'END'
280 bMem
.WriteString(str
, 3);
281 // Ñîõðàíÿåì ìàðêåð îêîí÷àíèÿ:
282 bFile
.WriteMemory(bMem
);
287 // Çàêðûâàåì ôàéë ñîõðàíåíèÿ:
292 on E1
: EInOutError
do
294 g_Console_Add(_lc
[I_GAME_ERROR_SAVE
]);
295 e_WriteLog('SaveState I/O Error: '+E1
.Message, MSG_WARNING
);
297 on E2
: EBinSizeError
do
299 g_Console_Add(_lc
[I_GAME_ERROR_SAVE
]);
300 e_WriteLog('SaveState Size Error: '+E2
.Message, MSG_WARNING
);
308 function g_LoadGame(n
: Integer): Boolean;
310 bFile
: TBinFileReader
;
311 bMem
: TBinMemoryReader
;
313 str
, WAD_Path
, Map_Name
: String;
314 nPlayers
, Game_Type
, Game_Mode
, Game_MaxLives
: Byte;
315 Game_TimeLimit
, Game_GoalLimit
: Word;
316 Game_Time
, Game_Options
: Cardinal;
317 Game_CoopMonstersKilled
,
318 Game_CoopSecretsFound
,
319 Game_CoopTotalMonstersKilled
,
320 Game_CoopTotalSecretsFound
,
321 Game_CoopTotalMonsters
,
322 Game_CoopTotalSecrets
,
331 // Îòêðûâàåì ôàéë ñ ñîõðàíåíèåì:
332 bFile
:= TBinFileReader
.Create();
333 if not bFile
.OpenFile(DataDir
+ 'SAVGAME' + IntToStr(n
) + '.DAT',
334 SAVE_SIGNATURE
, SAVE_VERSION
) then
340 e_WriteLog('Loading saved game...', MSG_NOTIFY
);
343 g_Game_ClearLoading();
344 g_Game_SetLoadingText(_lc
[I_LOAD_SAVE_FILE
], 0, False);
345 gLoadGameMode
:= True;
347 ///// Çàãðóæàåì ñîñòîÿíèå èãðû: /////
348 bMem
:= TBinMemoryReader
.Create();
349 bFile
.ReadMemory(bMem
);
351 bMem
.ReadString(str
);
353 bMem
.ReadString(WAD_Path
);
355 bMem
.ReadString(Map_Name
);
356 // Êîëè÷åñòâî èãðîêîâ:
357 bMem
.ReadByte(nPlayers
);
359 bMem
.ReadDWORD(Game_Time
);
361 bMem
.ReadByte(Game_Type
);
363 bMem
.ReadByte(Game_Mode
);
365 bMem
.ReadWord(Game_TimeLimit
);
367 bMem
.ReadWord(Game_GoalLimit
);
369 bMem
.ReadByte(Game_MaxLives
);
371 bMem
.ReadDWORD(Game_Options
);
373 bMem
.ReadWord(Game_CoopMonstersKilled
);
374 bMem
.ReadWord(Game_CoopSecretsFound
);
375 bMem
.ReadWord(Game_CoopTotalMonstersKilled
);
376 bMem
.ReadWord(Game_CoopTotalSecretsFound
);
377 bMem
.ReadWord(Game_CoopTotalMonsters
);
378 bMem
.ReadWord(Game_CoopTotalSecrets
);
379 // Cîñòîÿíèå èãðû çàãðóæåíî:
384 ///// Çàãðóæàåì ñîñòîÿíèå îáëàñòåé ïðîñìîòðà: /////
385 bMem
:= TBinMemoryReader
.Create();
386 bFile
.ReadMemory(bMem
);
388 if sig
<> PLAYER_VIEW_SIGNATURE
then // 'PLVW'
390 raise EInOutError
.Create('g_LoadGame: Wrong Player View Signature');
399 ZeroMemory(@gGameSettings
, SizeOf(TGameSettings
));
402 if (Game_Type
= GT_NONE
) or (Game_Type
= GT_SINGLE
) then
405 gGameSettings
.GameType
:= GT_SINGLE
;
406 gGameSettings
.MaxLives
:= 0;
407 gGameSettings
.Options
:= gGameSettings
.Options
+ GAME_OPTION_ALLOWEXIT
;
408 gGameSettings
.Options
:= gGameSettings
.Options
+ GAME_OPTION_MONSTERS
;
409 gGameSettings
.Options
:= gGameSettings
.Options
+ GAME_OPTION_BOTVSMONSTER
;
410 gSwitchGameMode
:= GM_SINGLE
;
415 gGameSettings
.GameType
:= GT_CUSTOM
;
416 gGameSettings
.GameMode
:= Game_Mode
;
417 gSwitchGameMode
:= Game_Mode
;
418 gGameSettings
.TimeLimit
:= Game_TimeLimit
;
419 gGameSettings
.GoalLimit
:= Game_GoalLimit
;
420 gGameSettings
.MaxLives
:= IfThen(Game_Mode
= GM_CTF
, 0, Game_MaxLives
);
421 gGameSettings
.Options
:= Game_Options
;
423 g_Game_ExecuteEvent('ongamestart');
425 // Óñòàíîâêà ðàçìåðîâ îêîí èãðîêîâ:
426 g_Game_SetupScreenSize();
428 // Çàãðóçêà è çàïóñê êàðòû:
429 if not g_Game_StartMap(WAD_Path
+ ':\' + Map_Name
, True) then
431 g_FatalError(Format(_lc
[I_GAME_ERROR_MAP_LOAD
], [WAD_Path
+ ':\' + Map_Name
]));
435 // Íàñòðîéêè èãðîêîâ è áîòîâ:
438 // Óñòàíàâëèâàåì âðåìÿ:
441 gCoopMonstersKilled
:= Game_CoopMonstersKilled
;
442 gCoopSecretsFound
:= Game_CoopSecretsFound
;
443 gCoopTotalMonstersKilled
:= Game_CoopTotalMonstersKilled
;
444 gCoopTotalSecretsFound
:= Game_CoopTotalSecretsFound
;
445 gCoopTotalMonsters
:= Game_CoopTotalMonsters
;
446 gCoopTotalSecrets
:= Game_CoopTotalSecrets
;
448 ///// Çàãðóæàåì ñîñòîÿíèå êàðòû: /////
449 bMem
:= TBinMemoryReader
.Create();
450 bFile
.ReadMemory(bMem
);
452 g_Map_LoadState(bMem
);
457 ///// Çàãðóæàåì ñîñòîÿíèå ïðåäìåòîâ: /////
458 bMem
:= TBinMemoryReader
.Create();
459 bFile
.ReadMemory(bMem
);
460 // Ñîñòîÿíèå ïðåäìåòîâ:
461 g_Items_LoadState(bMem
);
466 ///// Çàãðóæàåì ñîñòîÿíèå òðèããåðîâ: /////
467 bMem
:= TBinMemoryReader
.Create();
468 bFile
.ReadMemory(bMem
);
469 // Ñîñòîÿíèå òðèããåðîâ:
470 g_Triggers_LoadState(bMem
);
475 ///// Çàãðóæàåì ñîñòîÿíèå îðóæèÿ: /////
476 bMem
:= TBinMemoryReader
.Create();
477 bFile
.ReadMemory(bMem
);
479 g_Weapon_LoadState(bMem
);
484 ///// Çàãðóæàåì ñîñòîÿíèå ìîíñòðîâ: /////
485 bMem
:= TBinMemoryReader
.Create();
486 bFile
.ReadMemory(bMem
);
487 // Ñîñòîÿíèå ìîíñòðîâ:
488 g_Monsters_LoadState(bMem
);
493 ///// Çàãðóæàåì ñîñòîÿíèå òðóïîâ: /////
494 bMem
:= TBinMemoryReader
.Create();
495 bFile
.ReadMemory(bMem
);
497 g_Player_Corpses_LoadState(bMem
);
502 ///// Çàãðóæàåì èãðîêîâ (â òîì ÷èñëå áîòîâ): /////
506 for i
:= 0 to nPlayers
-1 do
508 // Çàãðóæàåì ñîñòîÿíèå èãðîêà:
509 bMem
:= TBinMemoryReader
.Create();
510 bFile
.ReadMemory(bMem
);
511 // Ñîñòîÿíèå èãðîêà/áîòà:
512 g_Player_CreateFromState(bMem
);
517 // Ïðèâÿçûâàåì îñíîâíûõ èãðîêîâ ê îáëàñòÿì ïðîñìîòðà:
518 gPlayer1
:= g_Player_Get(PID1
);
519 gPlayer2
:= g_Player_Get(PID2
);
520 if gPlayer1
<> nil then
522 gPlayer1
.Name
:= gPlayer1Settings
.Name
;
523 gPlayer1
.FPreferredTeam
:= gPlayer1Settings
.Team
;
524 gPlayer1
.FActualModelName
:= gPlayer1Settings
.Model
;
525 gPlayer1
.SetModel(gPlayer1
.FActualModelName
);
526 gPlayer1
.SetColor(gPlayer1Settings
.Color
);
528 if gPlayer2
<> nil then
530 gPlayer2
.Name
:= gPlayer2Settings
.Name
;
531 gPlayer2
.FPreferredTeam
:= gPlayer2Settings
.Team
;
532 gPlayer2
.FActualModelName
:= gPlayer2Settings
.Model
;
533 gPlayer2
.SetModel(gPlayer2
.FActualModelName
);
534 gPlayer2
.SetColor(gPlayer2Settings
.Color
);
538 ///// Ìàðêåð îêîí÷àíèÿ: /////
539 bMem
:= TBinMemoryReader
.Create();
540 bFile
.ReadMemory(bMem
);
541 // Ñòðîêà - îáîçíà÷åíèå êîíöà:
542 bMem
.ReadString(str
);
543 if str
<> END_MARKER_STRING
then // 'END'
545 raise EInOutError
.Create('g_LoadGame: No END Marker');
547 // Ìàðêåð îêîí÷àíèÿ çàãðóæåí:
552 // Èùåì òðèããåðû ñ óñëîâèåì ñìåðòè ìîíñòðîâ:
553 if (gMonsters
<> nil) and (gTriggers
<> nil) then
554 g_Map_ReAdd_DieTriggers();
556 // Çàêðûâàåì ôàéë çàãðóçêè:
558 gLoadGameMode
:= False;
562 on E1
: EInOutError
do
564 g_Console_Add(_lc
[I_GAME_ERROR_LOAD
]);
565 e_WriteLog('LoadState I/O Error: '+E1
.Message, MSG_WARNING
);
567 on E2
: EBinSizeError
do
569 g_Console_Add(_lc
[I_GAME_ERROR_LOAD
]);
570 e_WriteLog('LoadState Size Error: '+E2
.Message, MSG_WARNING
);