mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:59:56 +00:00
store global script state in saved game files
This commit is contained in:
parent
2a35c7d33a
commit
3590fa40bd
14 changed files with 290 additions and 33 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
#include <components/esm/globalscript.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
@ -90,4 +91,61 @@ namespace MWScript
|
||||||
addScript (iter->mScript);
|
addScript (iter->mScript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GlobalScripts::countSavedGameRecords() const
|
||||||
|
{
|
||||||
|
return mScripts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalScripts::write (ESM::ESMWriter& writer) const
|
||||||
|
{
|
||||||
|
for (std::map<std::string, std::pair<bool, Locals> >::const_iterator iter (mScripts.begin());
|
||||||
|
iter!=mScripts.end(); ++iter)
|
||||||
|
{
|
||||||
|
ESM::GlobalScript script;
|
||||||
|
|
||||||
|
script.mId = iter->first;
|
||||||
|
|
||||||
|
iter->second.second.write (script.mLocals, iter->first);
|
||||||
|
|
||||||
|
script.mRunning = iter->second.first ? 1 : 0;
|
||||||
|
|
||||||
|
writer.startRecord (ESM::REC_GSCR);
|
||||||
|
script.save (writer);
|
||||||
|
writer.endRecord (ESM::REC_GSCR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GlobalScripts::readRecord (ESM::ESMReader& reader, int32_t type)
|
||||||
|
{
|
||||||
|
if (type==ESM::REC_GSCR)
|
||||||
|
{
|
||||||
|
ESM::GlobalScript script;
|
||||||
|
script.load (reader);
|
||||||
|
|
||||||
|
std::map<std::string, std::pair<bool, Locals> >::iterator iter =
|
||||||
|
mScripts.find (script.mId);
|
||||||
|
|
||||||
|
if (iter==mScripts.end())
|
||||||
|
{
|
||||||
|
if (const ESM::Script *scriptRecord = mStore.get<ESM::Script>().search (script.mId))
|
||||||
|
{
|
||||||
|
std::pair<bool, Locals> data (false, Locals());
|
||||||
|
|
||||||
|
data.second.configure (*scriptRecord);
|
||||||
|
|
||||||
|
iter = mScripts.insert (std::make_pair (script.mId, data)).first;
|
||||||
|
}
|
||||||
|
else // script does not exist anymore
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->second.first = script.mRunning!=0;
|
||||||
|
iter->second.second.read (script.mLocals, script.mId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,16 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <libs/platform/stdint.h>
|
||||||
|
|
||||||
#include "locals.hpp"
|
#include "locals.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMWriter;
|
||||||
|
class ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
struct ESMStore;
|
struct ESMStore;
|
||||||
|
@ -35,6 +43,15 @@ namespace MWScript
|
||||||
|
|
||||||
void addStartup();
|
void addStartup();
|
||||||
///< Add startup script
|
///< Add startup script
|
||||||
|
|
||||||
|
int countSavedGameRecords() const;
|
||||||
|
|
||||||
|
void write (ESM::ESMWriter& writer) const;
|
||||||
|
|
||||||
|
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
||||||
|
///< Records for variables that do not exist are dropped silently.
|
||||||
|
///
|
||||||
|
/// \return Known type?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "locals.hpp"
|
#include "locals.hpp"
|
||||||
|
|
||||||
#include <components/esm/loadscpt.hpp>
|
#include <components/esm/loadscpt.hpp>
|
||||||
|
#include <components/esm/variant.hpp>
|
||||||
|
#include <components/esm/locals.hpp>
|
||||||
|
|
||||||
#include <components/compiler/locals.hpp>
|
#include <components/compiler/locals.hpp>
|
||||||
|
|
||||||
|
@ -65,4 +67,68 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Locals::write (ESM::Locals& locals, const std::string& script) const
|
||||||
|
{
|
||||||
|
const Compiler::Locals& declarations =
|
||||||
|
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
|
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
|
char type = 0;
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: type = 's'; break;
|
||||||
|
case 1: type = 'l'; break;
|
||||||
|
case 2: type = 'f'; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& names = declarations.get (type);
|
||||||
|
|
||||||
|
for (int i2=0; i2<static_cast<int> (names.size()); ++i2)
|
||||||
|
{
|
||||||
|
ESM::Variant value;
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break;
|
||||||
|
case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break;
|
||||||
|
case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
locals.mVariables.push_back (std::make_pair (names[i2], value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Locals::read (const ESM::Locals& locals, const std::string& script)
|
||||||
|
{
|
||||||
|
const Compiler::Locals& declarations =
|
||||||
|
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
|
|
||||||
|
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
|
||||||
|
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
|
||||||
|
{
|
||||||
|
char type = declarations.getType (iter->first);
|
||||||
|
char index = declarations.getIndex (iter->first);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 's': mShorts.at (index) = iter->second.getInteger(); break;
|
||||||
|
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
|
||||||
|
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
|
||||||
|
|
||||||
|
// silently ignore locals that don't exist anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// ignore type changes
|
||||||
|
/// \todo write to log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct Script;
|
struct Script;
|
||||||
|
struct Locals;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
|
@ -23,6 +24,9 @@ namespace MWScript
|
||||||
bool setVarByInt(const std::string& script, const std::string& var, int val);
|
bool setVarByInt(const std::string& script, const std::string& var, int val);
|
||||||
int getIntVar (const std::string& script, const std::string& var); ///< if var does not exist, returns 0
|
int getIntVar (const std::string& script, const std::string& var); ///< if var does not exist, returns 0
|
||||||
|
|
||||||
|
void write (ESM::Locals& locals, const std::string& script) const;
|
||||||
|
|
||||||
|
void read (const ESM::Locals& locals, const std::string& script);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
1 // saved game header
|
1 // saved game header
|
||||||
+MWBase::Environment::get().getJournal()->countSavedGameRecords()
|
+MWBase::Environment::get().getJournal()->countSavedGameRecords()
|
||||||
+MWBase::Environment::get().getWorld()->countSavedGameRecords()
|
+MWBase::Environment::get().getWorld()->countSavedGameRecords()
|
||||||
|
+MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords()
|
||||||
);
|
);
|
||||||
|
|
||||||
writer.save (stream);
|
writer.save (stream);
|
||||||
|
@ -124,6 +125,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
|
|
||||||
MWBase::Environment::get().getJournal()->write (writer);
|
MWBase::Environment::get().getJournal()->write (writer);
|
||||||
MWBase::Environment::get().getWorld()->write (writer);
|
MWBase::Environment::get().getWorld()->write (writer);
|
||||||
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer);
|
||||||
|
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
|
@ -173,6 +175,11 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
|
||||||
MWBase::Environment::get().getWorld()->readRecord (reader, n.val);
|
MWBase::Environment::get().getWorld()->readRecord (reader, n.val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ESM::REC_GSCR:
|
||||||
|
|
||||||
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.val);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// ignore invalid records
|
// ignore invalid records
|
||||||
|
|
|
@ -40,7 +40,7 @@ add_component_dir (esm
|
||||||
loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc loadnpcc
|
loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc loadnpcc
|
||||||
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
||||||
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
||||||
savedgame journalentry queststate
|
savedgame journalentry queststate locals globalscript
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (misc
|
add_component_dir (misc
|
||||||
|
|
|
@ -15,27 +15,27 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
case 's': return mShorts;
|
case 's': return mShorts;
|
||||||
case 'l': return mLongs;
|
case 'l': return mLongs;
|
||||||
case 'f': return mFloats;
|
case 'f': return mFloats;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::logic_error ("unknown variable type");
|
throw std::logic_error ("unknown variable type");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Locals::searchIndex (char type, const std::string& name) const
|
int Locals::searchIndex (char type, const std::string& name) const
|
||||||
{
|
{
|
||||||
const std::vector<std::string>& collection = get (type);
|
const std::vector<std::string>& collection = get (type);
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator iter =
|
std::vector<std::string>::const_iterator iter =
|
||||||
std::find (collection.begin(), collection.end(), name);
|
std::find (collection.begin(), collection.end(), name);
|
||||||
|
|
||||||
if (iter==collection.end())
|
if (iter==collection.end())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return iter-collection.begin();
|
return iter-collection.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Locals::search (char type, const std::string& name) const
|
bool Locals::search (char type, const std::string& name) const
|
||||||
{
|
{
|
||||||
return searchIndex (type, name)!=-1;
|
return searchIndex (type, name)!=-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
case 's': return mShorts;
|
case 's': return mShorts;
|
||||||
case 'l': return mLongs;
|
case 'l': return mLongs;
|
||||||
case 'f': return mFloats;
|
case 'f': return mFloats;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::logic_error ("unknown variable type");
|
throw std::logic_error ("unknown variable type");
|
||||||
}
|
}
|
||||||
|
|
||||||
char Locals::getType (const std::string& name) const
|
char Locals::getType (const std::string& name) const
|
||||||
|
@ -58,35 +58,35 @@ namespace Compiler
|
||||||
|
|
||||||
if (search ('l', name))
|
if (search ('l', name))
|
||||||
return 'l';
|
return 'l';
|
||||||
|
|
||||||
if (search ('f', name))
|
if (search ('f', name))
|
||||||
return 'f';
|
return 'f';
|
||||||
|
|
||||||
return ' ';
|
return ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
int Locals::getIndex (const std::string& name) const
|
int Locals::getIndex (const std::string& name) const
|
||||||
{
|
{
|
||||||
int index = searchIndex ('s', name);
|
int index = searchIndex ('s', name);
|
||||||
|
|
||||||
if (index!=-1)
|
if (index!=-1)
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
index = searchIndex ('l', name);
|
index = searchIndex ('l', name);
|
||||||
|
|
||||||
if (index!=-1)
|
if (index!=-1)
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
return searchIndex ('f', name);
|
return searchIndex ('f', name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Locals::write (std::ostream& localFile) const
|
void Locals::write (std::ostream& localFile) const
|
||||||
{
|
{
|
||||||
localFile
|
localFile
|
||||||
<< get ('s').size() << ' '
|
<< get ('s').size() << ' '
|
||||||
<< get ('l').size() << ' '
|
<< get ('l').size() << ' '
|
||||||
<< get ('f').size() << std::endl;
|
<< get ('f').size() << std::endl;
|
||||||
|
|
||||||
std::copy (get ('s').begin(), get ('s').end(),
|
std::copy (get ('s').begin(), get ('s').end(),
|
||||||
std::ostream_iterator<std::string> (localFile, " "));
|
std::ostream_iterator<std::string> (localFile, " "));
|
||||||
std::copy (get ('l').begin(), get ('l').end(),
|
std::copy (get ('l').begin(), get ('l').end(),
|
||||||
|
@ -94,12 +94,12 @@ namespace Compiler
|
||||||
std::copy (get ('f').begin(), get ('f').end(),
|
std::copy (get ('f').begin(), get ('f').end(),
|
||||||
std::ostream_iterator<std::string> (localFile, " "));
|
std::ostream_iterator<std::string> (localFile, " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Locals::declare (char type, const std::string& name)
|
void Locals::declare (char type, const std::string& name)
|
||||||
{
|
{
|
||||||
get (type).push_back (name);
|
get (type).push_back (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Locals::clear()
|
void Locals::clear()
|
||||||
{
|
{
|
||||||
get ('s').clear();
|
get ('s').clear();
|
||||||
|
|
|
@ -8,35 +8,35 @@
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
/// \brief Local variable declarations
|
/// \brief Local variable declarations
|
||||||
|
|
||||||
class Locals
|
class Locals
|
||||||
{
|
{
|
||||||
std::vector<std::string> mShorts;
|
std::vector<std::string> mShorts;
|
||||||
std::vector<std::string> mLongs;
|
std::vector<std::string> mLongs;
|
||||||
std::vector<std::string> mFloats;
|
std::vector<std::string> mFloats;
|
||||||
|
|
||||||
int searchIndex (char type, const std::string& name) const;
|
int searchIndex (char type, const std::string& name) const;
|
||||||
|
|
||||||
bool search (char type, const std::string& name) const;
|
bool search (char type, const std::string& name) const;
|
||||||
|
|
||||||
std::vector<std::string>& get (char type);
|
std::vector<std::string>& get (char type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
char getType (const std::string& name) const;
|
char getType (const std::string& name) const;
|
||||||
///< 's': short, 'l': long, 'f': float, ' ': does not exist.
|
///< 's': short, 'l': long, 'f': float, ' ': does not exist.
|
||||||
|
|
||||||
int getIndex (const std::string& name) const;
|
int getIndex (const std::string& name) const;
|
||||||
///< return index for local variable \a name (-1: does not exist).
|
///< return index for local variable \a name (-1: does not exist).
|
||||||
|
|
||||||
const std::vector<std::string>& get (char type) const;
|
const std::vector<std::string>& get (char type) const;
|
||||||
|
|
||||||
void write (std::ostream& localFile) const;
|
void write (std::ostream& localFile) const;
|
||||||
///< write declarations to file.
|
///< write declarations to file.
|
||||||
|
|
||||||
void declare (char type, const std::string& name);
|
void declare (char type, const std::string& name);
|
||||||
///< declares a variable.
|
///< declares a variable.
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
///< remove all declarations.
|
///< remove all declarations.
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,6 +87,7 @@ enum RecNameInts
|
||||||
REC_SAVE = 0x45564153,
|
REC_SAVE = 0x45564153,
|
||||||
REC_JOUR = 0x524f55a4,
|
REC_JOUR = 0x524f55a4,
|
||||||
REC_QUES = 0x53455551,
|
REC_QUES = 0x53455551,
|
||||||
|
REC_GSCR = 0x52435347,
|
||||||
|
|
||||||
// format 1
|
// format 1
|
||||||
REC_FILT = 0x544C4946
|
REC_FILT = 0x544C4946
|
||||||
|
|
25
components/esm/globalscript.cpp
Normal file
25
components/esm/globalscript.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
#include "globalscript.hpp"
|
||||||
|
|
||||||
|
#include "esmreader.hpp"
|
||||||
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
|
void ESM::GlobalScript::load (ESMReader &esm)
|
||||||
|
{
|
||||||
|
mId = esm.getHNString ("NAME");
|
||||||
|
|
||||||
|
mLocals.load (esm);
|
||||||
|
|
||||||
|
mRunning = 0;
|
||||||
|
esm.getHNOT (mRunning, "RUN_");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESM::GlobalScript::save (ESMWriter &esm) const
|
||||||
|
{
|
||||||
|
esm.writeHNString ("NAME", mId);
|
||||||
|
|
||||||
|
mLocals.save (esm);
|
||||||
|
|
||||||
|
if (mRunning)
|
||||||
|
esm.writeHNT ("RUN_", mRunning);
|
||||||
|
}
|
24
components/esm/globalscript.hpp
Normal file
24
components/esm/globalscript.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef OPENMW_ESM_GLOBALSCRIPT_H
|
||||||
|
#define OPENMW_ESM_GLOBALSCRIPT_H
|
||||||
|
|
||||||
|
#include "locals.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
class ESMWriter;
|
||||||
|
|
||||||
|
/// \brief Storage structure for global script state (only used in saved games)
|
||||||
|
|
||||||
|
struct GlobalScript
|
||||||
|
{
|
||||||
|
std::string mId;
|
||||||
|
Locals mLocals;
|
||||||
|
int mRunning;
|
||||||
|
|
||||||
|
void load (ESMReader &esm);
|
||||||
|
void save (ESMWriter &esm) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
components/esm/locals.cpp
Normal file
28
components/esm/locals.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
#include "locals.hpp"
|
||||||
|
|
||||||
|
#include "esmreader.hpp"
|
||||||
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
|
void ESM::Locals::load (ESMReader &esm)
|
||||||
|
{
|
||||||
|
while (esm.isNextSub ("LOCA"))
|
||||||
|
{
|
||||||
|
std::string id = esm.getHString();
|
||||||
|
|
||||||
|
Variant value;
|
||||||
|
value.read (esm, Variant::Format_Info);
|
||||||
|
|
||||||
|
mVariables.push_back (std::make_pair (id, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESM::Locals::save (ESMWriter &esm) const
|
||||||
|
{
|
||||||
|
for (std::vector<std::pair<std::string, Variant> >::const_iterator iter (mVariables.begin());
|
||||||
|
iter!=mVariables.end(); ++iter)
|
||||||
|
{
|
||||||
|
esm.writeHNString ("LOCA", iter->first);
|
||||||
|
iter->second.write (esm, Variant::Format_Info);
|
||||||
|
}
|
||||||
|
}
|
27
components/esm/locals.hpp
Normal file
27
components/esm/locals.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef OPENMW_ESM_LOCALS_H
|
||||||
|
#define OPENMW_ESM_LOCALS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "variant.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
class ESMWriter;
|
||||||
|
|
||||||
|
/// \brief Storage structure for local variables (only used in saved games)
|
||||||
|
///
|
||||||
|
/// \note This is not a top-level record.
|
||||||
|
|
||||||
|
struct Locals
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, Variant> > mVariables;
|
||||||
|
|
||||||
|
void load (ESMReader &esm);
|
||||||
|
void save (ESMWriter &esm) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -33,7 +33,7 @@ namespace ESM
|
||||||
{
|
{
|
||||||
Format_Global,
|
Format_Global,
|
||||||
Format_Gmst,
|
Format_Gmst,
|
||||||
Format_Info
|
Format_Info // also used for local variables in saved game files
|
||||||
};
|
};
|
||||||
|
|
||||||
Variant();
|
Variant();
|
||||||
|
|
Loading…
Reference in a new issue