mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 04:45:33 +00:00
Merge branch 'master' of git://github.com/zinnschlag/openmw into graphics
This commit is contained in:
commit
c9f7f1b994
24 changed files with 982 additions and 319 deletions
|
@ -112,14 +112,11 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
|
|||
case '5': oper_str = ">="; break;
|
||||
}
|
||||
|
||||
std::string value_str = "??";
|
||||
if (ss.mType == ESM::VT_Int)
|
||||
value_str = str(boost::format("%d") % ss.mI);
|
||||
else if (ss.mType == ESM::VT_Float)
|
||||
value_str = str(boost::format("%f") % ss.mF);
|
||||
std::ostringstream stream;
|
||||
stream << ss.mValue;
|
||||
|
||||
std::string result = str(boost::format("%-12s %-32s %2s %s")
|
||||
% type_str % func_str % oper_str % value_str);
|
||||
% type_str % func_str % oper_str % stream.str());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -713,31 +710,13 @@ void Record<ESM::Faction>::print()
|
|||
template<>
|
||||
void Record<ESM::Global>::print()
|
||||
{
|
||||
// nothing to print (well, nothing that's correct anyway)
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Value: " << mData.mValue << std::endl;
|
||||
std::cout << " " << mData.mValue << std::endl;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Record<ESM::GameSetting>::print()
|
||||
{
|
||||
std::cout << " Value: ";
|
||||
switch (mData.mType) {
|
||||
case ESM::VT_String:
|
||||
std::cout << "'" << mData.mStr << "' (std::string)";
|
||||
break;
|
||||
|
||||
case ESM::VT_Float:
|
||||
std::cout << mData.mF << " (float)";
|
||||
break;
|
||||
|
||||
case ESM::VT_Int:
|
||||
std::cout << mData.mI << " (int)";
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << "unknown type";
|
||||
}
|
||||
std::cout << " " << mData.mValue << std::endl;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
@ -116,8 +116,7 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sFloats[i];
|
||||
gmst.mF = 0;
|
||||
gmst.mType = ESM::VT_Float;
|
||||
gmst.mValue.setType (ESM::VT_Float);
|
||||
addOptionalGmst (gmst);
|
||||
}
|
||||
|
||||
|
@ -125,8 +124,7 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sIntegers[i];
|
||||
gmst.mI = 0;
|
||||
gmst.mType = ESM::VT_Long;
|
||||
gmst.mValue.setType (ESM::VT_Int);
|
||||
addOptionalGmst (gmst);
|
||||
}
|
||||
|
||||
|
@ -134,8 +132,8 @@ void CSMDoc::Document::addOptionalGmsts()
|
|||
{
|
||||
ESM::GameSetting gmst;
|
||||
gmst.mId = sStrings[i];
|
||||
gmst.mStr = "<no text>";
|
||||
gmst.mType = ESM::VT_String;
|
||||
gmst.mValue.setType (ESM::VT_String);
|
||||
gmst.mValue.setString ("<no text>");
|
||||
addOptionalGmst (gmst);
|
||||
}
|
||||
}
|
||||
|
@ -154,8 +152,7 @@ void CSMDoc::Document::addOptionalGlobals()
|
|||
{
|
||||
ESM::Global global;
|
||||
global.mId = sGlobals[i];
|
||||
global.mType = ESM::VT_Int;
|
||||
global.mValue = 0;
|
||||
global.mValue.setType (ESM::VT_Long);
|
||||
addOptionalGlobal (global);
|
||||
}
|
||||
}
|
||||
|
@ -192,9 +189,14 @@ void CSMDoc::Document::createBase()
|
|||
for (int i=0; sGlobals[i]; ++i)
|
||||
{
|
||||
ESM::Global record;
|
||||
|
||||
record.mId = sGlobals[i];
|
||||
record.mValue = i==0 ? 1 : 0;
|
||||
record.mType = ESM::VT_Float;
|
||||
|
||||
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Int);
|
||||
|
||||
if (i==0)
|
||||
record.mValue.setInteger (1);
|
||||
|
||||
getData().getGlobals().add (record);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace CSMWorld
|
|||
Display_Integer,
|
||||
Display_Float,
|
||||
Display_Var,
|
||||
Display_VarType
|
||||
Display_GmstVarType,
|
||||
Display_GlobalVarType
|
||||
};
|
||||
|
||||
std::string mTitle;
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace CSMWorld
|
|||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mValue;
|
||||
return record.get().mValue.getFloat();
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mValue = data.toFloat();
|
||||
record2.mValue.setFloat (data.toFloat());
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
|
@ -96,17 +96,17 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct VarTypeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
VarTypeColumn() : Column<ESXRecordT> ("Type", ColumnBase::Display_VarType) {}
|
||||
VarTypeColumn (ColumnBase::Display display) : Column<ESXRecordT> ("Type", display) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return static_cast<int> (record.get().mType);
|
||||
return static_cast<int> (record.get().mValue.getType());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
record2.mType = static_cast<ESM::VarType> (data.toInt());
|
||||
record2.mValue.setType (static_cast<ESM::VarType> (data.toInt()));
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
|
@ -123,11 +123,21 @@ namespace CSMWorld
|
|||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
switch (record.get().mType)
|
||||
switch (record.get().mValue.getType())
|
||||
{
|
||||
case ESM::VT_String: return record.get().mStr.c_str(); break;
|
||||
case ESM::VT_Int: return record.get().mI; break;
|
||||
case ESM::VT_Float: return record.get().mF; break;
|
||||
case ESM::VT_String:
|
||||
|
||||
return record.get().mValue.getString().c_str(); break;
|
||||
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
|
||||
return record.get().mValue.getInteger(); break;
|
||||
|
||||
case ESM::VT_Float:
|
||||
|
||||
return record.get().mValue.getFloat(); break;
|
||||
|
||||
default: return QVariant();
|
||||
}
|
||||
|
@ -137,11 +147,24 @@ namespace CSMWorld
|
|||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
switch (record2.mType)
|
||||
switch (record2.mValue.getType())
|
||||
{
|
||||
case ESM::VT_String: record2.mStr = data.toString().toUtf8().constData(); break;
|
||||
case ESM::VT_Int: record2.mI = data.toInt(); break;
|
||||
case ESM::VT_Float: record2.mF = data.toFloat(); break;
|
||||
case ESM::VT_String:
|
||||
|
||||
record2.mValue.setString (data.toString().toUtf8().constData());
|
||||
break;
|
||||
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
|
||||
record2.mValue.setInteger (data.toInt());
|
||||
break;
|
||||
|
||||
case ESM::VT_Float:
|
||||
|
||||
record2.mValue.setFloat (data.toFloat());
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QAbstractTableModel>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/loadglob.hpp>
|
||||
|
||||
#include "idtable.hpp"
|
||||
|
@ -26,12 +27,13 @@ CSMWorld::Data::Data()
|
|||
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
||||
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
||||
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
|
||||
mGlobals.addColumn (new FloatValueColumn<ESM::Global>);
|
||||
mGlobals.addColumn (new VarTypeColumn<ESM::Global> (ColumnBase::Display_GlobalVarType));
|
||||
mGlobals.addColumn (new VarValueColumn<ESM::Global>);
|
||||
|
||||
mGmsts.addColumn (new StringIdColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new RecordStateColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new FixedRecordTypeColumn<ESM::GameSetting> (UniversalId::Type_Gmst));
|
||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting>);
|
||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
||||
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
|
|
|
@ -35,8 +35,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
{
|
||||
mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection;
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_VarType,
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType,
|
||||
new CSVWorld::VarTypeDelegateFactory (ESM::VT_None, ESM::VT_String, ESM::VT_Int, ESM::VT_Float));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
|
||||
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
|
||||
|
||||
}
|
||||
|
||||
CSVDoc::ViewManager::~ViewManager()
|
||||
|
|
|
@ -85,7 +85,7 @@ void CSVWorld::VarTypeDelegateFactory::add (ESM::VarType type)
|
|||
{
|
||||
{ ESM::VT_None, "empty" },
|
||||
{ ESM::VT_Short, "short" },
|
||||
{ ESM::VT_Int, "long" },
|
||||
{ ESM::VT_Int, "integer" },
|
||||
{ ESM::VT_Long, "long" },
|
||||
{ ESM::VT_Float, "float" },
|
||||
{ ESM::VT_String, "string" },
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CSV_WORLD_VARTYPEDELEGATE_H
|
||||
#define CSV_WORLD_VARTYPEDELEGATE_H
|
||||
|
||||
#include <components/esm/variant.hpp>
|
||||
|
||||
#include "enumdelegate.hpp"
|
||||
|
||||
namespace CSVWorld
|
||||
|
|
|
@ -31,14 +31,13 @@ namespace
|
|||
template<typename T>
|
||||
bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1)
|
||||
{
|
||||
if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int ||
|
||||
select.mType==ESM::VT_Long)
|
||||
if (select.mValue.getType()==ESM::VT_Int)
|
||||
{
|
||||
return selectCompareImp (select.mSelectRule[4], value1, select.mI);
|
||||
return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getInteger());
|
||||
}
|
||||
else if (select.mType==ESM::VT_Float)
|
||||
else if (select.mValue.getType()==ESM::VT_Float)
|
||||
{
|
||||
return selectCompareImp (select.mSelectRule[4], value1, select.mF);
|
||||
return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getFloat());
|
||||
}
|
||||
else
|
||||
throw std::runtime_error (
|
||||
|
|
|
@ -587,7 +587,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st
|
|||
else
|
||||
mMessageBoxManager->createMessageBox(message);
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
mMessageBoxManager->createInteractiveMessageBox(message, buttons);
|
||||
|
@ -610,8 +610,9 @@ std::string WindowManager::getGameSettingString(const std::string &id, const std
|
|||
const ESM::GameSetting *setting =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search(id);
|
||||
|
||||
if (setting && setting->mType == ESM::VT_String)
|
||||
return setting->getString();
|
||||
if (setting && setting->mValue.getType()==ESM::VT_String)
|
||||
return setting->mValue.getString();
|
||||
|
||||
return default_;
|
||||
}
|
||||
|
||||
|
@ -792,8 +793,8 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r
|
|||
const ESM::GameSetting *setting =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(tag);
|
||||
|
||||
if (setting && setting->mType == ESM::VT_String)
|
||||
_result = setting->getString();
|
||||
if (setting && setting->mValue.getType()==ESM::VT_String)
|
||||
_result = setting->mValue.getString();
|
||||
else
|
||||
_result = tag;
|
||||
}
|
||||
|
|
|
@ -21,21 +21,21 @@ namespace MWWorld
|
|||
Globals::Collection::const_iterator Globals::find (const std::string& name) const
|
||||
{
|
||||
Collection::const_iterator iter = mVariables.find (name);
|
||||
|
||||
|
||||
if (iter==mVariables.end())
|
||||
throw std::runtime_error ("unknown global variable: " + name);
|
||||
|
||||
return iter;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
Globals::Collection::iterator Globals::find (const std::string& name)
|
||||
{
|
||||
Collection::iterator iter = mVariables.find (name);
|
||||
|
||||
|
||||
if (iter==mVariables.end())
|
||||
throw std::runtime_error ("unknown global variable: " + name);
|
||||
|
||||
return iter;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
Globals::Globals (const MWWorld::ESMStore& store)
|
||||
|
@ -46,44 +46,41 @@ namespace MWWorld
|
|||
{
|
||||
char type = ' ';
|
||||
Data value;
|
||||
|
||||
switch (iter->mType)
|
||||
|
||||
switch (iter->mValue.getType())
|
||||
{
|
||||
case ESM::VT_Short:
|
||||
|
||||
|
||||
type = 's';
|
||||
value.mShort = *reinterpret_cast<const Interpreter::Type_Float *> (
|
||||
&iter->mValue);
|
||||
value.mShort = iter->mValue.getInteger();
|
||||
break;
|
||||
|
||||
case ESM::VT_Int:
|
||||
|
||||
|
||||
case ESM::VT_Long:
|
||||
|
||||
type = 'l';
|
||||
value.mLong = *reinterpret_cast<const Interpreter::Type_Float *> (
|
||||
&iter->mValue);
|
||||
value.mLong = iter->mValue.getInteger();
|
||||
break;
|
||||
|
||||
|
||||
case ESM::VT_Float:
|
||||
|
||||
|
||||
type = 'f';
|
||||
value.mFloat = *reinterpret_cast<const Interpreter::Type_Float *> (
|
||||
&iter->mValue);
|
||||
value.mFloat = iter->mValue.getFloat();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
|
||||
throw std::runtime_error ("unsupported global variable type");
|
||||
}
|
||||
}
|
||||
|
||||
mVariables.insert (std::make_pair (iter->mId, std::make_pair (type, value)));
|
||||
}
|
||||
|
||||
|
||||
if (mVariables.find ("dayspassed")==mVariables.end())
|
||||
{
|
||||
// vanilla Morrowind does not define dayspassed.
|
||||
Data value;
|
||||
value.mLong = 0;
|
||||
|
||||
|
||||
mVariables.insert (std::make_pair ("dayspassed", std::make_pair ('l', value)));
|
||||
}
|
||||
}
|
||||
|
@ -91,31 +88,31 @@ namespace MWWorld
|
|||
const Globals::Data& Globals::operator[] (const std::string& name) const
|
||||
{
|
||||
Collection::const_iterator iter = find (name);
|
||||
|
||||
|
||||
return iter->second.second;
|
||||
}
|
||||
|
||||
Globals::Data& Globals::operator[] (const std::string& name)
|
||||
{
|
||||
Collection::iterator iter = find (name);
|
||||
|
||||
|
||||
return iter->second.second;
|
||||
}
|
||||
|
||||
|
||||
void Globals::setInt (const std::string& name, int value)
|
||||
{
|
||||
Collection::iterator iter = find (name);
|
||||
|
||||
|
||||
switch (iter->second.first)
|
||||
{
|
||||
case 's': iter->second.second.mShort = value; break;
|
||||
case 'l': iter->second.second.mLong = value; break;
|
||||
case 'f': iter->second.second.mFloat = value; break;
|
||||
|
||||
|
||||
default: throw std::runtime_error ("unsupported global variable type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Globals::setFloat (const std::string& name, float value)
|
||||
{
|
||||
Collection::iterator iter = find (name);
|
||||
|
@ -127,9 +124,9 @@ namespace MWWorld
|
|||
case 'f': iter->second.second.mFloat = value; break;
|
||||
|
||||
default: throw std::runtime_error ("unsupported global variable type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Globals::getInt (const std::string& name) const
|
||||
{
|
||||
Collection::const_iterator iter = find (name);
|
||||
|
@ -141,13 +138,13 @@ namespace MWWorld
|
|||
case 'f': return iter->second.second.mFloat;
|
||||
|
||||
default: throw std::runtime_error ("unsupported global variable type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Globals::getFloat (const std::string& name) const
|
||||
{
|
||||
Collection::const_iterator iter = find (name);
|
||||
|
||||
|
||||
switch (iter->second.first)
|
||||
{
|
||||
case 's': return iter->second.second.mShort;
|
||||
|
@ -155,16 +152,16 @@ namespace MWWorld
|
|||
case 'f': return iter->second.second.mFloat;
|
||||
|
||||
default: throw std::runtime_error ("unsupported global variable type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char Globals::getType (const std::string& name) const
|
||||
{
|
||||
Collection::const_iterator iter = mVariables.find (name);
|
||||
|
||||
|
||||
if (iter==mVariables.end())
|
||||
return ' ';
|
||||
|
||||
|
||||
return iter->second.first;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ namespace MWWorld
|
|||
for (std::vector<std::string>::size_type i = 0; i < master.size(); i++, idx++)
|
||||
{
|
||||
boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master[i]));
|
||||
|
||||
|
||||
std::cout << "Loading ESM " << masterPath.string() << "\n";
|
||||
|
||||
// This parses the ESM file
|
||||
|
@ -210,11 +210,11 @@ namespace MWWorld
|
|||
mEsm[idx] = lEsm;
|
||||
mStore.load (mEsm[idx]);
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<std::string>::size_type i = 0; i < plugins.size(); i++, idx++)
|
||||
{
|
||||
boost::filesystem::path pluginPath (fileCollections.getCollection (".esp").getPath (plugins[i]));
|
||||
|
||||
|
||||
std::cout << "Loading ESP " << pluginPath.string() << "\n";
|
||||
|
||||
// This parses the ESP file
|
||||
|
@ -226,7 +226,7 @@ namespace MWWorld
|
|||
mEsm[idx] = lEsm;
|
||||
mStore.load (mEsm[idx]);
|
||||
}
|
||||
|
||||
|
||||
mStore.setUp();
|
||||
|
||||
mPlayer = new MWWorld::Player (mStore.get<ESM::NPC>().find ("player"), *this);
|
||||
|
@ -363,10 +363,8 @@ namespace MWWorld
|
|||
const ESM::GameSetting *setting =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().search("sDefaultCellname");
|
||||
|
||||
if (setting && setting->mType == ESM::VT_String)
|
||||
name = setting->getString();
|
||||
else
|
||||
name = "Wilderness";
|
||||
if (setting && setting->mValue.getType()==ESM::VT_String)
|
||||
name = setting->mValue.getString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ add_component_dir (esm
|
|||
loadclas loadclot loadcont loadcrea loadcrec loaddial loaddoor loadench loadfact loadglob loadgmst
|
||||
loadinfo loadingr loadland loadlevlist loadligh loadlocks loadltex loadmgef loadmisc loadnpcc
|
||||
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
||||
loadweap records aipackage effectlist spelllist
|
||||
loadweap records aipackage effectlist spelllist variant variantimp
|
||||
)
|
||||
|
||||
add_component_dir (misc
|
||||
|
|
|
@ -9,18 +9,6 @@ namespace ESM
|
|||
// Pixel color value. Standard four-byte rr,gg,bb,aa format.
|
||||
typedef int32_t Color;
|
||||
|
||||
enum VarType
|
||||
{
|
||||
VT_Unknown,
|
||||
VT_None,
|
||||
VT_Short,
|
||||
VT_Int,
|
||||
VT_Long,
|
||||
VT_Float,
|
||||
VT_String,
|
||||
VT_Ignored
|
||||
};
|
||||
|
||||
enum Specialization
|
||||
{
|
||||
SPC_Combat = 0,
|
||||
|
|
|
@ -1,57 +1,24 @@
|
|||
#include "loadglob.hpp"
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void Global::load(ESMReader &esm)
|
||||
{
|
||||
std::string tmp = esm.getHNString("FNAM");
|
||||
if (tmp == "s")
|
||||
mType = VT_Short;
|
||||
else if (tmp == "l")
|
||||
mType = VT_Int;
|
||||
else if (tmp == "f")
|
||||
mType = VT_Float;
|
||||
else
|
||||
esm.fail("Illegal global variable type " + tmp);
|
||||
|
||||
// Note: Both floats and longs are represented as floats.
|
||||
esm.getHNT(mValue, "FLTV");
|
||||
}
|
||||
|
||||
void Global::save(ESMWriter &esm)
|
||||
{
|
||||
switch(mType)
|
||||
void Global::load (ESMReader &esm)
|
||||
{
|
||||
case VT_Short:
|
||||
esm.writeHNString("FNAM", "s");
|
||||
break;
|
||||
|
||||
case VT_Int:
|
||||
esm.writeHNString("FNAM", "l");
|
||||
break;
|
||||
|
||||
case VT_Float:
|
||||
esm.writeHNString("FNAM", "f");
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
mValue.read (esm, ESM::Variant::Format_Global);
|
||||
}
|
||||
|
||||
void Global::save (ESMWriter &esm)
|
||||
{
|
||||
mValue.write (esm, ESM::Variant::Format_Global);
|
||||
}
|
||||
esm.writeHNT("FLTV", mValue);
|
||||
}
|
||||
|
||||
void Global::blank()
|
||||
{
|
||||
mValue = 0;
|
||||
mType = VT_Float;
|
||||
mValue.setType (ESM::VT_None);
|
||||
}
|
||||
|
||||
bool operator== (const Global& left, const Global& right)
|
||||
{
|
||||
return left.mId==right.mId && left.mValue==right.mValue && left.mType==right.mType;
|
||||
return left.mId==right.mId && left.mValue==right.mValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "defs.hpp"
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -18,8 +18,7 @@ class ESMWriter;
|
|||
struct Global
|
||||
{
|
||||
std::string mId;
|
||||
float mValue;
|
||||
VarType mType;
|
||||
Variant mValue;
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
|
|
|
@ -1,104 +1,39 @@
|
|||
#include "loadgmst.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void GameSetting::load(ESMReader &esm)
|
||||
{
|
||||
assert(mId != "");
|
||||
|
||||
// We are apparently allowed to be empty
|
||||
if (!esm.hasMoreSubs())
|
||||
void GameSetting::load (ESMReader &esm)
|
||||
{
|
||||
mType = VT_None;
|
||||
return;
|
||||
mValue.read (esm, ESM::Variant::Format_Gmst);
|
||||
}
|
||||
|
||||
// Load some data
|
||||
esm.getSubName();
|
||||
NAME n = esm.retSubName();
|
||||
if (n == "STRV")
|
||||
void GameSetting::save (ESMWriter &esm)
|
||||
{
|
||||
mStr = esm.getHString();
|
||||
mType = VT_String;
|
||||
mValue.write (esm, ESM::Variant::Format_Gmst);
|
||||
}
|
||||
else if (n == "INTV")
|
||||
{
|
||||
esm.getHT(mI);
|
||||
mType = VT_Int;
|
||||
}
|
||||
else if (n == "FLTV")
|
||||
{
|
||||
esm.getHT(mF);
|
||||
mType = VT_Float;
|
||||
}
|
||||
else
|
||||
esm.fail("Unwanted subrecord type");
|
||||
}
|
||||
|
||||
void GameSetting::save(ESMWriter &esm)
|
||||
{
|
||||
switch(mType)
|
||||
int GameSetting::getInt() const
|
||||
{
|
||||
case VT_String: esm.writeHNString("STRV", mStr); break;
|
||||
case VT_Int: esm.writeHNT("INTV", mI); break;
|
||||
case VT_Float: esm.writeHNT("FLTV", mF); break;
|
||||
default: break;
|
||||
return mValue.getInteger();
|
||||
}
|
||||
}
|
||||
|
||||
int GameSetting::getInt() const
|
||||
{
|
||||
switch (mType)
|
||||
float GameSetting::getFloat() const
|
||||
{
|
||||
case VT_Float: return static_cast<int> (mF);
|
||||
case VT_Int: return mI;
|
||||
default: throw std::runtime_error ("GMST " + mId + " is not of a numeric type");
|
||||
return mValue.getFloat();
|
||||
}
|
||||
}
|
||||
|
||||
float GameSetting::getFloat() const
|
||||
{
|
||||
switch (mType)
|
||||
std::string GameSetting::getString() const
|
||||
{
|
||||
case VT_Float: return mF;
|
||||
case VT_Int: return mI;
|
||||
default: throw std::runtime_error ("GMST " + mId + " is not of a numeric type");
|
||||
return mValue.getString();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GameSetting::getString() const
|
||||
{
|
||||
if (mType==VT_String)
|
||||
return mStr;
|
||||
|
||||
throw std::runtime_error ("GMST " + mId + " is not a string");
|
||||
}
|
||||
|
||||
void GameSetting::blank()
|
||||
{
|
||||
mStr.clear();
|
||||
mI = 0;
|
||||
mF = 0;
|
||||
mType = VT_Float;
|
||||
mValue.setType (ESM::VT_None);
|
||||
}
|
||||
|
||||
bool operator== (const GameSetting& left, const GameSetting& right)
|
||||
{
|
||||
if (left.mType!=right.mType)
|
||||
return false;
|
||||
|
||||
switch (left.mType)
|
||||
{
|
||||
case VT_Float: return left.mF==right.mF;
|
||||
case VT_Int: return left.mI==right.mI;
|
||||
case VT_String: return left.mStr==right.mStr;
|
||||
default: return false;
|
||||
}
|
||||
return left.mValue==right.mValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "defs.hpp"
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -19,14 +19,13 @@ class ESMWriter;
|
|||
struct GameSetting
|
||||
{
|
||||
std::string mId;
|
||||
// One of these is used depending on the variable type
|
||||
std::string mStr;
|
||||
int mI;
|
||||
float mF;
|
||||
VarType mType;
|
||||
|
||||
Variant mValue;
|
||||
|
||||
void load(ESMReader &esm);
|
||||
|
||||
/// \todo remove the get* functions (redundant, since mValue as equivalent functions now).
|
||||
|
||||
int getInt() const;
|
||||
///< Throws an exception if GMST is not of type int or float.
|
||||
|
||||
|
|
|
@ -84,22 +84,8 @@ void DialInfo::load(ESMReader &esm)
|
|||
SelectStruct ss;
|
||||
|
||||
ss.mSelectRule = esm.getHString();
|
||||
esm.isEmptyOrGetName();
|
||||
|
||||
if (subName.val == REC_INTV)
|
||||
{
|
||||
ss.mType = VT_Int;
|
||||
esm.getHT(ss.mI);
|
||||
}
|
||||
else if (subName.val == REC_FLTV)
|
||||
{
|
||||
ss.mType = VT_Float;
|
||||
esm.getHT(ss.mF);
|
||||
}
|
||||
else
|
||||
esm.fail(
|
||||
"INFO.SCVR must precede INTV or FLTV, not "
|
||||
+ subName.toString());
|
||||
ss.mValue.read (esm, Variant::Format_Info);
|
||||
|
||||
mSelects.push_back(ss);
|
||||
|
||||
|
@ -152,16 +138,11 @@ void DialInfo::save(ESMWriter &esm)
|
|||
for (std::vector<SelectStruct>::iterator it = mSelects.begin(); it != mSelects.end(); ++it)
|
||||
{
|
||||
esm.writeHNString("SCVR", it->mSelectRule);
|
||||
switch(it->mType)
|
||||
{
|
||||
case VT_Int: esm.writeHNT("INTV", it->mI); break;
|
||||
case VT_Float: esm.writeHNT("FLTV", it->mF); break;
|
||||
default: break;
|
||||
}
|
||||
it->mValue.write (esm, Variant::Format_Info);
|
||||
}
|
||||
|
||||
esm.writeHNOString("BNAM", mResultScript);
|
||||
|
||||
|
||||
switch(mQuestStatus)
|
||||
{
|
||||
case QS_Name: esm.writeHNT("QSTN",'\1'); break;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "defs.hpp"
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -12,8 +13,6 @@ namespace ESM
|
|||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
// NOT DONE
|
||||
|
||||
/*
|
||||
* Dialogue information. A series of these follow after DIAL records,
|
||||
* and form a linked list of dialogue items.
|
||||
|
@ -43,9 +42,7 @@ struct DialInfo
|
|||
struct SelectStruct
|
||||
{
|
||||
std::string mSelectRule; // This has a complicated format
|
||||
float mF; // Only one of 'f' or 'i' is used
|
||||
int mI;
|
||||
VarType mType;
|
||||
Variant mValue;
|
||||
};
|
||||
|
||||
// Journal quest indices (introduced with the quest system in Tribunal)
|
||||
|
@ -93,8 +90,7 @@ struct DialInfo
|
|||
REC_SNAM = 0x4d414e53,
|
||||
REC_NAME = 0x454d414e,
|
||||
REC_SCVR = 0x52564353,
|
||||
REC_INTV = 0x56544e49,
|
||||
REC_FLTV = 0x56544c46,
|
||||
|
||||
REC_BNAM = 0x4d414e42,
|
||||
REC_QSTN = 0x4e545351,
|
||||
REC_QSTF = 0x46545351,
|
||||
|
@ -106,42 +102,5 @@ struct DialInfo
|
|||
void save(ESMWriter &esm);
|
||||
};
|
||||
|
||||
/*
|
||||
Some old and unused D code and comments, that might be useful later:
|
||||
--------
|
||||
|
||||
// We only need to put each item in ONE list. For if your NPC
|
||||
// matches this response, then it must match ALL criteria, thus it
|
||||
// will have to look up itself in all the lists. I think the order
|
||||
// is well optimized in making the lists as small as possible.
|
||||
if(this.actor.index != -1) actorDial[this.actor][parent]++;
|
||||
else if(cell != "") cellDial[cell][parent]++;
|
||||
else if(this.Class != -1) classDial[this.Class][parent]++;
|
||||
else if(this.npcFaction != -1)
|
||||
factionDial[this.npcFaction][parent]++;
|
||||
else if(this.race != -1) raceDial[this.race][parent]++;
|
||||
else allDial[parent]++; // Lists dialogues that might
|
||||
// apply to all npcs.
|
||||
*/
|
||||
|
||||
// List of dialogue topics (and greetings, voices, etc.) that
|
||||
// reference other objects. Eg. raceDial is indexed by the indices of
|
||||
// all races referenced. The value of raceDial is a new AA, which is
|
||||
// basically used as a map (the int value is just a count and isn't
|
||||
// used for anything important.) The indices (or elements of the map)
|
||||
// are the dialogues that reference the given race. I use an AA
|
||||
// instead of a list or array, since each dialogue can be added lots
|
||||
// of times.
|
||||
|
||||
/*
|
||||
int allDial[Dialogue*];
|
||||
int classDial[int][Dialogue*];
|
||||
int factionDial[int][Dialogue*];
|
||||
int actorDial[Item][Dialogue*];
|
||||
// If I look up cells on cell load, I don't have to resolve these
|
||||
// names into anything!
|
||||
int cellDial[char[]][Dialogue*];
|
||||
int raceDial[int][Dialogue*];
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
|
282
components/esm/variant.cpp
Normal file
282
components/esm/variant.cpp
Normal file
|
@ -0,0 +1,282 @@
|
|||
#include "variant.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "variantimp.hpp"
|
||||
|
||||
ESM::Variant::Variant() : mType (VT_None), mData (0) {}
|
||||
|
||||
ESM::Variant::~Variant()
|
||||
{
|
||||
delete mData;
|
||||
}
|
||||
|
||||
ESM::Variant& ESM::Variant::operator= (const Variant& variant)
|
||||
{
|
||||
if (&variant!=this)
|
||||
{
|
||||
VariantDataBase *newData = variant.mData ? variant.mData->clone() : 0;
|
||||
|
||||
delete mData;
|
||||
|
||||
mType = variant.mType;
|
||||
mData = newData;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ESM::Variant::Variant (const Variant& variant)
|
||||
: mType (variant.mType), mData (variant.mData ? variant.mData->clone() : 0)
|
||||
{}
|
||||
|
||||
ESM::VarType ESM::Variant::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
std::string ESM::Variant::getString() const
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not convert empty variant to string");
|
||||
|
||||
return mData->getString();
|
||||
}
|
||||
|
||||
int ESM::Variant::getInteger() const
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not convert empty variant to integer");
|
||||
|
||||
return mData->getInteger();
|
||||
}
|
||||
|
||||
float ESM::Variant::getFloat() const
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not convert empty variant to float");
|
||||
|
||||
return mData->getFloat();
|
||||
}
|
||||
|
||||
void ESM::Variant::read (ESMReader& esm, Format format)
|
||||
{
|
||||
// type
|
||||
VarType type = VT_Unknown;
|
||||
|
||||
if (format==Format_Global)
|
||||
{
|
||||
std::string typeId = esm.getHNString ("FNAM");
|
||||
|
||||
if (typeId == "s")
|
||||
type = VT_Short;
|
||||
else if (typeId == "l")
|
||||
type = VT_Long;
|
||||
else if (typeId == "f")
|
||||
type = VT_Float;
|
||||
else
|
||||
esm.fail ("illegal global variable type " + typeId);
|
||||
}
|
||||
else if (format==Format_Gmst)
|
||||
{
|
||||
if (!esm.hasMoreSubs())
|
||||
{
|
||||
type = VT_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
esm.getSubName();
|
||||
NAME name = esm.retSubName();
|
||||
|
||||
if (name=="STRV")
|
||||
{
|
||||
type = VT_String;
|
||||
}
|
||||
else if (name=="INTV")
|
||||
{
|
||||
type = VT_Int;
|
||||
}
|
||||
else if (name=="FLTV")
|
||||
{
|
||||
type = VT_Float;
|
||||
}
|
||||
else
|
||||
esm.fail ("invalid subrecord: " + name.toString());
|
||||
}
|
||||
}
|
||||
else // info
|
||||
{
|
||||
esm.getSubName();
|
||||
NAME name = esm.retSubName();
|
||||
|
||||
if (name=="INTV")
|
||||
{
|
||||
type = VT_Int;
|
||||
}
|
||||
else if (name=="FLTV")
|
||||
{
|
||||
type = VT_Float;
|
||||
}
|
||||
else
|
||||
esm.fail ("invalid subrecord: " + name.toString());
|
||||
}
|
||||
|
||||
setType (type);
|
||||
|
||||
// data
|
||||
if (mData)
|
||||
mData->read (esm, format, mType);
|
||||
}
|
||||
|
||||
void ESM::Variant::write (ESMWriter& esm, Format format) const
|
||||
{
|
||||
if (mType==VT_Unknown)
|
||||
{
|
||||
throw std::runtime_error ("can not serialise variant of unknown type");
|
||||
}
|
||||
else if (mType==VT_None)
|
||||
{
|
||||
if (format==Format_Global)
|
||||
throw std::runtime_error ("can not serialise variant of type none to global format");
|
||||
|
||||
if (format==Format_Info)
|
||||
throw std::runtime_error ("can not serialise variant of type none to info format");
|
||||
|
||||
// nothing to do here for GMST format
|
||||
}
|
||||
else
|
||||
mData->write (esm, format, mType);
|
||||
}
|
||||
|
||||
void ESM::Variant::write (std::ostream& stream) const
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case VT_Unknown:
|
||||
|
||||
stream << "variant unknown";
|
||||
break;
|
||||
|
||||
case VT_None:
|
||||
|
||||
stream << "variant none";
|
||||
break;
|
||||
|
||||
case VT_Short:
|
||||
|
||||
stream << "variant short: " << mData->getInteger();
|
||||
break;
|
||||
|
||||
case VT_Int:
|
||||
|
||||
stream << "variant int: " << mData->getInteger();
|
||||
break;
|
||||
|
||||
case VT_Long:
|
||||
|
||||
stream << "variant long: " << mData->getInteger();
|
||||
break;
|
||||
|
||||
case VT_Float:
|
||||
|
||||
stream << "variant float: " << mData->getFloat();
|
||||
break;
|
||||
|
||||
case VT_String:
|
||||
|
||||
stream << "variant string: \"" << mData->getString() << "\2";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ESM::Variant::setType (VarType type)
|
||||
{
|
||||
if (type!=mType)
|
||||
{
|
||||
VariantDataBase *newData = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case VT_Unknown:
|
||||
case VT_None:
|
||||
|
||||
break; // no data
|
||||
|
||||
case VT_Short:
|
||||
case VT_Int:
|
||||
case VT_Long:
|
||||
|
||||
newData = new VariantIntegerData (mData);
|
||||
break;
|
||||
|
||||
case VT_Float:
|
||||
|
||||
newData = new VariantFloatData (mData);
|
||||
break;
|
||||
|
||||
case VT_String:
|
||||
|
||||
newData = new VariantStringData (mData);
|
||||
break;
|
||||
}
|
||||
|
||||
delete mData;
|
||||
mData = newData;
|
||||
mType = type;
|
||||
}
|
||||
}
|
||||
|
||||
void ESM::Variant::setString (const std::string& value)
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not assign string to empty variant");
|
||||
|
||||
mData->setString (value);
|
||||
}
|
||||
|
||||
void ESM::Variant::setInteger (int value)
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not assign integer to empty variant");
|
||||
|
||||
mData->setInteger (value);
|
||||
}
|
||||
|
||||
void ESM::Variant::setFloat (float value)
|
||||
{
|
||||
if (!mData)
|
||||
throw std::runtime_error ("can not assign float to empty variant");
|
||||
|
||||
mData->setFloat (value);
|
||||
}
|
||||
|
||||
bool ESM::Variant::isEqual (const Variant& value) const
|
||||
{
|
||||
if (mType!=value.mType)
|
||||
return false;
|
||||
|
||||
if (!mData)
|
||||
return true;
|
||||
|
||||
assert (value.mData);
|
||||
|
||||
return mData->isEqual (*value.mData);
|
||||
}
|
||||
|
||||
std::ostream& ESM::operator<< (std::ostream& stream, const Variant& value)
|
||||
{
|
||||
value.write (stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool ESM::operator== (const Variant& left, const Variant& right)
|
||||
{
|
||||
return left.isEqual (right);
|
||||
}
|
||||
|
||||
bool ESM::operator!= (const Variant& left, const Variant& right)
|
||||
{
|
||||
return !(left==right);
|
||||
}
|
86
components/esm/variant.hpp
Normal file
86
components/esm/variant.hpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifndef OPENMW_ESM_VARIANT_H
|
||||
#define OPENMW_ESM_VARIANT_H
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
enum VarType
|
||||
{
|
||||
VT_Unknown,
|
||||
VT_None,
|
||||
VT_Short, // stored as a float, kinda
|
||||
VT_Int,
|
||||
VT_Long, // stored as a float
|
||||
VT_Float,
|
||||
VT_String
|
||||
};
|
||||
|
||||
class VariantDataBase;
|
||||
|
||||
class Variant
|
||||
{
|
||||
VarType mType;
|
||||
VariantDataBase *mData;
|
||||
|
||||
public:
|
||||
|
||||
enum Format
|
||||
{
|
||||
Format_Global,
|
||||
Format_Gmst,
|
||||
Format_Info
|
||||
};
|
||||
|
||||
Variant();
|
||||
|
||||
~Variant();
|
||||
|
||||
Variant& operator= (const Variant& variant);
|
||||
|
||||
Variant (const Variant& variant);
|
||||
|
||||
VarType getType() const;
|
||||
|
||||
std::string getString() const;
|
||||
///< Will throw an exception, if value can not be represented as a string.
|
||||
|
||||
int getInteger() const;
|
||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
||||
/// casting of float values is permitted).
|
||||
|
||||
float getFloat() const;
|
||||
///< Will throw an exception, if value can not be represented as a float value.
|
||||
|
||||
void read (ESMReader& esm, Format format);
|
||||
|
||||
void write (ESMWriter& esm, Format format) const;
|
||||
|
||||
void write (std::ostream& stream) const;
|
||||
///< Write in text format.
|
||||
|
||||
void setType (VarType type);
|
||||
|
||||
void setString (const std::string& value);
|
||||
///< Will throw an exception, if type is not compatible with string.
|
||||
|
||||
void setInteger (int value);
|
||||
///< Will throw an exception, if type is not compatible with integer.
|
||||
|
||||
void setFloat (float value);
|
||||
///< Will throw an exception, if type is not compatible with float.
|
||||
|
||||
bool isEqual (const Variant& value) const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Variant& value);
|
||||
|
||||
bool operator== (const Variant& left, const Variant& right);
|
||||
bool operator!= (const Variant& left, const Variant& right);
|
||||
}
|
||||
|
||||
#endif
|
280
components/esm/variantimp.cpp
Normal file
280
components/esm/variantimp.cpp
Normal file
|
@ -0,0 +1,280 @@
|
|||
|
||||
#include "variantimp.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
ESM::VariantDataBase::~VariantDataBase() {}
|
||||
|
||||
std::string ESM::VariantDataBase::getString (bool default_) const
|
||||
{
|
||||
if (default_)
|
||||
return "";
|
||||
|
||||
throw std::runtime_error ("can not convert variant to string");
|
||||
}
|
||||
|
||||
int ESM::VariantDataBase::getInteger (bool default_) const
|
||||
{
|
||||
if (default_)
|
||||
return 0;
|
||||
|
||||
throw std::runtime_error ("can not convert variant to integer");
|
||||
}
|
||||
|
||||
float ESM::VariantDataBase::getFloat (bool default_) const
|
||||
{
|
||||
if (default_)
|
||||
return 0;
|
||||
|
||||
throw std::runtime_error ("can not convert variant to float");
|
||||
}
|
||||
|
||||
void ESM::VariantDataBase::setString (const std::string& value)
|
||||
{
|
||||
throw std::runtime_error ("conversion of string to variant not possible");
|
||||
}
|
||||
|
||||
void ESM::VariantDataBase::setInteger (int value)
|
||||
{
|
||||
throw std::runtime_error ("conversion of integer to variant not possible");
|
||||
}
|
||||
|
||||
void ESM::VariantDataBase::setFloat (float value)
|
||||
{
|
||||
throw std::runtime_error ("conversion of float to variant not possible");
|
||||
}
|
||||
|
||||
|
||||
|
||||
ESM::VariantStringData::VariantStringData (const VariantDataBase *data)
|
||||
{
|
||||
if (data)
|
||||
mValue = data->getString (true);
|
||||
}
|
||||
|
||||
ESM::VariantDataBase *ESM::VariantStringData::clone() const
|
||||
{
|
||||
return new VariantStringData (*this);
|
||||
}
|
||||
|
||||
std::string ESM::VariantStringData::getString (bool default_) const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void ESM::VariantStringData::setString (const std::string& value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarType type)
|
||||
{
|
||||
if (type!=VT_String)
|
||||
throw std::logic_error ("not a string type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
esm.fail ("global variables of type string not supported");
|
||||
|
||||
if (format==Variant::Format_Info)
|
||||
esm.fail ("info variables of type string not supported");
|
||||
|
||||
// GMST
|
||||
mValue = esm.getHString();
|
||||
}
|
||||
|
||||
void ESM::VariantStringData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
||||
{
|
||||
if (type!=VT_String)
|
||||
throw std::logic_error ("not a string type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
throw std::runtime_error ("global variables of type string not supported");
|
||||
|
||||
if (format==Variant::Format_Info)
|
||||
throw std::runtime_error ("info variables of type string not supported");
|
||||
|
||||
// GMST
|
||||
esm.writeHNString ("STRV", mValue);
|
||||
}
|
||||
|
||||
bool ESM::VariantStringData::isEqual (const VariantDataBase& value) const
|
||||
{
|
||||
return dynamic_cast<const VariantStringData&> (value).mValue==mValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ESM::VariantIntegerData::VariantIntegerData (const VariantDataBase *data) : mValue (0)
|
||||
{
|
||||
if (data)
|
||||
mValue = data->getInteger (true);
|
||||
}
|
||||
|
||||
ESM::VariantDataBase *ESM::VariantIntegerData::clone() const
|
||||
{
|
||||
return new VariantIntegerData (*this);
|
||||
}
|
||||
|
||||
int ESM::VariantIntegerData::getInteger (bool default_) const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
float ESM::VariantIntegerData::getFloat (bool default_) const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void ESM::VariantIntegerData::setInteger (int value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
void ESM::VariantIntegerData::setFloat (float value)
|
||||
{
|
||||
mValue = static_cast<int> (value);
|
||||
}
|
||||
|
||||
void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarType type)
|
||||
{
|
||||
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
||||
throw std::logic_error ("not an integer type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
{
|
||||
float value;
|
||||
esm.getHNT (value, "FLTV");
|
||||
|
||||
if (type==VT_Short)
|
||||
{
|
||||
if (value!=value)
|
||||
mValue = 0; // nan
|
||||
else
|
||||
mValue = static_cast<short> (value);
|
||||
}
|
||||
else if (type==VT_Long)
|
||||
mValue = static_cast<int> (value);
|
||||
else
|
||||
esm.fail ("unsupported global variable integer type");
|
||||
}
|
||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
|
||||
{
|
||||
if (type!=VT_Int)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream
|
||||
<< "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info")
|
||||
<< " variable integer type";
|
||||
esm.fail (stream.str());
|
||||
}
|
||||
|
||||
esm.getHT (mValue);
|
||||
}
|
||||
}
|
||||
|
||||
void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
||||
{
|
||||
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
||||
throw std::logic_error ("not an integer type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
{
|
||||
if (type==VT_Short || type==VT_Long)
|
||||
{
|
||||
float value = mValue;
|
||||
esm.writeHNString ("FNAM", type==VT_Short ? "s" : "l");
|
||||
esm.writeHNT ("FLTV", value);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error ("unsupported global variable integer type");
|
||||
}
|
||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
|
||||
{
|
||||
if (type==VT_Int)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream
|
||||
<< "unsupported " <<(format==Variant::Format_Gmst ? "gmst" : "info")
|
||||
<< " variable integer type";
|
||||
throw std::runtime_error (stream.str());
|
||||
}
|
||||
|
||||
esm.writeHNT ("INTV", mValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool ESM::VariantIntegerData::isEqual (const VariantDataBase& value) const
|
||||
{
|
||||
return dynamic_cast<const VariantIntegerData&> (value).mValue==mValue;
|
||||
}
|
||||
|
||||
|
||||
ESM::VariantFloatData::VariantFloatData (const VariantDataBase *data) : mValue (0)
|
||||
{
|
||||
if (data)
|
||||
mValue = data->getFloat (true);
|
||||
}
|
||||
|
||||
ESM::VariantDataBase *ESM::VariantFloatData::clone() const
|
||||
{
|
||||
return new VariantFloatData (*this);
|
||||
}
|
||||
|
||||
int ESM::VariantFloatData::getInteger (bool default_) const
|
||||
{
|
||||
return static_cast<int> (mValue);
|
||||
}
|
||||
|
||||
float ESM::VariantFloatData::getFloat (bool default_) const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void ESM::VariantFloatData::setInteger (int value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
void ESM::VariantFloatData::setFloat (float value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
void ESM::VariantFloatData::read (ESMReader& esm, Variant::Format format, VarType type)
|
||||
{
|
||||
if (type!=VT_Float)
|
||||
throw std::logic_error ("not a float type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
{
|
||||
esm.getHNT (mValue, "FLTV");
|
||||
}
|
||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
|
||||
{
|
||||
esm.getHT (mValue);
|
||||
}
|
||||
}
|
||||
|
||||
void ESM::VariantFloatData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
||||
{
|
||||
if (type!=VT_Float)
|
||||
throw std::logic_error ("not a float type");
|
||||
|
||||
if (format==Variant::Format_Global)
|
||||
{
|
||||
esm.writeHNString ("FNAM", "f");
|
||||
esm.writeHNT ("FLTV", mValue);
|
||||
}
|
||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info)
|
||||
{
|
||||
esm.writeHNT ("FLTV", mValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool ESM::VariantFloatData::isEqual (const VariantDataBase& value) const
|
||||
{
|
||||
return dynamic_cast<const VariantFloatData&> (value).mValue==mValue;
|
||||
}
|
179
components/esm/variantimp.hpp
Normal file
179
components/esm/variantimp.hpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
#ifndef OPENMW_ESM_VARIANTIMP_H
|
||||
#define OPENMW_ESM_VARIANTIMP_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class VariantDataBase
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~VariantDataBase();
|
||||
|
||||
virtual VariantDataBase *clone() const = 0;
|
||||
|
||||
virtual std::string getString (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as a string.
|
||||
///
|
||||
/// \note Numeric values are not converted to strings.
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual int getInteger (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
||||
/// casting of float values is permitted).
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual float getFloat (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as a float value.
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual void setString (const std::string& value);
|
||||
///< Will throw an exception, if type is not compatible with string.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual void setInteger (int value);
|
||||
///< Will throw an exception, if type is not compatible with integer.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual void setFloat (float value);
|
||||
///< Will throw an exception, if type is not compatible with float.
|
||||
///
|
||||
/// Default-implementation: throw an exception.
|
||||
|
||||
virtual void read (ESMReader& esm, Variant::Format format, VarType type) = 0;
|
||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
||||
|
||||
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const = 0;
|
||||
///< If \a type is not supported by \a format, an exception is thrown.
|
||||
|
||||
virtual bool isEqual (const VariantDataBase& value) const = 0;
|
||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
||||
|
||||
};
|
||||
|
||||
class VariantStringData : public VariantDataBase
|
||||
{
|
||||
std::string mValue;
|
||||
|
||||
public:
|
||||
|
||||
VariantStringData (const VariantDataBase *data = 0);
|
||||
///< Calling the constructor with an incompatible data type will result in a silent
|
||||
/// default initialisation.
|
||||
|
||||
virtual VariantDataBase *clone() const;
|
||||
|
||||
virtual std::string getString (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as a string.
|
||||
///
|
||||
/// \note Numeric values are not converted to strings.
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
|
||||
virtual void setString (const std::string& value);
|
||||
///< Will throw an exception, if type is not compatible with string.
|
||||
|
||||
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
|
||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
||||
|
||||
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
|
||||
///< If \a type is not supported by \a format, an exception is thrown.
|
||||
|
||||
virtual bool isEqual (const VariantDataBase& value) const;
|
||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
||||
};
|
||||
|
||||
class VariantIntegerData : public VariantDataBase
|
||||
{
|
||||
int mValue;
|
||||
|
||||
public:
|
||||
|
||||
VariantIntegerData (const VariantDataBase *data = 0);
|
||||
///< Calling the constructor with an incompatible data type will result in a silent
|
||||
/// default initialisation.
|
||||
|
||||
virtual VariantDataBase *clone() const;
|
||||
|
||||
virtual int getInteger (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
||||
/// casting of float values is permitted).
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
|
||||
virtual float getFloat (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as a float value.
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
|
||||
virtual void setInteger (int value);
|
||||
///< Will throw an exception, if type is not compatible with integer.
|
||||
|
||||
virtual void setFloat (float value);
|
||||
///< Will throw an exception, if type is not compatible with float.
|
||||
|
||||
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
|
||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
||||
|
||||
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
|
||||
///< If \a type is not supported by \a format, an exception is thrown.
|
||||
|
||||
virtual bool isEqual (const VariantDataBase& value) const;
|
||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
||||
};
|
||||
|
||||
class VariantFloatData : public VariantDataBase
|
||||
{
|
||||
float mValue;
|
||||
|
||||
public:
|
||||
|
||||
VariantFloatData (const VariantDataBase *data = 0);
|
||||
///< Calling the constructor with an incompatible data type will result in a silent
|
||||
/// default initialisation.
|
||||
|
||||
virtual VariantDataBase *clone() const;
|
||||
|
||||
virtual int getInteger (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
||||
/// casting of float values is permitted).
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
|
||||
virtual float getFloat (bool default_ = false) const;
|
||||
///< Will throw an exception, if value can not be represented as a float value.
|
||||
///
|
||||
/// \param default_ Return a default value instead of throwing an exception.
|
||||
|
||||
virtual void setInteger (int value);
|
||||
///< Will throw an exception, if type is not compatible with integer.
|
||||
|
||||
virtual void setFloat (float value);
|
||||
///< Will throw an exception, if type is not compatible with float.
|
||||
|
||||
virtual void read (ESMReader& esm, Variant::Format format, VarType type);
|
||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
||||
|
||||
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const;
|
||||
///< If \a type is not supported by \a format, an exception is thrown.
|
||||
|
||||
virtual bool isEqual (const VariantDataBase& value) const;
|
||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue