forked from teamnwah/openmw-tes3coop
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
This commit is contained in:
parent
5715235a17
commit
e2e1c3b54b
4 changed files with 95 additions and 22 deletions
|
@ -25,6 +25,8 @@ module esm.esmmain;
|
|||
|
||||
public import esm.records;
|
||||
|
||||
import ogre.ogre;
|
||||
|
||||
/* This file is the main module for loading from ESM, ESP and ESS
|
||||
files. It stores all the data in the appropriate data structures
|
||||
for later referal. TODO: Put this in a class or whatever? Nah, we
|
||||
|
@ -115,11 +117,21 @@ void loadTESFiles(char[][] files)
|
|||
hyperlinks.sort();
|
||||
}
|
||||
|
||||
// Load a TES savegame file (.ess). Currently VERY limited, only reads
|
||||
// the header.
|
||||
void importSavegame(char[] file)
|
||||
// Contains the small bits of information that we currently extract
|
||||
// from savegames.
|
||||
struct PlayerSaveInfo
|
||||
{
|
||||
writefln("Loading savegame %s", file);
|
||||
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)
|
||||
{
|
||||
PlayerSaveInfo pi;
|
||||
|
||||
esFile.open(file, esmRegion);
|
||||
scope(exit) esFile.close();
|
||||
|
||||
|
@ -128,14 +140,28 @@ void importSavegame(char[] file)
|
|||
|
||||
with(esFile.saveData)
|
||||
{
|
||||
writefln("Floats:");
|
||||
foreach(i, f; unknown)
|
||||
writefln(" %s: %s", i, f);
|
||||
|
||||
writefln("Cell name: ", stripz(cell));
|
||||
|
||||
writefln("Strange value: ", unk2);
|
||||
writefln("Player name: ", stripz(player));
|
||||
pi.cellName = stripz(cell);
|
||||
pi.playerName = stripz(player);
|
||||
}
|
||||
writefln();
|
||||
|
||||
with(esFile)
|
||||
{
|
||||
while(hasMoreRecs())
|
||||
{
|
||||
if(isNextHRec("REFR"))
|
||||
{
|
||||
while(hasMoreSubs())
|
||||
{
|
||||
getSubName();
|
||||
if(retSubName() == "DATA")
|
||||
readHExact(&pi.pos, pi.pos.sizeof);
|
||||
else
|
||||
skipHSub();
|
||||
}
|
||||
}
|
||||
else
|
||||
skipHRecord();
|
||||
}
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ struct TES3File
|
|||
// name.
|
||||
struct _saveData
|
||||
{
|
||||
float[6] unknown; // 24 bytes
|
||||
float[6] unknown;
|
||||
char[64] cell; // Cell name
|
||||
float unk2; // Unknown value
|
||||
char[32] player; // Player name
|
||||
|
@ -534,13 +534,26 @@ struct TES3File
|
|||
// Size of current sub record
|
||||
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()
|
||||
{
|
||||
file.seekCur(leftRec);
|
||||
leftRec = 0;
|
||||
}
|
||||
|
||||
// Skip an entire record
|
||||
void skipHRecord()
|
||||
{
|
||||
if(!leftFile) return;
|
||||
|
||||
uint flags;
|
||||
|
||||
getRecName();
|
||||
getRecHeader(flags);
|
||||
skipRecord();
|
||||
}
|
||||
|
||||
// Skip current sub record and return size
|
||||
uint skipHSub()
|
||||
{
|
||||
|
|
44
openmw.d
44
openmw.d
|
@ -38,6 +38,7 @@ import bullet.bullet;
|
|||
import scene.celldata;
|
||||
import scene.soundlist;
|
||||
import scene.gamesettings;
|
||||
import scene.player;
|
||||
|
||||
import core.resource;
|
||||
import core.memory;
|
||||
|
@ -90,6 +91,8 @@ void main(char[][] args)
|
|||
bool debugOut = false;
|
||||
bool extTest = false;
|
||||
bool doGen = false;
|
||||
bool nextSave = false;
|
||||
bool loadSave = false;
|
||||
|
||||
// Some examples to try:
|
||||
//
|
||||
|
@ -107,6 +110,9 @@ void main(char[][] args)
|
|||
// Cells to load
|
||||
char[][] cells;
|
||||
|
||||
// Savegame to load
|
||||
char[] savefile;
|
||||
|
||||
foreach(char[] a; args[1..$])
|
||||
if(a == "-n") render = false;
|
||||
else if(a == "-ex") extTest = true;
|
||||
|
@ -115,6 +121,7 @@ void main(char[][] args)
|
|||
else if(a == "-rk") resetKeys = true;
|
||||
else if(a == "-oc") showOgreFlag = true;
|
||||
else if(a == "-ns") config.noSound = true;
|
||||
else if(a == "-save") nextSave = true;
|
||||
else if(a == "-debug")
|
||||
{
|
||||
// Enable Monster debug output
|
||||
|
@ -123,6 +130,11 @@ void main(char[][] args)
|
|||
// Tell OGRE to do the same later on
|
||||
debugOut = true;
|
||||
}
|
||||
else if(nextSave)
|
||||
{
|
||||
savefile = a;
|
||||
nextSave = false;
|
||||
}
|
||||
else cells ~= a;
|
||||
|
||||
if(cells.length > 1)
|
||||
|
@ -142,6 +154,7 @@ void main(char[][] args)
|
|||
writefln(" -oc Show the Ogre config dialogue");
|
||||
writefln(" -ns Completely disable sound");
|
||||
writefln(" -debug Print debug information");
|
||||
writefln(" -save <file> Load cell/pos from savegame");
|
||||
writefln(" -h Show this help");
|
||||
writefln("");
|
||||
writefln("Specifying more than one cell implies -n");
|
||||
|
@ -156,11 +169,28 @@ void main(char[][] args)
|
|||
initializeMemoryRegions();
|
||||
initMonsterScripts();
|
||||
|
||||
/*
|
||||
importSavegame("data/quiksave.ess");
|
||||
importSavegame("data/Perm1hal0000.ess");
|
||||
// This is getting increasingly hackish, but this entire engine
|
||||
// design is now quickly outgrowing its usefulness, and a rewrite is
|
||||
// coming soon anyway.
|
||||
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);
|
||||
scope(exit) config.writeConfig();
|
||||
|
@ -181,7 +211,7 @@ void main(char[][] args)
|
|||
if(config.defaultCell.length)
|
||||
cells ~= config.defaultCell;
|
||||
|
||||
if(cells.length == 1)
|
||||
if(cells.length == 1 && !loadSave)
|
||||
config.defaultCell = cells[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.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're loading from save, override the player position
|
||||
if(loadSave)
|
||||
*playerData.position = pi.pos;
|
||||
}
|
||||
|
||||
// Simple safety hack
|
||||
|
|
Loading…
Reference in a new issue