Added -save switch: can now load player cell / pos from savegames

git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@137 ea6a568a-9f4f-0410-981a-c910a81bb256
actorid
nkorslund 15 years ago
parent 5715235a17
commit e2e1c3b54b

@ -25,6 +25,8 @@ module esm.esmmain;
public import esm.records; public import esm.records;
import ogre.ogre;
/* This file is the main module for loading from ESM, ESP and ESS /* This file is the main module for loading from ESM, ESP and ESS
files. It stores all the data in the appropriate data structures files. It stores all the data in the appropriate data structures
for later referal. TODO: Put this in a class or whatever? Nah, we for later referal. TODO: Put this in a class or whatever? Nah, we
@ -115,11 +117,21 @@ void loadTESFiles(char[][] files)
hyperlinks.sort(); hyperlinks.sort();
} }
// Load a TES savegame file (.ess). Currently VERY limited, only reads // Contains the small bits of information that we currently extract
// the header. // from savegames.
void importSavegame(char[] file) struct PlayerSaveInfo
{
char[] cellName;
char[] playerName;
Placement pos;
}
// Load a TES savegame file (.ess). Currently VERY limited, reads the
// player's cell name and position
PlayerSaveInfo importSavegame(char[] file)
{ {
writefln("Loading savegame %s", file); PlayerSaveInfo pi;
esFile.open(file, esmRegion); esFile.open(file, esmRegion);
scope(exit) esFile.close(); scope(exit) esFile.close();
@ -128,14 +140,28 @@ void importSavegame(char[] file)
with(esFile.saveData) with(esFile.saveData)
{ {
writefln("Floats:"); pi.cellName = stripz(cell);
foreach(i, f; unknown) pi.playerName = stripz(player);
writefln(" %s: %s", i, f); }
writefln("Cell name: ", stripz(cell));
writefln("Strange value: ", unk2); with(esFile)
writefln("Player name: ", stripz(player)); {
while(hasMoreRecs())
{
if(isNextHRec("REFR"))
{
while(hasMoreSubs())
{
getSubName();
if(retSubName() == "DATA")
readHExact(&pi.pos, pi.pos.sizeof);
else
skipHSub();
}
}
else
skipHRecord();
}
} }
writefln(); return pi;
} }

@ -174,7 +174,7 @@ struct TES3File
// name. // name.
struct _saveData struct _saveData
{ {
float[6] unknown; // 24 bytes float[6] unknown;
char[64] cell; // Cell name char[64] cell; // Cell name
float unk2; // Unknown value float unk2; // Unknown value
char[32] player; // Player name char[32] player; // Player name
@ -534,13 +534,26 @@ struct TES3File
// Size of current sub record // Size of current sub record
uint getSubSize() { return leftSub; } uint getSubSize() { return leftSub; }
// Skip the rest of this record // Skip the rest of this record. Assumes the name and header have
// already been read
void skipRecord() void skipRecord()
{ {
file.seekCur(leftRec); file.seekCur(leftRec);
leftRec = 0; leftRec = 0;
} }
// Skip an entire record
void skipHRecord()
{
if(!leftFile) return;
uint flags;
getRecName();
getRecHeader(flags);
skipRecord();
}
// Skip current sub record and return size // Skip current sub record and return size
uint skipHSub() uint skipHSub()
{ {

@ -160,7 +160,7 @@ struct NPC
readHExact(&AI, AI.sizeof); readHExact(&AI, AI.sizeof);
hasAI = true; hasAI = true;
} }
else hasAI = false; else hasAI = false;
skipRecord(); skipRecord();

@ -38,6 +38,7 @@ import bullet.bullet;
import scene.celldata; import scene.celldata;
import scene.soundlist; import scene.soundlist;
import scene.gamesettings; import scene.gamesettings;
import scene.player;
import core.resource; import core.resource;
import core.memory; import core.memory;
@ -90,6 +91,8 @@ void main(char[][] args)
bool debugOut = false; bool debugOut = false;
bool extTest = false; bool extTest = false;
bool doGen = false; bool doGen = false;
bool nextSave = false;
bool loadSave = false;
// Some examples to try: // Some examples to try:
// //
@ -107,6 +110,9 @@ void main(char[][] args)
// Cells to load // Cells to load
char[][] cells; char[][] cells;
// Savegame to load
char[] savefile;
foreach(char[] a; args[1..$]) foreach(char[] a; args[1..$])
if(a == "-n") render = false; if(a == "-n") render = false;
else if(a == "-ex") extTest = true; else if(a == "-ex") extTest = true;
@ -115,6 +121,7 @@ void main(char[][] args)
else if(a == "-rk") resetKeys = true; else if(a == "-rk") resetKeys = true;
else if(a == "-oc") showOgreFlag = true; else if(a == "-oc") showOgreFlag = true;
else if(a == "-ns") config.noSound = true; else if(a == "-ns") config.noSound = true;
else if(a == "-save") nextSave = true;
else if(a == "-debug") else if(a == "-debug")
{ {
// Enable Monster debug output // Enable Monster debug output
@ -123,6 +130,11 @@ void main(char[][] args)
// Tell OGRE to do the same later on // Tell OGRE to do the same later on
debugOut = true; debugOut = true;
} }
else if(nextSave)
{
savefile = a;
nextSave = false;
}
else cells ~= a; else cells ~= a;
if(cells.length > 1) if(cells.length > 1)
@ -142,6 +154,7 @@ void main(char[][] args)
writefln(" -oc Show the Ogre config dialogue"); writefln(" -oc Show the Ogre config dialogue");
writefln(" -ns Completely disable sound"); writefln(" -ns Completely disable sound");
writefln(" -debug Print debug information"); writefln(" -debug Print debug information");
writefln(" -save <file> Load cell/pos from savegame");
writefln(" -h Show this help"); writefln(" -h Show this help");
writefln(""); writefln("");
writefln("Specifying more than one cell implies -n"); writefln("Specifying more than one cell implies -n");
@ -156,11 +169,28 @@ void main(char[][] args)
initializeMemoryRegions(); initializeMemoryRegions();
initMonsterScripts(); initMonsterScripts();
/* // This is getting increasingly hackish, but this entire engine
importSavegame("data/quiksave.ess"); // design is now quickly outgrowing its usefulness, and a rewrite is
importSavegame("data/Perm1hal0000.ess"); // coming soon anyway.
return; PlayerSaveInfo pi;
*/ if(savefile != "")
{
if(cells.length)
{
writefln("Please don't specify both a savegame file (%s) and cell names (%s)", savefile, cells);
return;
}
loadSave = true;
writefln("Loading savegame %s", savefile);
pi = importSavegame(savefile);
writefln(" Player name: %s", pi.playerName);
writefln(" Cell name: %s", pi.cellName);
writefln(" Pos: %s", pi.pos.position);
writefln(" Rot: %s", pi.pos.rotation);
cells = [pi.cellName];
}
config.initialize(resetKeys); config.initialize(resetKeys);
scope(exit) config.writeConfig(); scope(exit) config.writeConfig();
@ -181,7 +211,7 @@ void main(char[][] args)
if(config.defaultCell.length) if(config.defaultCell.length)
cells ~= config.defaultCell; cells ~= config.defaultCell;
if(cells.length == 1) if(cells.length == 1 && !loadSave)
config.defaultCell = cells[0]; config.defaultCell = cells[0];
if(cells.length == 0) if(cells.length == 0)
@ -218,6 +248,10 @@ Perhaps this cell does not exist in your Morrowind language version?
Try specifying another cell name on the command line, or edit openmw.ini."); Try specifying another cell name on the command line, or edit openmw.ini.");
return; return;
} }
// If we're loading from save, override the player position
if(loadSave)
*playerData.position = pi.pos;
} }
// Simple safety hack // Simple safety hack

Loading…
Cancel
Save