mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-01 21:41:34 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
b44fc1904b
112 changed files with 1158 additions and 469 deletions
|
@ -51,6 +51,8 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binarie
|
||||||
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||||
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||||
|
|
||||||
|
set(CUSTOM_OGRE_PLUGIN_DIR "" CACHE PATH "Specify a custom directory for Ogre plugins (autodetected by default)")
|
||||||
|
|
||||||
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
||||||
|
|
||||||
# Apps and tools
|
# Apps and tools
|
||||||
|
@ -323,8 +325,10 @@ if (APPLE AND OPENMW_OSX_DEPLOYMENT)
|
||||||
# make it empty so plugin loading code can check this and try to find plugins inside app bundle
|
# make it empty so plugin loading code can check this and try to find plugins inside app bundle
|
||||||
add_definitions(-DOGRE_PLUGIN_DIR="")
|
add_definitions(-DOGRE_PLUGIN_DIR="")
|
||||||
else()
|
else()
|
||||||
if (NOT DEFINED ${OGRE_PLUGIN_DIR})
|
if (CUSTOM_OGRE_PLUGIN_DIR STREQUAL "")
|
||||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
||||||
|
else()
|
||||||
|
set(OGRE_PLUGIN_DIR ${CUSTOM_OGRE_PLUGIN_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}")
|
add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}")
|
||||||
|
|
|
@ -27,8 +27,8 @@ struct Arguments
|
||||||
|
|
||||||
void replaceAll(std::string& str, const std::string& needle, const std::string& substitute)
|
void replaceAll(std::string& str, const std::string& needle, const std::string& substitute)
|
||||||
{
|
{
|
||||||
int pos = str.find(needle);
|
size_t pos = str.find(needle);
|
||||||
while(pos != -1)
|
while(pos != std::string::npos)
|
||||||
{
|
{
|
||||||
str.replace(pos, needle.size(), substitute);
|
str.replace(pos, needle.size(), substitute);
|
||||||
pos = str.find(needle);
|
pos = str.find(needle);
|
||||||
|
@ -138,8 +138,8 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
else if (variables["input-file"].as< std::vector<std::string> >().size() > 1)
|
else if (variables["input-file"].as< std::vector<std::string> >().size() > 1)
|
||||||
info.outdir = variables["input-file"].as< std::vector<std::string> >()[1];
|
info.outdir = variables["input-file"].as< std::vector<std::string> >()[1];
|
||||||
|
|
||||||
info.longformat = variables.count("long");
|
info.longformat = variables.count("long") != 0;
|
||||||
info.fullpath = variables.count("full-path");
|
info.fullpath = variables.count("full-path") != 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct ESMData
|
||||||
{
|
{
|
||||||
std::string author;
|
std::string author;
|
||||||
std::string description;
|
std::string description;
|
||||||
int version;
|
unsigned int version;
|
||||||
std::vector<ESM::Header::MasterData> masters;
|
std::vector<ESM::Header::MasterData> masters;
|
||||||
|
|
||||||
std::deque<EsmTool::RecordBase *> mRecords;
|
std::deque<EsmTool::RecordBase *> mRecords;
|
||||||
|
@ -48,9 +48,9 @@ const std::set<int> ESMData::sLabeledRec =
|
||||||
// Based on the legacy struct
|
// Based on the legacy struct
|
||||||
struct Arguments
|
struct Arguments
|
||||||
{
|
{
|
||||||
unsigned int raw_given;
|
bool raw_given;
|
||||||
unsigned int quiet_given;
|
bool quiet_given;
|
||||||
unsigned int loadcells_given;
|
bool loadcells_given;
|
||||||
bool plain_given;
|
bool plain_given;
|
||||||
|
|
||||||
std::string mode;
|
std::string mode;
|
||||||
|
@ -177,10 +177,10 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
if (variables["input-file"].as< std::vector<std::string> >().size() > 1)
|
if (variables["input-file"].as< std::vector<std::string> >().size() > 1)
|
||||||
info.outname = variables["input-file"].as< std::vector<std::string> >()[1];
|
info.outname = variables["input-file"].as< std::vector<std::string> >()[1];
|
||||||
|
|
||||||
info.raw_given = variables.count ("raw");
|
info.raw_given = variables.count ("raw") != 0;
|
||||||
info.quiet_given = variables.count ("quiet");
|
info.quiet_given = variables.count ("quiet") != 0;
|
||||||
info.loadcells_given = variables.count ("loadcells");
|
info.loadcells_given = variables.count ("loadcells") != 0;
|
||||||
info.plain_given = (variables.count("plain") > 0);
|
info.plain_given = variables.count("plain") != 0;
|
||||||
|
|
||||||
// Font encoding settings
|
// Font encoding settings
|
||||||
info.encoding = variables["encoding"].as<std::string>();
|
info.encoding = variables["encoding"].as<std::string>();
|
||||||
|
@ -261,7 +261,7 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
||||||
std::cout << " Faction: '" << ref.mFaction << "'" << std::endl;
|
std::cout << " Faction: '" << ref.mFaction << "'" << std::endl;
|
||||||
std::cout << " Faction rank: '" << ref.mFactionRank << "'" << std::endl;
|
std::cout << " Faction rank: '" << ref.mFactionRank << "'" << std::endl;
|
||||||
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
||||||
std::cout << " Uses/health: '" << ref.mCharge << "'\n";
|
std::cout << " Uses/health: '" << ref.mChargeInt << "'\n";
|
||||||
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
||||||
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
||||||
std::cout << " Deleted: " << deleted << std::endl;
|
std::cout << " Deleted: " << deleted << std::endl;
|
||||||
|
@ -430,7 +430,7 @@ int clone(Arguments& info)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int recordCount = info.data.mRecords.size();
|
size_t recordCount = info.data.mRecords.size();
|
||||||
|
|
||||||
int digitCount = 1; // For a nicer output
|
int digitCount = 1; // For a nicer output
|
||||||
if (recordCount > 9) ++digitCount;
|
if (recordCount > 9) ++digitCount;
|
||||||
|
@ -501,9 +501,9 @@ int clone(Arguments& info)
|
||||||
if (!info.data.mCellRefs[ptr].empty()) {
|
if (!info.data.mCellRefs[ptr].empty()) {
|
||||||
typedef std::deque<ESM::CellRef> RefList;
|
typedef std::deque<ESM::CellRef> RefList;
|
||||||
RefList &refs = info.data.mCellRefs[ptr];
|
RefList &refs = info.data.mCellRefs[ptr];
|
||||||
for (RefList::iterator it = refs.begin(); it != refs.end(); ++it)
|
for (RefList::iterator refIt = refs.begin(); refIt != refs.end(); ++refIt)
|
||||||
{
|
{
|
||||||
it->save(esm);
|
refIt->save(esm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,7 +511,7 @@ int clone(Arguments& info)
|
||||||
esm.endRecord(name.toString());
|
esm.endRecord(name.toString());
|
||||||
|
|
||||||
saved++;
|
saved++;
|
||||||
int perc = (saved / (float)recordCount)*100;
|
int perc = (int)((saved / (float)recordCount)*100);
|
||||||
if (perc % 10 == 0)
|
if (perc % 10 == 0)
|
||||||
{
|
{
|
||||||
std::cerr << "\r" << perc << "%";
|
std::cerr << "\r" << perc << "%";
|
||||||
|
|
|
@ -13,14 +13,13 @@
|
||||||
#include <components/esm/loadweap.hpp>
|
#include <components/esm/loadweap.hpp>
|
||||||
#include <components/esm/aipackage.hpp>
|
#include <components/esm/aipackage.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
std::string bodyPartLabel(int idx)
|
std::string bodyPartLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 26)
|
if (idx >= 0 && idx <= 26)
|
||||||
{
|
{
|
||||||
const char *bodyPartLabels[] = {
|
static const char *bodyPartLabels[] = {
|
||||||
"Head",
|
"Head",
|
||||||
"Hair",
|
"Hair",
|
||||||
"Neck",
|
"Neck",
|
||||||
|
@ -59,7 +58,7 @@ std::string meshPartLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail)
|
if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail)
|
||||||
{
|
{
|
||||||
const char *meshPartLabels[] = {
|
static const char *meshPartLabels[] = {
|
||||||
"Head",
|
"Head",
|
||||||
"Hair",
|
"Hair",
|
||||||
"Neck",
|
"Neck",
|
||||||
|
@ -86,7 +85,7 @@ std::string meshTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor)
|
if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor)
|
||||||
{
|
{
|
||||||
const char *meshTypeLabels[] = {
|
static const char *meshTypeLabels[] = {
|
||||||
"Skin",
|
"Skin",
|
||||||
"Clothing",
|
"Clothing",
|
||||||
"Armor"
|
"Armor"
|
||||||
|
@ -101,7 +100,7 @@ std::string clothingTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 9)
|
if (idx >= 0 && idx <= 9)
|
||||||
{
|
{
|
||||||
const char *clothingTypeLabels[] = {
|
static const char *clothingTypeLabels[] = {
|
||||||
"Pants",
|
"Pants",
|
||||||
"Shoes",
|
"Shoes",
|
||||||
"Shirt",
|
"Shirt",
|
||||||
|
@ -123,7 +122,7 @@ std::string armorTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 10)
|
if (idx >= 0 && idx <= 10)
|
||||||
{
|
{
|
||||||
const char *armorTypeLabels[] = {
|
static const char *armorTypeLabels[] = {
|
||||||
"Helmet",
|
"Helmet",
|
||||||
"Cuirass",
|
"Cuirass",
|
||||||
"Left Pauldron",
|
"Left Pauldron",
|
||||||
|
@ -146,7 +145,7 @@ std::string dialogTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 4)
|
if (idx >= 0 && idx <= 4)
|
||||||
{
|
{
|
||||||
const char *dialogTypeLabels[] = {
|
static const char *dialogTypeLabels[] = {
|
||||||
"Topic",
|
"Topic",
|
||||||
"Voice",
|
"Voice",
|
||||||
"Greeting",
|
"Greeting",
|
||||||
|
@ -165,7 +164,7 @@ std::string questStatusLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 4)
|
if (idx >= 0 && idx <= 4)
|
||||||
{
|
{
|
||||||
const char *questStatusLabels[] = {
|
static const char *questStatusLabels[] = {
|
||||||
"None",
|
"None",
|
||||||
"Name",
|
"Name",
|
||||||
"Finished",
|
"Finished",
|
||||||
|
@ -182,7 +181,7 @@ std::string creatureTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 3)
|
if (idx >= 0 && idx <= 3)
|
||||||
{
|
{
|
||||||
const char *creatureTypeLabels[] = {
|
static const char *creatureTypeLabels[] = {
|
||||||
"Creature",
|
"Creature",
|
||||||
"Daedra",
|
"Daedra",
|
||||||
"Undead",
|
"Undead",
|
||||||
|
@ -198,7 +197,7 @@ std::string soundTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 7)
|
if (idx >= 0 && idx <= 7)
|
||||||
{
|
{
|
||||||
const char *soundTypeLabels[] = {
|
static const char *soundTypeLabels[] = {
|
||||||
"Left Foot",
|
"Left Foot",
|
||||||
"Right Foot",
|
"Right Foot",
|
||||||
"Swim Left",
|
"Swim Left",
|
||||||
|
@ -218,7 +217,7 @@ std::string weaponTypeLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 13)
|
if (idx >= 0 && idx <= 13)
|
||||||
{
|
{
|
||||||
const char *weaponTypeLabels[] = {
|
static const char *weaponTypeLabels[] = {
|
||||||
"Short Blade One Hand",
|
"Short Blade One Hand",
|
||||||
"Long Blade One Hand",
|
"Long Blade One Hand",
|
||||||
"Long Blade Two Hand",
|
"Long Blade Two Hand",
|
||||||
|
|
|
@ -25,7 +25,7 @@ void printAIPackage(ESM::AIPackage p)
|
||||||
{
|
{
|
||||||
std::cout << " Travel Coordinates: (" << p.mTravel.mX << ","
|
std::cout << " Travel Coordinates: (" << p.mTravel.mX << ","
|
||||||
<< p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl;
|
<< p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl;
|
||||||
std::cout << " Travel Unknown: " << (int)p.mTravel.mUnk << std::endl;
|
std::cout << " Travel Unknown: " << p.mTravel.mUnk << std::endl;
|
||||||
}
|
}
|
||||||
else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort)
|
else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort)
|
||||||
{
|
{
|
||||||
|
@ -33,12 +33,12 @@ void printAIPackage(ESM::AIPackage p)
|
||||||
<< p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl;
|
<< p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl;
|
||||||
std::cout << " Duration: " << p.mTarget.mDuration << std::endl;
|
std::cout << " Duration: " << p.mTarget.mDuration << std::endl;
|
||||||
std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl;
|
std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl;
|
||||||
std::cout << " Unknown: " << (int)p.mTarget.mUnk << std::endl;
|
std::cout << " Unknown: " << p.mTarget.mUnk << std::endl;
|
||||||
}
|
}
|
||||||
else if (p.mType == ESM::AI_Activate)
|
else if (p.mType == ESM::AI_Activate)
|
||||||
{
|
{
|
||||||
std::cout << " Name: " << p.mActivate.mName.toString() << std::endl;
|
std::cout << " Name: " << p.mActivate.mName.toString() << std::endl;
|
||||||
std::cout << " Activate Unknown: " << (int)p.mActivate.mUnk << std::endl;
|
std::cout << " Activate Unknown: " << p.mActivate.mUnk << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
|
std::cout << " BadPackage: " << boost::format("0x%08x") % p.mType << std::endl;
|
||||||
|
@ -89,6 +89,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
|
||||||
case 'A': if (indicator == 'R') type_str = "Not Race"; break;
|
case 'A': if (indicator == 'R') type_str = "Not Race"; break;
|
||||||
case 'B': if (indicator == 'L') type_str = "Not Cell"; break;
|
case 'B': if (indicator == 'L') type_str = "Not Cell"; break;
|
||||||
case 'C': if (indicator == 's') type_str = "Not Local"; break;
|
case 'C': if (indicator == 's') type_str = "Not Local"; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the variable name to the function string if any.
|
// Append the variable name to the function string if any.
|
||||||
|
@ -110,6 +111,7 @@ std::string ruleString(ESM::DialInfo::SelectStruct ss)
|
||||||
case '3': oper_str = ">="; break;
|
case '3': oper_str = ">="; break;
|
||||||
case '4': oper_str = "< "; break;
|
case '4': oper_str = "< "; break;
|
||||||
case '5': oper_str = "<="; break;
|
case '5': oper_str = "<="; break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
@ -430,7 +432,7 @@ void Record<ESM::Apparatus>::print()
|
||||||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType)
|
std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType)
|
||||||
<< " (" << (int)mData.mData.mType << ")" << std::endl;
|
<< " (" << mData.mData.mType << ")" << std::endl;
|
||||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||||
|
@ -816,7 +818,7 @@ void Record<ESM::Land>::print()
|
||||||
// Seems like this should done with reference counting in the
|
// Seems like this should done with reference counting in the
|
||||||
// loader to me. But I'm not really knowledgable about this
|
// loader to me. But I'm not really knowledgable about this
|
||||||
// record type yet. --Cory
|
// record type yet. --Cory
|
||||||
bool wasLoaded = mData.mDataLoaded;
|
bool wasLoaded = (mData.mDataLoaded != 0);
|
||||||
if (mData.mDataTypes) mData.loadData(mData.mDataTypes);
|
if (mData.mDataTypes) mData.loadData(mData.mDataTypes);
|
||||||
if (mData.mDataLoaded)
|
if (mData.mDataLoaded)
|
||||||
{
|
{
|
||||||
|
@ -999,7 +1001,7 @@ void Record<ESM::NPC>::print()
|
||||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
|
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
|
||||||
std::cout << " Unknown3: "
|
std::cout << " Unknown3: "
|
||||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
|
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
|
||||||
std::cout << " Gold: " << (int)mData.mNpdt12.mGold << std::endl;
|
std::cout << " Gold: " << mData.mNpdt12.mGold << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl;
|
std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl;
|
||||||
|
@ -1021,7 +1023,7 @@ void Record<ESM::NPC>::print()
|
||||||
std::cout << " Skills:" << std::endl;
|
std::cout << " Skills:" << std::endl;
|
||||||
for (int i = 0; i != ESM::Skill::Length; i++)
|
for (int i = 0; i != ESM::Skill::Length; i++)
|
||||||
std::cout << " " << skillLabel(i) << ": "
|
std::cout << " " << skillLabel(i) << ": "
|
||||||
<< (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;
|
<< (int)(mData.mNpdt52.mSkills[i]) << std::endl;
|
||||||
|
|
||||||
std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl;
|
std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl;
|
||||||
std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl;
|
std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl;
|
||||||
|
@ -1123,9 +1125,9 @@ void Record<ESM::Race>::print()
|
||||||
|
|
||||||
std::cout << (male ? " Male:" : " Female:") << std::endl;
|
std::cout << (male ? " Male:" : " Female:") << std::endl;
|
||||||
|
|
||||||
for (int i=0; i<8; ++i)
|
for (int j=0; j<8; ++j)
|
||||||
std::cout << " " << sAttributeNames[i] << ": "
|
std::cout << " " << sAttributeNames[j] << ": "
|
||||||
<< mData.mData.mAttributeValues[i].getValue (male) << std::endl;
|
<< mData.mData.mAttributeValues[j].getValue (male) << std::endl;
|
||||||
|
|
||||||
std::cout << " Height: " << mData.mData.mHeight.getValue (male) << std::endl;
|
std::cout << " Height: " << mData.mData.mHeight.getValue (male) << std::endl;
|
||||||
std::cout << " Weight: " << mData.mData.mWeight.getValue (male) << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight.getValue (male) << std::endl;
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace EsmTool
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::string mId;
|
std::string mId;
|
||||||
int mFlags;
|
uint32_t mFlags;
|
||||||
ESM::NAME mType;
|
ESM::NAME mType;
|
||||||
bool mPrintPlain;
|
bool mPrintPlain;
|
||||||
|
|
||||||
|
@ -40,11 +40,11 @@ namespace EsmTool
|
||||||
mId = id;
|
mId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFlags() const {
|
uint32_t getFlags() const {
|
||||||
return mFlags;
|
return mFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFlags(int flags) {
|
void setFlags(uint32_t flags) {
|
||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,6 @@ namespace EsmTool
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getPrintPlain() const {
|
|
||||||
return mPrintPlain;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPrintPlain(bool plain) {
|
void setPrintPlain(bool plain) {
|
||||||
mPrintPlain = plain;
|
mPrintPlain = plain;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,13 @@ set(ESSIMPORTER_FILES
|
||||||
importinventory.cpp
|
importinventory.cpp
|
||||||
importklst.cpp
|
importklst.cpp
|
||||||
importcntc.cpp
|
importcntc.cpp
|
||||||
|
importgame.cpp
|
||||||
|
importinfo.cpp
|
||||||
|
importdial.cpp
|
||||||
|
importques.cpp
|
||||||
|
importjour.cpp
|
||||||
|
importscri.cpp
|
||||||
|
importscpt.cpp
|
||||||
importercontext.cpp
|
importercontext.cpp
|
||||||
converter.cpp
|
converter.cpp
|
||||||
convertacdt.cpp
|
convertacdt.cpp
|
||||||
|
@ -16,6 +23,7 @@ set(ESSIMPORTER_FILES
|
||||||
convertinventory.cpp
|
convertinventory.cpp
|
||||||
convertcrec.cpp
|
convertcrec.cpp
|
||||||
convertcntc.cpp
|
convertcntc.cpp
|
||||||
|
convertscri.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(openmw-essimporter
|
add_executable(openmw-essimporter
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "convertcrec.hpp"
|
#include "convertcrec.hpp"
|
||||||
#include "convertcntc.hpp"
|
#include "convertcntc.hpp"
|
||||||
|
#include "convertscri.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -27,6 +28,10 @@ namespace
|
||||||
objstate.mEnabled = cellref.mEnabled;
|
objstate.mEnabled = cellref.mEnabled;
|
||||||
objstate.mPosition = cellref.mPos;
|
objstate.mPosition = cellref.mPos;
|
||||||
objstate.mRef.mRefNum = cellref.mRefNum;
|
objstate.mRef.mRefNum = cellref.mRefNum;
|
||||||
|
if (cellref.mDeleted)
|
||||||
|
objstate.mCount = 0;
|
||||||
|
convertSCRI(cellref.mSCRI, objstate.mLocals);
|
||||||
|
objstate.mHasLocals = !objstate.mLocals.mVariables.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIndexedRefId(const std::string& indexedRefId)
|
bool isIndexedRefId(const std::string& indexedRefId)
|
||||||
|
@ -34,6 +39,10 @@ namespace
|
||||||
if (indexedRefId.size() <= 8)
|
if (indexedRefId.size() <= 8)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (indexedRefId.find_first_not_of("0123456789") == std::string::npos)
|
||||||
|
return false; // entirely numeric refid, this is a reference to
|
||||||
|
// a dynamically created record e.g. player-enchanted weapon
|
||||||
|
|
||||||
std::string index = indexedRefId.substr(indexedRefId.size()-8);
|
std::string index = indexedRefId.substr(indexedRefId.size()-8);
|
||||||
if(index.find_first_not_of("0123456789ABCDEF") == std::string::npos )
|
if(index.find_first_not_of("0123456789ABCDEF") == std::string::npos )
|
||||||
return true;
|
return true;
|
||||||
|
@ -70,6 +79,12 @@ namespace ESSImport
|
||||||
cell.mName = id;
|
cell.mName = id;
|
||||||
cell.load(esm, false);
|
cell.load(esm, false);
|
||||||
|
|
||||||
|
// I wonder what 0x40 does?
|
||||||
|
if (cell.isExterior() && cell.mData.mFlags & 0x20)
|
||||||
|
{
|
||||||
|
mContext->mGlobalMapState.mMarkers.insert(std::make_pair(cell.mData.mX, cell.mData.mY));
|
||||||
|
}
|
||||||
|
|
||||||
// note if the player is in a nameless exterior cell, we will assign the cellId later based on player position
|
// note if the player is in a nameless exterior cell, we will assign the cellId later based on player position
|
||||||
if (id == mContext->mPlayerCellName)
|
if (id == mContext->mPlayerCellName)
|
||||||
{
|
{
|
||||||
|
@ -136,13 +151,6 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
CellRef ref;
|
CellRef ref;
|
||||||
ref.load (esm);
|
ref.load (esm);
|
||||||
if (esm.isNextSub("DELE"))
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
// strangely this can be e.g. 52 instead of just 1,
|
|
||||||
//std::cout << "deleted ref " << ref.mIndexedRefId << std::endl;
|
|
||||||
esm.skipHSub();
|
|
||||||
}
|
|
||||||
cellrefs.push_back(ref);
|
cellrefs.push_back(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,8 +209,7 @@ namespace ESSImport
|
||||||
for (std::vector<CellRef>::const_iterator refIt = cell.mRefs.begin(); refIt != cell.mRefs.end(); ++refIt)
|
for (std::vector<CellRef>::const_iterator refIt = cell.mRefs.begin(); refIt != cell.mRefs.end(); ++refIt)
|
||||||
{
|
{
|
||||||
const CellRef& cellref = *refIt;
|
const CellRef& cellref = *refIt;
|
||||||
ESM::CellRef out;
|
ESM::CellRef out (cellref);
|
||||||
out.blank();
|
|
||||||
|
|
||||||
if (!isIndexedRefId(cellref.mIndexedRefId))
|
if (!isIndexedRefId(cellref.mIndexedRefId))
|
||||||
{
|
{
|
||||||
|
@ -241,8 +248,8 @@ namespace ESSImport
|
||||||
objstate.mRef.mRefID = idLower;
|
objstate.mRef.mRefID = idLower;
|
||||||
// probably need more micromanagement here so we don't overwrite values
|
// probably need more micromanagement here so we don't overwrite values
|
||||||
// from the ESM with default values
|
// from the ESM with default values
|
||||||
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats);
|
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||||
convertNpcData(cellref.mActorData, objstate.mNpcStats);
|
convertNpcData(cellref, objstate.mNpcStats);
|
||||||
convertNPCC(npccIt->second, objstate);
|
convertNPCC(npccIt->second, objstate);
|
||||||
convertCellRef(cellref, objstate);
|
convertCellRef(cellref, objstate);
|
||||||
esm.writeHNT ("OBJE", ESM::REC_NPC_);
|
esm.writeHNT ("OBJE", ESM::REC_NPC_);
|
||||||
|
@ -273,7 +280,7 @@ namespace ESSImport
|
||||||
objstate.blank();
|
objstate.blank();
|
||||||
objstate.mRef = out;
|
objstate.mRef = out;
|
||||||
objstate.mRef.mRefID = idLower;
|
objstate.mRef.mRefID = idLower;
|
||||||
convertACDT(cellref.mActorData.mACDT, objstate.mCreatureStats);
|
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||||
// probably need more micromanagement here so we don't overwrite values
|
// probably need more micromanagement here so we don't overwrite values
|
||||||
// from the ESM with default values
|
// from the ESM with default values
|
||||||
convertCREC(crecIt->second, objstate);
|
convertCREC(crecIt->second, objstate);
|
||||||
|
@ -306,6 +313,10 @@ namespace ESSImport
|
||||||
it->save(esm);
|
it->save(esm);
|
||||||
esm.endRecord(ESM::REC_MARK);
|
esm.endRecord(ESM::REC_MARK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esm.startRecord(ESM::REC_GMAP);
|
||||||
|
mContext->mGlobalMapState.save(esm);
|
||||||
|
esm.endRecord(ESM::REC_GMAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <components/esm/loadfact.hpp>
|
#include <components/esm/loadfact.hpp>
|
||||||
#include <components/esm/dialoguestate.hpp>
|
#include <components/esm/dialoguestate.hpp>
|
||||||
#include <components/esm/custommarkerstate.hpp>
|
#include <components/esm/custommarkerstate.hpp>
|
||||||
|
#include <components/esm/loadcrea.hpp>
|
||||||
|
|
||||||
#include "importcrec.hpp"
|
#include "importcrec.hpp"
|
||||||
#include "importcntc.hpp"
|
#include "importcntc.hpp"
|
||||||
|
@ -19,6 +20,12 @@
|
||||||
#include "importercontext.hpp"
|
#include "importercontext.hpp"
|
||||||
#include "importcellref.hpp"
|
#include "importcellref.hpp"
|
||||||
#include "importklst.hpp"
|
#include "importklst.hpp"
|
||||||
|
#include "importgame.hpp"
|
||||||
|
#include "importinfo.hpp"
|
||||||
|
#include "importdial.hpp"
|
||||||
|
#include "importques.hpp"
|
||||||
|
#include "importjour.hpp"
|
||||||
|
#include "importscpt.hpp"
|
||||||
|
|
||||||
#include "convertacdt.hpp"
|
#include "convertacdt.hpp"
|
||||||
#include "convertnpcc.hpp"
|
#include "convertnpcc.hpp"
|
||||||
|
@ -86,25 +93,53 @@ class ConvertNPC : public Converter
|
||||||
public:
|
public:
|
||||||
virtual void read(ESM::ESMReader &esm)
|
virtual void read(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
// this is always the player
|
|
||||||
ESM::NPC npc;
|
ESM::NPC npc;
|
||||||
std::string id = esm.getHNString("NAME");
|
std::string id = esm.getHNString("NAME");
|
||||||
npc.load(esm);
|
npc.load(esm);
|
||||||
if (id != "player") // seems to occur sometimes, with "chargen X" names
|
if (id != "player")
|
||||||
std::cerr << "non-player NPC record: " << id << std::endl;
|
{
|
||||||
|
// TODO:
|
||||||
|
// this should handle changes to the NPC struct, but since there is no index here
|
||||||
|
// it will apply to ALL instances of the class. seems to be the reason for the
|
||||||
|
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
|
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
|
||||||
mContext->mPlayerBase = npc;
|
mContext->mPlayerBase = npc;
|
||||||
std::map<const int, float> empty;
|
std::map<const int, float> empty;
|
||||||
// FIXME: player start spells, racial spells and birthsign spells aren't listed here,
|
// FIXME: player start spells and birthsign spells aren't listed here,
|
||||||
// need to fix openmw to account for this
|
// need to fix openmw to account for this
|
||||||
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)
|
for (std::vector<std::string>::const_iterator it = npc.mSpells.mList.begin(); it != npc.mSpells.mList.end(); ++it)
|
||||||
mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[*it] = empty;
|
mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells[*it] = empty;
|
||||||
|
|
||||||
|
// Clear the list now that we've written it, this prevents issues cropping up with
|
||||||
|
// ensureCustomData() in OpenMW tripping over no longer existing spells, where an error would be fatal.
|
||||||
|
mContext->mPlayerBase.mSpells.mList.clear();
|
||||||
|
|
||||||
|
// Same with inventory. Actually it's strange this would contain something, since there's already an
|
||||||
|
// inventory list in NPCC. There seems to be a fair amount of redundancy in this format.
|
||||||
|
mContext->mPlayerBase.mInventory.mList.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConvertCREA : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
// See comment in ConvertNPC
|
||||||
|
ESM::Creature creature;
|
||||||
|
std::string id = esm.getHNString("NAME");
|
||||||
|
creature.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Do we need ConvertCONT?
|
||||||
|
// I've seen a CONT record in a certain save file, but the container contents in it
|
||||||
|
// were identical to a corresponding CNTC record. See previous comment about redundancy...
|
||||||
|
|
||||||
class ConvertGlobal : public DefaultConverter<ESM::Global>
|
class ConvertGlobal : public DefaultConverter<ESM::Global>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -191,7 +226,28 @@ public:
|
||||||
|
|
||||||
ESM::NpcStats& npcStats = mContext->mPlayer.mObject.mNpcStats;
|
ESM::NpcStats& npcStats = mContext->mPlayer.mObject.mNpcStats;
|
||||||
convertNpcData(refr.mActorData, npcStats);
|
convertNpcData(refr.mActorData, npcStats);
|
||||||
|
|
||||||
|
mSelectedSpell = refr.mActorData.mSelectedSpell;
|
||||||
|
if (!refr.mActorData.mSelectedEnchantItem.empty())
|
||||||
|
{
|
||||||
|
ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<invState.mItems.size(); ++i)
|
||||||
|
{
|
||||||
|
// FIXME: in case of conflict (multiple items with this refID) use the already equipped one?
|
||||||
|
if (Misc::StringUtils::ciEqual(invState.mItems[i].mRef.mRefID, refr.mActorData.mSelectedEnchantItem))
|
||||||
|
invState.mSelectedEnchantItem = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
virtual void write(ESM::ESMWriter& esm)
|
||||||
|
{
|
||||||
|
esm.startRecord(ESM::REC_ASPL);
|
||||||
|
esm.writeHNString("ID__", mSelectedSpell);
|
||||||
|
esm.endRecord(ESM::REC_ASPL);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string mSelectedSpell;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertPCDT : public Converter
|
class ConvertPCDT : public Converter
|
||||||
|
@ -329,15 +385,18 @@ public:
|
||||||
{
|
{
|
||||||
std::string itemid = esm.getHNString("NAME");
|
std::string itemid = esm.getHNString("NAME");
|
||||||
|
|
||||||
while (esm.isNextSub("ONAM"))
|
while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM"))
|
||||||
{
|
{
|
||||||
std::string ownerid = esm.getHString();
|
if (esm.retSubName().toString() == "FNAM")
|
||||||
mStolenItems.insert(std::make_pair(itemid, ownerid));
|
{
|
||||||
}
|
std::string factionid = esm.getHString();
|
||||||
while (esm.isNextSub("FNAM"))
|
mFactionStolenItems.insert(std::make_pair(itemid, factionid));
|
||||||
{
|
}
|
||||||
std::string factionid = esm.getHString();
|
else
|
||||||
mFactionStolenItems.insert(std::make_pair(itemid, factionid));
|
{
|
||||||
|
std::string ownerid = esm.getHString();
|
||||||
|
mStolenItems.insert(std::make_pair(itemid, ownerid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -345,6 +404,75 @@ private:
|
||||||
std::multimap<std::string, std::string> mFactionStolenItems;
|
std::multimap<std::string, std::string> mFactionStolenItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Seen responses for a dialogue topic?
|
||||||
|
/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs
|
||||||
|
/// Dialogue conversion problems (probably have to adjust OpenMW format) -
|
||||||
|
/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID.
|
||||||
|
/// - Seen dialogue responses only store the INFO id, rather than the fulltext.
|
||||||
|
/// - Quest stages only store the INFO id, rather than the journal entry fulltext.
|
||||||
|
class ConvertINFO : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader& esm)
|
||||||
|
{
|
||||||
|
INFO info;
|
||||||
|
info.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConvertDIAL : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader& esm)
|
||||||
|
{
|
||||||
|
std::string id = esm.getHNString("NAME");
|
||||||
|
DIAL dial;
|
||||||
|
dial.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConvertQUES : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader& esm)
|
||||||
|
{
|
||||||
|
std::string id = esm.getHNString("NAME");
|
||||||
|
QUES quest;
|
||||||
|
quest.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConvertJOUR : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader& esm)
|
||||||
|
{
|
||||||
|
JOUR journal;
|
||||||
|
journal.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConvertGAME : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
GAME game;
|
||||||
|
game.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Running global script
|
||||||
|
class ConvertSCPT : public Converter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void read(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
SCPT script;
|
||||||
|
script.load(esm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,16 +7,23 @@ namespace ESSImport
|
||||||
|
|
||||||
void convertInventory(const Inventory &inventory, ESM::InventoryState &state)
|
void convertInventory(const Inventory &inventory, ESM::InventoryState &state)
|
||||||
{
|
{
|
||||||
|
int index = 0;
|
||||||
for (std::vector<Inventory::InventoryItem>::const_iterator it = inventory.mItems.begin();
|
for (std::vector<Inventory::InventoryItem>::const_iterator it = inventory.mItems.begin();
|
||||||
it != inventory.mItems.end(); ++it)
|
it != inventory.mItems.end(); ++it)
|
||||||
{
|
{
|
||||||
ESM::ObjectState objstate;
|
ESM::ObjectState objstate;
|
||||||
objstate.blank();
|
objstate.blank();
|
||||||
|
objstate.mRef = *it;
|
||||||
objstate.mRef.mRefID = Misc::StringUtils::lowerCase(it->mId);
|
objstate.mRef.mRefID = Misc::StringUtils::lowerCase(it->mId);
|
||||||
objstate.mCount = std::abs(it->mCount); // restocking items have negative count in the savefile
|
objstate.mCount = std::abs(it->mCount); // restocking items have negative count in the savefile
|
||||||
// openmw handles them differently, so no need to set any flags
|
// openmw handles them differently, so no need to set any flags
|
||||||
objstate.mRef.mCharge = it->mCondition;
|
state.mItems.push_back(objstate);
|
||||||
state.mItems.push_back(std::make_pair(objstate, -1));
|
if (it->mRelativeEquipmentSlot != -1)
|
||||||
|
// Note we should really write the absolute slot here, which we do not know about
|
||||||
|
// Not a big deal, OpenMW will auto-correct to a valid slot, the only problem is when
|
||||||
|
// an item could be equipped in two different slots (e.g. equipped two rings)
|
||||||
|
state.mEquipmentSlots[index] = it->mRelativeEquipmentSlot;
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
apps/essimporter/convertscri.cpp
Normal file
32
apps/essimporter/convertscri.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "convertscri.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T, ESM::VarType VariantType>
|
||||||
|
void storeVariables(const std::vector<T>& variables, ESM::Locals& locals, const std::string& scriptname)
|
||||||
|
{
|
||||||
|
for (typename std::vector<T>::const_iterator it = variables.begin(); it != variables.end(); ++it)
|
||||||
|
{
|
||||||
|
ESM::Variant val(*it);
|
||||||
|
val.setType(VariantType);
|
||||||
|
locals.mVariables.push_back(std::make_pair(std::string(), val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void convertSCRI(const SCRI &scri, ESM::Locals &locals)
|
||||||
|
{
|
||||||
|
// order *is* important, as we do not have variable names available in this format
|
||||||
|
storeVariables<short, ESM::VT_Short> (scri.mShorts, locals, scri.mScript);
|
||||||
|
storeVariables<int, ESM::VT_Int> (scri.mLongs, locals, scri.mScript);
|
||||||
|
storeVariables<float, ESM::VT_Float> (scri.mFloats, locals, scri.mScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
apps/essimporter/convertscri.hpp
Normal file
16
apps/essimporter/convertscri.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_CONVERTSCRI_H
|
||||||
|
#define OPENMW_ESSIMPORT_CONVERTSCRI_H
|
||||||
|
|
||||||
|
#include "importscri.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/locals.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Convert script variable assignments
|
||||||
|
void convertSCRI (const SCRI& scri, ESM::Locals& locals);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,18 +9,16 @@ namespace ESSImport
|
||||||
|
|
||||||
void ActorData::load(ESM::ESMReader &esm)
|
void ActorData::load(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
// unsure at which point between NAME and ESM::CellRef
|
|
||||||
if (esm.isNextSub("MNAM"))
|
|
||||||
esm.skipHSub();
|
|
||||||
|
|
||||||
if (esm.isNextSub("ACTN"))
|
if (esm.isNextSub("ACTN"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
if (esm.isNextSub("STPR"))
|
if (esm.isNextSub("STPR"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
ESM::CellRef bla;
|
if (esm.isNextSub("MNAM"))
|
||||||
bla.ESM::CellRef::loadData(esm);
|
esm.skipHSub();
|
||||||
|
|
||||||
|
ESM::CellRef::loadData(esm);
|
||||||
|
|
||||||
// FIXME: not all actors have this, add flag
|
// FIXME: not all actors have this, add flag
|
||||||
esm.getHNOT(mACDT, "ACDT");
|
esm.getHNOT(mACDT, "ACDT");
|
||||||
|
@ -62,15 +60,18 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("PWPS"))
|
if (esm.isNextSub("PWPS"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
|
// unsure at which point between LSTN and CHRD
|
||||||
|
if (esm.isNextSub("APUD"))
|
||||||
|
esm.skipHSub(); // 40 bytes, starts with string "ancestor guardian". maybe spellcasting in progress?
|
||||||
|
|
||||||
if (esm.isNextSub("WNAM"))
|
if (esm.isNextSub("WNAM"))
|
||||||
{
|
{
|
||||||
esm.skipHSub(); // seen values: "ancestor guardian", "bound dagger_en". Summoned creature / bound weapons?
|
std::string id = esm.getHString();
|
||||||
|
|
||||||
if (esm.isNextSub("XNAM"))
|
if (esm.isNextSub("XNAM"))
|
||||||
{
|
mSelectedEnchantItem = esm.getHString();
|
||||||
// "demon tanto", probably the ID of spell/item that created the bound weapon/crature?
|
else
|
||||||
esm.skipHSub();
|
mSelectedSpell = id;
|
||||||
}
|
|
||||||
|
|
||||||
if (esm.isNextSub("YNAM"))
|
if (esm.isNextSub("YNAM"))
|
||||||
esm.skipHSub(); // 4 byte, 0
|
esm.skipHSub(); // 4 byte, 0
|
||||||
|
@ -83,18 +84,7 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("CRED")) // creature only
|
if (esm.isNextSub("CRED")) // creature only
|
||||||
esm.getHExact(mCombatStats, 3*2*sizeof(int));
|
esm.getHExact(mCombatStats, 3*2*sizeof(int));
|
||||||
|
|
||||||
mScript = esm.getHNOString("SCRI");
|
mSCRI.load(esm);
|
||||||
|
|
||||||
// script variables?
|
|
||||||
if (!mScript.empty())
|
|
||||||
{
|
|
||||||
if (esm.isNextSub("SLCS"))
|
|
||||||
esm.skipHSub();
|
|
||||||
if (esm.isNextSub("SLSD")) // Short Data?
|
|
||||||
esm.skipHSub();
|
|
||||||
if (esm.isNextSub("SLFD")) // Float Data?
|
|
||||||
esm.skipHSub();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esm.isNextSub("ND3D"))
|
if (esm.isNextSub("ND3D"))
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <components/esm/cellref.hpp>
|
||||||
|
|
||||||
|
#include "importscri.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
struct ESMReader;
|
struct ESMReader;
|
||||||
|
@ -37,7 +41,7 @@ namespace ESSImport
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct ActorData
|
struct ActorData : public ESM::CellRef
|
||||||
{
|
{
|
||||||
ACDT mACDT;
|
ACDT mACDT;
|
||||||
|
|
||||||
|
@ -48,7 +52,10 @@ namespace ESSImport
|
||||||
// to change them ingame
|
// to change them ingame
|
||||||
int mCombatStats[3][2];
|
int mCombatStats[3][2];
|
||||||
|
|
||||||
std::string mScript;
|
std::string mSelectedSpell;
|
||||||
|
std::string mSelectedEnchantItem;
|
||||||
|
|
||||||
|
SCRI mSCRI;
|
||||||
|
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace ESSImport
|
||||||
|
|
||||||
void CellRef::load(ESM::ESMReader &esm)
|
void CellRef::load(ESM::ESMReader &esm)
|
||||||
{
|
{
|
||||||
|
blank();
|
||||||
|
|
||||||
// (FRMR subrecord name is already read by the loop in ConvertCell)
|
// (FRMR subrecord name is already read by the loop in ConvertCell)
|
||||||
esm.getHT(mRefNum.mIndex); // FRMR
|
esm.getHT(mRefNum.mIndex); // FRMR
|
||||||
|
|
||||||
|
@ -17,25 +19,32 @@ namespace ESSImport
|
||||||
|
|
||||||
mIndexedRefId = esm.getHNString("NAME");
|
mIndexedRefId = esm.getHNString("NAME");
|
||||||
|
|
||||||
|
ActorData::load(esm);
|
||||||
if (esm.isNextSub("LVCR"))
|
if (esm.isNextSub("LVCR"))
|
||||||
{
|
{
|
||||||
// occurs on leveled creature spawner references
|
// occurs on leveled creature spawner references
|
||||||
// probably some identifier for the the creature that has been spawned?
|
// probably some identifier for the creature that has been spawned?
|
||||||
unsigned char lvcr;
|
unsigned char lvcr;
|
||||||
esm.getHT(lvcr);
|
esm.getHT(lvcr);
|
||||||
//std::cout << "LVCR: " << (int)lvcr << std::endl;
|
//std::cout << "LVCR: " << (int)lvcr << std::endl;
|
||||||
}
|
}
|
||||||
mActorData.load(esm);
|
|
||||||
|
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
esm.getHNOT(mEnabled, "ZNAM");
|
esm.getHNOT(mEnabled, "ZNAM");
|
||||||
|
|
||||||
// should occur for all references but not levelled creature spawners
|
// DATA should occur for all references, except leveled creature spawners
|
||||||
esm.getHNOT(mPos, "DATA", 24);
|
// I've seen DATA *twice* on a creature record, and with the exact same content too! weird
|
||||||
|
|
||||||
// i've seen DATA record TWICE on a creature record - and with the exact same content too! weird
|
|
||||||
// alarmvoi0000.ess
|
// alarmvoi0000.ess
|
||||||
esm.getHNOT(mPos, "DATA", 24);
|
esm.getHNOT(mPos, "DATA", 24);
|
||||||
|
esm.getHNOT(mPos, "DATA", 24);
|
||||||
|
|
||||||
|
mDeleted = 0;
|
||||||
|
if (esm.isNextSub("DELE"))
|
||||||
|
{
|
||||||
|
unsigned int deleted;
|
||||||
|
esm.getHT(deleted);
|
||||||
|
mDeleted = (deleted >> 24) & 0x2; // the other 3 bytes seem to be uninitialized garbage
|
||||||
|
}
|
||||||
|
|
||||||
if (esm.isNextSub("MVRF"))
|
if (esm.isNextSub("MVRF"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,20 +15,16 @@ namespace ESM
|
||||||
namespace ESSImport
|
namespace ESSImport
|
||||||
{
|
{
|
||||||
|
|
||||||
// Not sure if we can share any code with ESM::CellRef here
|
struct CellRef : public ActorData
|
||||||
struct CellRef
|
|
||||||
{
|
{
|
||||||
std::string mIndexedRefId;
|
std::string mIndexedRefId;
|
||||||
ESM::RefNum mRefNum;
|
|
||||||
|
|
||||||
ActorData mActorData;
|
|
||||||
|
|
||||||
ESM::Position mPos;
|
|
||||||
|
|
||||||
std::string mScript;
|
std::string mScript;
|
||||||
|
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
|
|
||||||
|
bool mDeleted;
|
||||||
|
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ namespace ESSImport
|
||||||
float scale;
|
float scale;
|
||||||
esm.getHNOT(scale, "XSCL");
|
esm.getHNOT(scale, "XSCL");
|
||||||
|
|
||||||
|
// FIXME: use AiPackageList, need to fix getSubName()
|
||||||
|
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||||
|
|| esm.isNextSub("AI_A"))
|
||||||
|
esm.skipHSub();
|
||||||
|
|
||||||
mInventory.load(esm);
|
mInventory.load(esm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
apps/essimporter/importdial.cpp
Normal file
23
apps/essimporter/importdial.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "importdial.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void DIAL::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
// See ESM::Dialogue::Type enum, not sure why we would need this here though
|
||||||
|
int type = 0;
|
||||||
|
esm.getHNOT(type, "DATA");
|
||||||
|
|
||||||
|
// Deleted dialogue in a savefile. No clue what this means...
|
||||||
|
int deleted = 0;
|
||||||
|
esm.getHNOT(deleted, "DELE");
|
||||||
|
|
||||||
|
mIndex = 0;
|
||||||
|
// *should* always occur except when the dialogue is deleted, but leaving it optional just in case...
|
||||||
|
esm.getHNOT(mIndex, "XIDX");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
apps/essimporter/importdial.hpp
Normal file
20
apps/essimporter/importdial.hpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTDIAL_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTDIAL_H
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
struct DIAL
|
||||||
|
{
|
||||||
|
int mIndex; // Journal index
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -105,6 +105,7 @@ namespace ESSImport
|
||||||
blacklist.insert(std::make_pair("REFR", "DATA")); // player position
|
blacklist.insert(std::make_pair("REFR", "DATA")); // player position
|
||||||
blacklist.insert(std::make_pair("CELL", "NAM8")); // fog of war
|
blacklist.insert(std::make_pair("CELL", "NAM8")); // fog of war
|
||||||
blacklist.insert(std::make_pair("GAME", "GMDT")); // weather data, current time always changes
|
blacklist.insert(std::make_pair("GAME", "GMDT")); // weather data, current time always changes
|
||||||
|
blacklist.insert(std::make_pair("CELL", "DELE")); // first 3 bytes are uninitialized
|
||||||
|
|
||||||
// this changes way too often, name suggests some renderer internal data?
|
// this changes way too often, name suggests some renderer internal data?
|
||||||
blacklist.insert(std::make_pair("CELL", "ND3D"));
|
blacklist.insert(std::make_pair("CELL", "ND3D"));
|
||||||
|
@ -122,7 +123,7 @@ namespace ESSImport
|
||||||
|
|
||||||
if (i >= file2.mRecords.size())
|
if (i >= file2.mRecords.size())
|
||||||
{
|
{
|
||||||
std::cout << "Record in file1 not present in file2: (1) 0x" << std::hex << rec.mFileOffset;
|
std::cout << "Record in file1 not present in file2: (1) 0x" << std::hex << rec.mFileOffset << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ namespace ESSImport
|
||||||
|
|
||||||
if (j >= rec2.mSubrecords.size())
|
if (j >= rec2.mSubrecords.size())
|
||||||
{
|
{
|
||||||
std::cout << "Subrecord in file1 not present in file2: (1) 0x" << std::hex << sub.mFileOffset;
|
std::cout << "Subrecord in file1 not present in file2: (1) 0x" << std::hex << sub.mFileOffset << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +202,14 @@ namespace ESSImport
|
||||||
const unsigned int recFMAP = ESM::FourCC<'F','M','A','P'>::value;
|
const unsigned int recFMAP = ESM::FourCC<'F','M','A','P'>::value;
|
||||||
const unsigned int recKLST = ESM::FourCC<'K','L','S','T'>::value;
|
const unsigned int recKLST = ESM::FourCC<'K','L','S','T'>::value;
|
||||||
const unsigned int recSTLN = ESM::FourCC<'S','T','L','N'>::value;
|
const unsigned int recSTLN = ESM::FourCC<'S','T','L','N'>::value;
|
||||||
|
const unsigned int recGAME = ESM::FourCC<'G','A','M','E'>::value;
|
||||||
|
const unsigned int recJOUR = ESM::FourCC<'J','O','U','R'>::value;
|
||||||
|
|
||||||
std::map<unsigned int, boost::shared_ptr<Converter> > converters;
|
std::map<unsigned int, boost::shared_ptr<Converter> > converters;
|
||||||
converters[ESM::REC_GLOB] = boost::shared_ptr<Converter>(new ConvertGlobal());
|
converters[ESM::REC_GLOB] = boost::shared_ptr<Converter>(new ConvertGlobal());
|
||||||
converters[ESM::REC_BOOK] = boost::shared_ptr<Converter>(new ConvertBook());
|
converters[ESM::REC_BOOK] = boost::shared_ptr<Converter>(new ConvertBook());
|
||||||
converters[ESM::REC_NPC_] = boost::shared_ptr<Converter>(new ConvertNPC());
|
converters[ESM::REC_NPC_] = boost::shared_ptr<Converter>(new ConvertNPC());
|
||||||
|
converters[ESM::REC_CREA] = boost::shared_ptr<Converter>(new ConvertCREA());
|
||||||
converters[ESM::REC_NPCC] = boost::shared_ptr<Converter>(new ConvertNPCC());
|
converters[ESM::REC_NPCC] = boost::shared_ptr<Converter>(new ConvertNPCC());
|
||||||
converters[ESM::REC_CREC] = boost::shared_ptr<Converter>(new ConvertCREC());
|
converters[ESM::REC_CREC] = boost::shared_ptr<Converter>(new ConvertCREC());
|
||||||
converters[recREFR ] = boost::shared_ptr<Converter>(new ConvertREFR());
|
converters[recREFR ] = boost::shared_ptr<Converter>(new ConvertREFR());
|
||||||
|
@ -213,6 +217,7 @@ namespace ESSImport
|
||||||
converters[recFMAP ] = boost::shared_ptr<Converter>(new ConvertFMAP());
|
converters[recFMAP ] = boost::shared_ptr<Converter>(new ConvertFMAP());
|
||||||
converters[recKLST ] = boost::shared_ptr<Converter>(new ConvertKLST());
|
converters[recKLST ] = boost::shared_ptr<Converter>(new ConvertKLST());
|
||||||
converters[recSTLN ] = boost::shared_ptr<Converter>(new ConvertSTLN());
|
converters[recSTLN ] = boost::shared_ptr<Converter>(new ConvertSTLN());
|
||||||
|
converters[recGAME ] = boost::shared_ptr<Converter>(new ConvertGAME());
|
||||||
converters[ESM::REC_CELL] = boost::shared_ptr<Converter>(new ConvertCell());
|
converters[ESM::REC_CELL] = boost::shared_ptr<Converter>(new ConvertCell());
|
||||||
converters[ESM::REC_ALCH] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::Potion>());
|
converters[ESM::REC_ALCH] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::Potion>());
|
||||||
converters[ESM::REC_CLAS] = boost::shared_ptr<Converter>(new ConvertClass());
|
converters[ESM::REC_CLAS] = boost::shared_ptr<Converter>(new ConvertClass());
|
||||||
|
@ -226,6 +231,17 @@ namespace ESSImport
|
||||||
converters[ESM::REC_LEVI] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::ItemLevList>());
|
converters[ESM::REC_LEVI] = boost::shared_ptr<Converter>(new DefaultConverter<ESM::ItemLevList>());
|
||||||
converters[ESM::REC_CNTC] = boost::shared_ptr<Converter>(new ConvertCNTC());
|
converters[ESM::REC_CNTC] = boost::shared_ptr<Converter>(new ConvertCNTC());
|
||||||
converters[ESM::REC_FACT] = boost::shared_ptr<Converter>(new ConvertFACT());
|
converters[ESM::REC_FACT] = boost::shared_ptr<Converter>(new ConvertFACT());
|
||||||
|
converters[ESM::REC_INFO] = boost::shared_ptr<Converter>(new ConvertINFO());
|
||||||
|
converters[ESM::REC_DIAL] = boost::shared_ptr<Converter>(new ConvertDIAL());
|
||||||
|
converters[ESM::REC_QUES] = boost::shared_ptr<Converter>(new ConvertQUES());
|
||||||
|
converters[recJOUR ] = boost::shared_ptr<Converter>(new ConvertJOUR());
|
||||||
|
converters[ESM::REC_SCPT] = boost::shared_ptr<Converter>(new ConvertSCPT());
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - REGN (weather in certain regions?)
|
||||||
|
// - VFXM
|
||||||
|
// - SPLM (active spell effects)
|
||||||
|
// - PROJ (magic projectiles in air)
|
||||||
|
|
||||||
std::set<unsigned int> unknownRecords;
|
std::set<unsigned int> unknownRecords;
|
||||||
|
|
||||||
|
@ -248,7 +264,7 @@ namespace ESSImport
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (unknownRecords.insert(n.val).second)
|
if (unknownRecords.insert(n.val).second)
|
||||||
std::cerr << "unknown record " << n.toString() << std::endl;
|
std::cerr << "unknown record " << n.toString() << " (0x" << std::hex << esm.getFileOffset() << ")" << std::endl;
|
||||||
|
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
#include <components/esm/player.hpp>
|
#include <components/esm/player.hpp>
|
||||||
#include <components/esm/dialoguestate.hpp>
|
#include <components/esm/dialoguestate.hpp>
|
||||||
|
#include <components/esm/globalmap.hpp>
|
||||||
|
|
||||||
#include "importnpcc.hpp"
|
#include "importnpcc.hpp"
|
||||||
#include "importcrec.hpp"
|
#include "importcrec.hpp"
|
||||||
|
@ -28,6 +29,8 @@ namespace ESSImport
|
||||||
|
|
||||||
ESM::DialogueState mDialogueState;
|
ESM::DialogueState mDialogueState;
|
||||||
|
|
||||||
|
ESM::GlobalMap mGlobalMapState;
|
||||||
|
|
||||||
int mDay, mMonth, mYear;
|
int mDay, mMonth, mYear;
|
||||||
float mHour;
|
float mHour;
|
||||||
|
|
||||||
|
@ -48,6 +51,11 @@ namespace ESSImport
|
||||||
mPlayer.mCurrentCrimeId = 0; // TODO
|
mPlayer.mCurrentCrimeId = 0; // TODO
|
||||||
mPlayer.mObject.blank();
|
mPlayer.mObject.blank();
|
||||||
mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame
|
mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame
|
||||||
|
|
||||||
|
mGlobalMapState.mBounds.mMinX = 0;
|
||||||
|
mGlobalMapState.mBounds.mMaxX = 0;
|
||||||
|
mGlobalMapState.mBounds.mMinY = 0;
|
||||||
|
mGlobalMapState.mBounds.mMaxY = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
apps/essimporter/importgame.cpp
Normal file
13
apps/essimporter/importgame.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "importgame.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void GAME::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
esm.getHNT(mGMDT, "GMDT");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
apps/essimporter/importgame.hpp
Normal file
33
apps/essimporter/importgame.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_GAME_H
|
||||||
|
#define OPENMW_ESSIMPORT_GAME_H
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Weather data
|
||||||
|
struct GAME
|
||||||
|
{
|
||||||
|
struct GMDT
|
||||||
|
{
|
||||||
|
char mCellName[64];
|
||||||
|
int mFogColour;
|
||||||
|
float mFogDensity;
|
||||||
|
int mCurrentWeather, mNextWeather;
|
||||||
|
int mWeatherTransition; // 0-100 transition between weathers, top 3 bytes may be garbage
|
||||||
|
float mTimeOfNextTransition; // weather changes when gamehour == timeOfNextTransition
|
||||||
|
int masserPhase, secundaPhase; // top 3 bytes may be garbage
|
||||||
|
};
|
||||||
|
|
||||||
|
GMDT mGMDT;
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
14
apps/essimporter/importinfo.cpp
Normal file
14
apps/essimporter/importinfo.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "importinfo.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void INFO::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
mInfo = esm.getHNString("INAM");
|
||||||
|
mActorRefId = esm.getHNString("ACDT");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
apps/essimporter/importinfo.hpp
Normal file
24
apps/essimporter/importinfo.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTINFO_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTINFO_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
struct INFO
|
||||||
|
{
|
||||||
|
std::string mInfo;
|
||||||
|
std::string mActorRefId;
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,7 @@
|
||||||
#include "importinventory.hpp"
|
#include "importinventory.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <components/esm/esmreader.hpp>
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadcont.hpp>
|
#include <components/esm/loadcont.hpp>
|
||||||
|
@ -17,6 +19,7 @@ namespace ESSImport
|
||||||
InventoryItem item;
|
InventoryItem item;
|
||||||
item.mId = contItem.mItem.toString();
|
item.mId = contItem.mItem.toString();
|
||||||
item.mCount = contItem.mCount;
|
item.mCount = contItem.mCount;
|
||||||
|
item.mRelativeEquipmentSlot = -1;
|
||||||
|
|
||||||
// seems that a stack of items can have a set of subrecords for each item? rings0000.ess
|
// seems that a stack of items can have a set of subrecords for each item? rings0000.ess
|
||||||
// doesn't make any sense to me, if the values were different then the items shouldn't stack in the first place?
|
// doesn't make any sense to me, if the values were different then the items shouldn't stack in the first place?
|
||||||
|
@ -26,25 +29,14 @@ namespace ESSImport
|
||||||
if (esm.isNextSub("XIDX")) // index in the stack?
|
if (esm.isNextSub("XIDX")) // index in the stack?
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
std::string script = esm.getHNOString("SCRI");
|
item.mSCRI.load(esm);
|
||||||
// script variables?
|
|
||||||
// unsure if before or after ESM::CellRef
|
|
||||||
if (!script.empty())
|
|
||||||
{
|
|
||||||
if (esm.isNextSub("SLCS"))
|
|
||||||
esm.skipHSub();
|
|
||||||
if (esm.isNextSub("SLSD")) // Short Data?
|
|
||||||
esm.skipHSub();
|
|
||||||
if (esm.isNextSub("SLFD")) // Float Data?
|
|
||||||
esm.skipHSub();
|
|
||||||
}
|
|
||||||
|
|
||||||
// for XSOL and XCHG seen so far, but probably others too
|
// for XSOL and XCHG seen so far, but probably others too
|
||||||
item.ESM::CellRef::loadData(esm);
|
item.ESM::CellRef::loadData(esm);
|
||||||
|
|
||||||
item.mCondition = -1;
|
int charge=-1;
|
||||||
// FIXME: for Lights, this is actually a float
|
esm.getHNOT(charge, "XHLT");
|
||||||
esm.getHNOT(item.mCondition, "XHLT");
|
item.mChargeInt = charge;
|
||||||
}
|
}
|
||||||
|
|
||||||
mItems.push_back(item);
|
mItems.push_back(item);
|
||||||
|
@ -55,14 +47,21 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
// note: same item can be equipped 2 items (e.g. 2 rings)
|
// note: same item can be equipped 2 items (e.g. 2 rings)
|
||||||
// and will be *stacked* in the NPCO list, unlike openmw!
|
// and will be *stacked* in the NPCO list, unlike openmw!
|
||||||
|
// this is currently not handled properly.
|
||||||
|
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
int itemIndex; // index of the item in the NPCO list
|
int itemIndex; // index of the item in the NPCO list
|
||||||
esm.getT(itemIndex);
|
esm.getT(itemIndex);
|
||||||
|
|
||||||
|
if (itemIndex < 0 || itemIndex >= int(mItems.size()))
|
||||||
|
esm.fail("equipment item index out of range");
|
||||||
|
|
||||||
// appears to be a relative index for only the *possible* slots this item can be equipped in,
|
// appears to be a relative index for only the *possible* slots this item can be equipped in,
|
||||||
// i.e. 0 most of the time, unlike openmw slot enum index
|
// i.e. 0 most of the time
|
||||||
int slotIndex;
|
int slotIndex;
|
||||||
esm.getT(slotIndex);
|
esm.getT(slotIndex);
|
||||||
|
|
||||||
|
mItems[itemIndex].mRelativeEquipmentSlot = slotIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <components/esm/cellref.hpp>
|
#include <components/esm/cellref.hpp>
|
||||||
|
#include "importscri.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
@ -20,7 +21,8 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
std::string mId;
|
std::string mId;
|
||||||
int mCount;
|
int mCount;
|
||||||
int mCondition;
|
int mRelativeEquipmentSlot;
|
||||||
|
SCRI mSCRI;
|
||||||
};
|
};
|
||||||
std::vector<InventoryItem> mItems;
|
std::vector<InventoryItem> mItems;
|
||||||
|
|
||||||
|
|
13
apps/essimporter/importjour.cpp
Normal file
13
apps/essimporter/importjour.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "importjour.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void JOUR::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
mText = esm.getHNString("NAME");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
apps/essimporter/importjour.hpp
Normal file
25
apps/essimporter/importjour.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTJOUR_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTJOUR_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Journal
|
||||||
|
struct JOUR
|
||||||
|
{
|
||||||
|
// The entire journal, in HTML
|
||||||
|
std::string mText;
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,11 +9,9 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
esm.getHNT(mNPDT, "NPDT");
|
esm.getHNT(mNPDT, "NPDT");
|
||||||
|
|
||||||
if (esm.isNextSub("AI_E"))
|
// FIXME: use AiPackageList, need to fix getSubName()
|
||||||
esm.skipHSub();
|
while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F")
|
||||||
if (esm.isNextSub("AI_T"))
|
|| esm.isNextSub("AI_A"))
|
||||||
esm.skipHSub();
|
|
||||||
if (esm.isNextSub("AI_F"))
|
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
|
|
||||||
mInventory.load(esm);
|
mInventory.load(esm);
|
||||||
|
|
|
@ -23,6 +23,10 @@ namespace ESSImport
|
||||||
mKnownDialogueTopics.push_back(esm.getHString());
|
mKnownDialogueTopics.push_back(esm.getHString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esm.isNextSub("MNAM"))
|
||||||
|
esm.skipHSub(); // If this field is here it seems to specify the interior cell the player is in,
|
||||||
|
// but it's not always here, so it's kinda useless
|
||||||
|
|
||||||
esm.getHNT(mPNAM, "PNAM");
|
esm.getHNT(mPNAM, "PNAM");
|
||||||
|
|
||||||
if (esm.isNextSub("SNAM"))
|
if (esm.isNextSub("SNAM"))
|
||||||
|
@ -59,8 +63,11 @@ namespace ESSImport
|
||||||
mFactions.push_back(fnam);
|
mFactions.push_back(fnam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esm.isNextSub("AADT"))
|
||||||
|
esm.skipHSub(); // 44 bytes, no clue
|
||||||
|
|
||||||
if (esm.isNextSub("KNAM"))
|
if (esm.isNextSub("KNAM"))
|
||||||
esm.skipHSub();
|
esm.skipHSub(); // assigned Quick Keys, I think
|
||||||
|
|
||||||
if (esm.isNextSub("WERE"))
|
if (esm.isNextSub("WERE"))
|
||||||
{
|
{
|
||||||
|
@ -69,6 +76,10 @@ namespace ESSImport
|
||||||
esm.getSubHeader();
|
esm.getSubHeader();
|
||||||
esm.skip(152);
|
esm.skip(152);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unsure if before or after WERE
|
||||||
|
if (esm.isNextSub("ANIS"))
|
||||||
|
esm.skipHSub();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
14
apps/essimporter/importques.cpp
Normal file
14
apps/essimporter/importques.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "importques.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void QUES::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
while (esm.isNextSub("DATA"))
|
||||||
|
mInfo.push_back(esm.getHString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
apps/essimporter/importques.hpp
Normal file
28
apps/essimporter/importques.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTQUES_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTQUES_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
/// State for a quest
|
||||||
|
/// Presumably this record only exists when Tribunal is installed,
|
||||||
|
/// since pre-Tribunal there weren't any quest names in the data files.
|
||||||
|
struct QUES
|
||||||
|
{
|
||||||
|
std::string mName; // NAME, should be assigned from outside as usual
|
||||||
|
std::vector<std::string> mInfo; // list of journal entries for the quest
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
20
apps/essimporter/importscpt.cpp
Normal file
20
apps/essimporter/importscpt.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "importscpt.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void SCPT::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
esm.getHNT(mSCHD, "SCHD");
|
||||||
|
|
||||||
|
mSCRI.load(esm);
|
||||||
|
|
||||||
|
mRNAM = -1;
|
||||||
|
esm.getHNOT(mRNAM, "RNAM");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
apps/essimporter/importscpt.hpp
Normal file
32
apps/essimporter/importscpt.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTSCPT_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTSCPT_H
|
||||||
|
|
||||||
|
#include "importscri.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/loadscpt.hpp>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
// A running global script
|
||||||
|
// TODO: test how targeted scripts are saved
|
||||||
|
struct SCPT
|
||||||
|
{
|
||||||
|
ESM::Script::SCHD mSCHD;
|
||||||
|
|
||||||
|
// values of local variables
|
||||||
|
SCRI mSCRI;
|
||||||
|
|
||||||
|
int mRNAM; // unknown, seems to be -1 for some scripts, some huge integer for others
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
55
apps/essimporter/importscri.cpp
Normal file
55
apps/essimporter/importscri.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include "importscri.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
void SCRI::load(ESM::ESMReader &esm)
|
||||||
|
{
|
||||||
|
mScript = esm.getHNOString("SCRI");
|
||||||
|
|
||||||
|
int numShorts = 0, numLongs = 0, numFloats = 0;
|
||||||
|
if (esm.isNextSub("SLCS"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
esm.getT(numShorts);
|
||||||
|
esm.getT(numLongs);
|
||||||
|
esm.getT(numFloats);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esm.isNextSub("SLSD"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
for (int i=0; i<numShorts; ++i)
|
||||||
|
{
|
||||||
|
short val;
|
||||||
|
esm.getT(val);
|
||||||
|
mShorts.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// I haven't seen Longs in a save file yet, but SLLD would make sense for the name
|
||||||
|
// TODO: test this
|
||||||
|
if (esm.isNextSub("SLLD"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
for (int i=0; i<numLongs; ++i)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
esm.getT(val);
|
||||||
|
mLongs.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (esm.isNextSub("SLFD"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
for (int i=0; i<numFloats; ++i)
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
esm.getT(val);
|
||||||
|
mFloats.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
apps/essimporter/importscri.hpp
Normal file
30
apps/essimporter/importscri.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef OPENMW_ESSIMPORT_IMPORTSCRI_H
|
||||||
|
#define OPENMW_ESSIMPORT_IMPORTSCRI_H
|
||||||
|
|
||||||
|
#include <components/esm/variant.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESSImport
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Local variable assigments for a running script
|
||||||
|
struct SCRI
|
||||||
|
{
|
||||||
|
std::string mScript;
|
||||||
|
|
||||||
|
std::vector<short> mShorts;
|
||||||
|
std::vector<int> mLongs;
|
||||||
|
std::vector<float> mFloats;
|
||||||
|
|
||||||
|
void load(ESM::ESMReader& esm);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,7 +12,7 @@ namespace bfs = boost::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,15 @@ int main(int argc, const char** argv)
|
||||||
if (vm.count("compare"))
|
if (vm.count("compare"))
|
||||||
importer.compare();
|
importer.compare();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
const std::string& ext = ".omwsave";
|
||||||
|
if (boost::filesystem::exists(boost::filesystem::path(outputFile))
|
||||||
|
&& (outputFile.size() < ext.size() || outputFile.substr(outputFile.size()-ext.size()) != ext))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Output file already exists and does not end in .omwsave. Did you mean to use --compare?");
|
||||||
|
}
|
||||||
importer.run();
|
importer.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1053,13 +1053,13 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
{
|
{
|
||||||
return record.get().mCharge;
|
return record.get().mChargeInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
{
|
{
|
||||||
ESXRecordT record2 = record.get();
|
ESXRecordT record2 = record.get();
|
||||||
record2.mCharge = data.toInt();
|
record2.mChargeInt = data.toInt();
|
||||||
record.setModified (record2);
|
record.setModified (record2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0;
|
||||||
|
|
||||||
/// Changes faction1's opinion of faction2 by \a diff.
|
/// Changes faction1's opinion of faction2 by \a diff.
|
||||||
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff) = 0;
|
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff) = 0;
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0;
|
||||||
|
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace MWBase
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0;
|
||||||
virtual int countSavedGameRecords() const = 0;
|
virtual int countSavedGameRecords() const = 0;
|
||||||
|
|
||||||
/// Does the current stack of GUI-windows permit saving?
|
/// Does the current stack of GUI-windows permit saving?
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type,
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type,
|
||||||
const std::map<int, int>& contentFileMap) = 0;
|
const std::map<int, int>& contentFileMap) = 0;
|
||||||
|
|
||||||
virtual MWWorld::CellStore *getExterior (int x, int y) = 0;
|
virtual MWWorld::CellStore *getExterior (int x, int y) = 0;
|
||||||
|
|
|
@ -26,27 +26,6 @@
|
||||||
#include "../mwrender/actors.hpp"
|
#include "../mwrender/actors.hpp"
|
||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct LightCustomData : public MWWorld::CustomData
|
|
||||||
{
|
|
||||||
float mTime;
|
|
||||||
///< Time remaining
|
|
||||||
|
|
||||||
LightCustomData(MWWorld::Ptr ptr)
|
|
||||||
{
|
|
||||||
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
|
||||||
mTime = ref->mBase->mData.mTime;
|
|
||||||
}
|
|
||||||
///< Constructs this CustomData from the base values for Ptr.
|
|
||||||
|
|
||||||
virtual MWWorld::CustomData *clone() const
|
|
||||||
{
|
|
||||||
return new LightCustomData (*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
std::string Light::getId (const MWWorld::Ptr& ptr) const
|
std::string Light::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
@ -219,17 +198,16 @@ namespace MWClass
|
||||||
|
|
||||||
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
|
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
|
||||||
{
|
{
|
||||||
ensureCustomData(ptr);
|
ptr.getCellRef().setChargeFloat(duration);
|
||||||
|
|
||||||
float &timeRemaining = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
|
||||||
timeRemaining = duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const
|
float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
ensureCustomData(ptr);
|
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
||||||
|
if (ptr.getCellRef().getCharge() == -1)
|
||||||
return dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
return ref->mBase->mData.mTime;
|
||||||
|
else
|
||||||
|
return ptr.getCellRef().getChargeFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr
|
MWWorld::Ptr
|
||||||
|
@ -241,12 +219,6 @@ namespace MWClass
|
||||||
return MWWorld::Ptr(&cell.get<ESM::Light>().insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Light>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
|
|
||||||
{
|
|
||||||
if (!ptr.getRefData().getCustomData())
|
|
||||||
ptr.getRefData().setCustomData(new LightCustomData(ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||||
{
|
{
|
||||||
return npcServices & ESM::NPC::Lights;
|
return npcServices & ESM::NPC::Lights;
|
||||||
|
@ -282,22 +254,6 @@ namespace MWClass
|
||||||
return std::make_pair(1,"");
|
return std::make_pair(1,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
ensureCustomData (ptr);
|
|
||||||
|
|
||||||
dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime = state.mTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Light::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
ensureCustomData (ptr);
|
|
||||||
|
|
||||||
state.mTime = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Light::getSound(const MWWorld::Ptr& ptr) const
|
std::string Light::getSound(const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
return ptr.get<ESM::Light>()->mBase->mSound;
|
return ptr.get<ESM::Light>()->mBase->mSound;
|
||||||
|
|
|
@ -10,8 +10,6 @@ namespace MWClass
|
||||||
virtual MWWorld::Ptr
|
virtual MWWorld::Ptr
|
||||||
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
||||||
|
|
||||||
void ensureCustomData (const MWWorld::Ptr& ptr) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Return ID of \a ptr
|
/// Return ID of \a ptr
|
||||||
|
@ -75,14 +73,6 @@ namespace MWClass
|
||||||
|
|
||||||
std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const;
|
std::pair<int, std::string> canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const;
|
||||||
|
|
||||||
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
|
||||||
const;
|
|
||||||
///< Read additional state from \a state into \a ptr.
|
|
||||||
|
|
||||||
virtual void writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
|
||||||
const;
|
|
||||||
///< Write additional state from \a ptr into \a state.
|
|
||||||
|
|
||||||
virtual std::string getSound(const MWWorld::Ptr& ptr) const;
|
virtual std::string getSound(const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,7 +647,7 @@ namespace MWDialogue
|
||||||
writer.endRecord (ESM::REC_DIAS);
|
writer.endRecord (ESM::REC_DIAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::readRecord (ESM::ESMReader& reader, int32_t type)
|
void DialogueManager::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_DIAS)
|
if (type==ESM::REC_DIAS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
/// Changes faction1's opinion of faction2 by \a diff.
|
/// Changes faction1's opinion of faction2 by \a diff.
|
||||||
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff);
|
virtual void modFactionReaction (const std::string& faction1, const std::string& faction2, int diff);
|
||||||
|
|
|
@ -227,9 +227,9 @@ namespace MWDialogue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Journal::readRecord (ESM::ESMReader& reader, int32_t type)
|
void Journal::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_JOUR)
|
if (type==ESM::REC_JOUR || type==ESM::REC_JOUR_LEGACY)
|
||||||
{
|
{
|
||||||
ESM::JournalEntry record;
|
ESM::JournalEntry record;
|
||||||
record.load (reader);
|
record.load (reader);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -886,7 +886,7 @@ namespace MWGui
|
||||||
writer.endRecord(ESM::REC_GMAP);
|
writer.endRecord(ESM::REC_GMAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::readRecord(ESM::ESMReader &reader, int32_t type)
|
void MapWindow::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type == ESM::REC_GMAP)
|
if (type == ESM::REC_GMAP)
|
||||||
{
|
{
|
||||||
|
|
|
@ -177,7 +177,7 @@ namespace MWGui
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||||
void readRecord (ESM::ESMReader& reader, int32_t type);
|
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
|
|
|
@ -431,7 +431,7 @@ namespace MWGui
|
||||||
writer.endRecord(ESM::REC_KEYS);
|
writer.endRecord(ESM::REC_KEYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickKeysMenu::readRecord(ESM::ESMReader &reader, int32_t type)
|
void QuickKeysMenu::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type != ESM::REC_KEYS)
|
if (type != ESM::REC_KEYS)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace MWGui
|
||||||
|
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer);
|
void write (ESM::ESMWriter& writer);
|
||||||
void readRecord (ESM::ESMReader& reader, int32_t type);
|
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1620,7 +1620,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type)
|
void WindowManager::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type == ESM::REC_GMAP)
|
if (type == ESM::REC_GMAP)
|
||||||
mMap->readRecord(reader, type);
|
mMap->readRecord(reader, type);
|
||||||
|
|
|
@ -306,7 +306,7 @@ namespace MWGui
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
virtual int countSavedGameRecords() const;
|
virtual int countSavedGameRecords() const;
|
||||||
|
|
||||||
/// Does the current stack of GUI-windows permit saving?
|
/// Does the current stack of GUI-windows permit saving?
|
||||||
|
|
|
@ -1468,7 +1468,7 @@ namespace MWMechanics
|
||||||
writer.endRecord(ESM::REC_DCOU);
|
writer.endRecord(ESM::REC_DCOU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::readRecord (ESM::ESMReader& reader, int32_t type)
|
void Actors::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type == ESM::REC_DCOU)
|
if (type == ESM::REC_DCOU)
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
|
||||||
|
|
||||||
void readRecord (ESM::ESMReader& reader, int32_t type);
|
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
void clear(); // Clear death counter
|
void clear(); // Clear death counter
|
||||||
|
|
||||||
|
|
|
@ -1360,7 +1360,7 @@ namespace MWMechanics
|
||||||
mActors.write(writer, listener);
|
mActors.write(writer, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::readRecord(ESM::ESMReader &reader, int32_t type)
|
void MechanicsManager::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
mActors.readRecord(reader, type);
|
mActors.readRecord(reader, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
|
|
|
@ -472,9 +472,7 @@ namespace MWMechanics
|
||||||
applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude);
|
applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude);
|
||||||
|
|
||||||
// Re-casting a summon effect will remove the creature from previous castings of that effect.
|
// Re-casting a summon effect will remove the creature from previous castings of that effect.
|
||||||
if (effectIt->mEffectID >= ESM::MagicEffect::SummonScamp
|
if (isSummoningEffect(effectIt->mEffectID) && !target.isEmpty() && target.getClass().isActor())
|
||||||
&& effectIt->mEffectID <= ESM::MagicEffect::SummonStormAtronach
|
|
||||||
&& !target.isEmpty() && target.getClass().isActor())
|
|
||||||
{
|
{
|
||||||
CreatureStats& targetStats = target.getClass().getCreatureStats(target);
|
CreatureStats& targetStats = target.getClass().getCreatureStats(target);
|
||||||
std::map<CreatureStats::SummonKey, int>::iterator found = targetStats.getSummonedCreatureMap().find(std::make_pair(effectIt->mEffectID, mId));
|
std::map<CreatureStats::SummonKey, int>::iterator found = targetStats.getSummonedCreatureMap().find(std::make_pair(effectIt->mEffectID, mId));
|
||||||
|
@ -956,4 +954,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
return static_cast<int>((result < 1) ? 1 : result);
|
return static_cast<int>((result < 1) ? 1 : result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSummoningEffect(int effectId)
|
||||||
|
{
|
||||||
|
return ((effectId >= ESM::MagicEffect::SummonScamp
|
||||||
|
&& effectId <= ESM::MagicEffect::SummonStormAtronach)
|
||||||
|
|| effectId == ESM::MagicEffect::SummonCenturionSphere
|
||||||
|
|| (effectId >= ESM::MagicEffect::SummonFabricant
|
||||||
|
&& effectId <= ESM::MagicEffect::SummonCreature05));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
ESM::Skill::SkillEnum spellSchoolToSkill(int school);
|
||||||
|
|
||||||
|
bool isSummoningEffect(int effectId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param spell spell to cast
|
* @param spell spell to cast
|
||||||
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
||||||
|
|
|
@ -312,21 +312,17 @@ namespace MWMechanics
|
||||||
|
|
||||||
void Spells::readState(const ESM::SpellState &state)
|
void Spells::readState(const ESM::SpellState &state)
|
||||||
{
|
{
|
||||||
mSpells = state.mSpells;
|
for (TContainer::const_iterator it = state.mSpells.begin(); it != state.mSpells.end(); ++it)
|
||||||
mSelectedSpell = state.mSelectedSpell;
|
|
||||||
|
|
||||||
// Discard spells that are no longer available due to changed content files
|
|
||||||
for (TContainer::iterator iter = mSpells.begin(); iter!=mSpells.end();)
|
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(iter->first);
|
// Discard spells that are no longer available due to changed content files
|
||||||
if (!spell)
|
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(it->first);
|
||||||
|
if (spell)
|
||||||
{
|
{
|
||||||
if (iter->first == mSelectedSpell)
|
mSpells[it->first] = it->second;
|
||||||
mSelectedSpell = "";
|
|
||||||
mSpells.erase(iter++);
|
if (it->first == state.mSelectedSpell)
|
||||||
|
mSelectedSpell = it->first;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to discard spells here (doesn't really matter if non existent ids are kept)
|
// No need to discard spells here (doesn't really matter if non existent ids are kept)
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/spellcasting.hpp"
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
|
@ -51,8 +53,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
void UpdateSummonedCreatures::visit(EffectKey key, const std::string &sourceName, const std::string &sourceId, int casterActorId, float magnitude, float remainingTime, float totalTime)
|
void UpdateSummonedCreatures::visit(EffectKey key, const std::string &sourceName, const std::string &sourceId, int casterActorId, float magnitude, float remainingTime, float totalTime)
|
||||||
{
|
{
|
||||||
if (key.mId >= ESM::MagicEffect::SummonScamp
|
if (isSummoningEffect(key.mId) && magnitude > 0)
|
||||||
&& key.mId <= ESM::MagicEffect::SummonStormAtronach && magnitude > 0)
|
|
||||||
{
|
{
|
||||||
mActiveEffects.insert(std::make_pair(key.mId, sourceId));
|
mActiveEffects.insert(std::make_pair(key.mId, sourceId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,17 +263,27 @@ void NpcAnimation::updateNpcBase()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isVampire)
|
mHeadModel = "";
|
||||||
|
if (isVampire) // FIXME: fall back to regular head when getVampireHead fails?
|
||||||
mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female);
|
mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female);
|
||||||
else if (!mNpc->mHead.empty())
|
else if (!mNpc->mHead.empty())
|
||||||
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
|
{
|
||||||
else
|
const ESM::BodyPart* bp = store.get<ESM::BodyPart>().search(mNpc->mHead);
|
||||||
mHeadModel = "";
|
if (bp)
|
||||||
|
mHeadModel = "meshes\\" + bp->mModel;
|
||||||
|
else
|
||||||
|
std::cerr << "Failed to load body part '" << mNpc->mHead << "'" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHairModel = "";
|
||||||
if (!mNpc->mHair.empty())
|
if (!mNpc->mHair.empty())
|
||||||
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;
|
{
|
||||||
else
|
const ESM::BodyPart* bp = store.get<ESM::BodyPart>().search(mNpc->mHair);
|
||||||
mHairModel = "";
|
if (bp)
|
||||||
|
mHairModel = "meshes\\" + bp->mModel;
|
||||||
|
else
|
||||||
|
std::cerr << "Failed to load body part '" << mNpc->mHair << "'" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
|
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
|
||||||
|
@ -801,6 +811,8 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
|
||||||
bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm))
|
bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm))
|
||||||
bodypart = NULL;
|
bodypart = NULL;
|
||||||
}
|
}
|
||||||
|
else if (!bodypart)
|
||||||
|
std::cerr << "Failed to find body part '" << part->mFemale << "'" << std::endl;
|
||||||
}
|
}
|
||||||
if(!bodypart && !part->mMale.empty())
|
if(!bodypart && !part->mMale.empty())
|
||||||
{
|
{
|
||||||
|
@ -814,6 +826,8 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
|
||||||
bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm))
|
bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm))
|
||||||
bodypart = NULL;
|
bodypart = NULL;
|
||||||
}
|
}
|
||||||
|
else if (!bodypart)
|
||||||
|
std::cerr << "Failed to find body part '" << part->mMale << "'" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bodypart)
|
if(bodypart)
|
||||||
|
|
|
@ -443,5 +443,6 @@ op 0x20002fc: RemoveFromLevCreature
|
||||||
op 0x20002fd: AddToLevItem
|
op 0x20002fd: AddToLevItem
|
||||||
op 0x20002fe: RemoveFromLevItem
|
op 0x20002fe: RemoveFromLevItem
|
||||||
op 0x20002ff: SetFactionReaction
|
op 0x20002ff: SetFactionReaction
|
||||||
|
op 0x2000300: EnableLevelupMenu
|
||||||
|
|
||||||
opcodes 0x2000300-0x3ffffff unused
|
opcodes 0x2000301-0x3ffffff unused
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalScripts::readRecord (ESM::ESMReader& reader, int32_t type)
|
bool GlobalScripts::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_GSCR)
|
if (type==ESM::REC_GSCR)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace MWScript
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
///< Records for variables that do not exist are dropped silently.
|
///< Records for variables that do not exist are dropped silently.
|
||||||
///
|
///
|
||||||
/// \return Known type?
|
/// \return Known type?
|
||||||
|
|
|
@ -231,6 +231,8 @@ namespace MWScript
|
||||||
new OpShowDialogue (MWGui::GM_Race));
|
new OpShowDialogue (MWGui::GM_Race));
|
||||||
interpreter.installSegment5 (Compiler::Gui::opcodeEnableStatsReviewMenu,
|
interpreter.installSegment5 (Compiler::Gui::opcodeEnableStatsReviewMenu,
|
||||||
new OpShowDialogue (MWGui::GM_Review));
|
new OpShowDialogue (MWGui::GM_Review));
|
||||||
|
interpreter.installSegment5 (Compiler::Gui::opcodeEnableLevelupMenu,
|
||||||
|
new OpShowDialogue (MWGui::GM_Levelup));
|
||||||
|
|
||||||
interpreter.installSegment5 (Compiler::Gui::opcodeEnableInventoryMenu,
|
interpreter.installSegment5 (Compiler::Gui::opcodeEnableInventoryMenu,
|
||||||
new OpEnableWindow (MWGui::GW_Inventory));
|
new OpEnableWindow (MWGui::GW_Inventory));
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
void Locals::configure (const ESM::Script& script)
|
void Locals::configure (const ESM::Script& script)
|
||||||
|
@ -124,27 +126,60 @@ namespace MWScript
|
||||||
const Compiler::Locals& declarations =
|
const Compiler::Locals& declarations =
|
||||||
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
|
|
||||||
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
|
int index = 0, numshorts = 0, numlongs = 0;
|
||||||
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
|
for (unsigned int v=0; v<locals.mVariables.size();++v)
|
||||||
{
|
{
|
||||||
char type = declarations.getType (iter->first);
|
ESM::VarType type = locals.mVariables[v].second.getType();
|
||||||
char index = declarations.getIndex (iter->first);
|
if (type == ESM::VT_Short)
|
||||||
|
++numshorts;
|
||||||
|
else if (type == ESM::VT_Int)
|
||||||
|
++numlongs;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
|
||||||
|
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter,++index)
|
||||||
|
{
|
||||||
|
if (iter->first.empty())
|
||||||
{
|
{
|
||||||
switch (type)
|
// no variable names available (this will happen for legacy, i.e. ESS-imported savegames only)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
case 's': mShorts.at (index) = iter->second.getInteger(); break;
|
if (index >= numshorts+numlongs)
|
||||||
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
|
mFloats.at(index - (numshorts+numlongs)) = iter->second.getFloat();
|
||||||
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
|
else if (index >= numshorts)
|
||||||
|
mLongs.at(index - numshorts) = iter->second.getInteger();
|
||||||
// silently ignore locals that don't exist anymore
|
else
|
||||||
|
mShorts.at(index) = iter->second.getInteger();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to read local variable state for script '"
|
||||||
|
<< script << "' (legacy format): " << e.what()
|
||||||
|
<< "\nNum shorts: " << numshorts << " / " << mShorts.size()
|
||||||
|
<< " Num longs: " << numlongs << " / " << mLongs.size() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
else
|
||||||
{
|
{
|
||||||
// ignore type changes
|
char type = declarations.getType (iter->first);
|
||||||
/// \todo write to log
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,6 +368,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::REC_JOUR:
|
case ESM::REC_JOUR:
|
||||||
|
case ESM::REC_JOUR_LEGACY:
|
||||||
case ESM::REC_QUES:
|
case ESM::REC_QUES:
|
||||||
|
|
||||||
MWBase::Environment::get().getJournal()->readRecord (reader, n.val);
|
MWBase::Environment::get().getJournal()->readRecord (reader, n.val);
|
||||||
|
|
|
@ -81,15 +81,29 @@ namespace MWWorld
|
||||||
|
|
||||||
int CellRef::getCharge() const
|
int CellRef::getCharge() const
|
||||||
{
|
{
|
||||||
return mCellRef.mCharge;
|
return mCellRef.mChargeInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellRef::setCharge(int charge)
|
void CellRef::setCharge(int charge)
|
||||||
{
|
{
|
||||||
if (charge != mCellRef.mCharge)
|
if (charge != mCellRef.mChargeInt)
|
||||||
{
|
{
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
mCellRef.mCharge = charge;
|
mCellRef.mChargeInt = charge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float CellRef::getChargeFloat() const
|
||||||
|
{
|
||||||
|
return mCellRef.mChargeFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CellRef::setChargeFloat(float charge)
|
||||||
|
{
|
||||||
|
if (charge != mCellRef.mChargeFloat)
|
||||||
|
{
|
||||||
|
mChanged = true;
|
||||||
|
mCellRef.mChargeFloat = charge;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,11 @@ namespace MWWorld
|
||||||
|
|
||||||
// For weapon or armor, this is the remaining item health.
|
// For weapon or armor, this is the remaining item health.
|
||||||
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
|
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
|
||||||
|
// If this returns int(-1) it means full health.
|
||||||
int getCharge() const;
|
int getCharge() const;
|
||||||
|
float getChargeFloat() const; // Implemented as union with int charge
|
||||||
void setCharge(int charge);
|
void setCharge(int charge);
|
||||||
|
void setChargeFloat(float charge);
|
||||||
|
|
||||||
// The NPC that owns this object (and will get angry if you steal it)
|
// The NPC that owns this object (and will get angry if you steal it)
|
||||||
std::string getOwner() const;
|
std::string getOwner() const;
|
||||||
|
|
|
@ -299,7 +299,7 @@ void MWWorld::Cells::write (ESM::ESMWriter& writer, Loading::Listener& progress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, int32_t type,
|
bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, uint32_t type,
|
||||||
const std::map<int, int>& contentFileMap)
|
const std::map<int, int>& contentFileMap)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_CSTA)
|
if (type==ESM::REC_CSTA)
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type,
|
bool readRecord (ESM::ESMReader& reader, uint32_t type,
|
||||||
const std::map<int, int>& contentFileMap);
|
const std::map<int, int>& contentFileMap);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -466,7 +466,7 @@ namespace MWWorld
|
||||||
// List moved references, from separately tracked list.
|
// List moved references, from separately tracked list.
|
||||||
for (ESM::CellRefTracker::const_iterator it = mCell->mLeasedRefs.begin(); it != mCell->mLeasedRefs.end(); ++it)
|
for (ESM::CellRefTracker::const_iterator it = mCell->mLeasedRefs.begin(); it != mCell->mLeasedRefs.end(); ++it)
|
||||||
{
|
{
|
||||||
ESM::CellRef &ref = const_cast<ESM::CellRef&>(*it);
|
const ESM::CellRef &ref = *it;
|
||||||
|
|
||||||
mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID));
|
mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID));
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState (CellRefList<T
|
||||||
return ContainerStoreIterator (this, --collection.mList.end());
|
return ContainerStoreIterator (this, --collection.mList.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::storeEquipmentState(const MWWorld::LiveCellRefBase &ref, int index, ESM::InventoryState &inventory) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::readEquipmentState(const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState &inventory)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void MWWorld::ContainerStore::storeState (const LiveCellRef<T>& ref, ESM::ObjectState& state) const
|
void MWWorld::ContainerStore::storeState (const LiveCellRef<T>& ref, ESM::ObjectState& state) const
|
||||||
{
|
{
|
||||||
|
@ -86,8 +94,8 @@ void MWWorld::ContainerStore::storeState (const LiveCellRef<T>& ref, ESM::Object
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void MWWorld::ContainerStore::storeStates (const CellRefList<T>& collection,
|
void MWWorld::ContainerStore::storeStates (CellRefList<T>& collection,
|
||||||
std::vector<std::pair<ESM::ObjectState, int> >& states, bool equipable) const
|
ESM::InventoryState& inventory, int& index, bool equipable) const
|
||||||
{
|
{
|
||||||
for (typename CellRefList<T>::List::const_iterator iter (collection.mList.begin());
|
for (typename CellRefList<T>::List::const_iterator iter (collection.mList.begin());
|
||||||
iter!=collection.mList.end(); ++iter)
|
iter!=collection.mList.end(); ++iter)
|
||||||
|
@ -96,18 +104,13 @@ void MWWorld::ContainerStore::storeStates (const CellRefList<T>& collection,
|
||||||
continue;
|
continue;
|
||||||
ESM::ObjectState state;
|
ESM::ObjectState state;
|
||||||
storeState (*iter, state);
|
storeState (*iter, state);
|
||||||
int slot = equipable ? getSlot (*iter) : -1;
|
if (equipable)
|
||||||
states.push_back (std::make_pair (state, slot));
|
storeEquipmentState(*iter, index, inventory);
|
||||||
|
inventory.mItems.push_back (state);
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWWorld::ContainerStore::getSlot (const MWWorld::LiveCellRefBase& ref) const
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWWorld::ContainerStore::setSlot (const MWWorld::ContainerStoreIterator& iter, int slot) {}
|
|
||||||
|
|
||||||
const std::string MWWorld::ContainerStore::sGoldId = "gold_001";
|
const std::string MWWorld::ContainerStore::sGoldId = "gold_001";
|
||||||
|
|
||||||
MWWorld::ContainerStore::ContainerStore() : mCachedWeight (0), mWeightUpToDate (false) {}
|
MWWorld::ContainerStore::ContainerStore() : mCachedWeight (0), mWeightUpToDate (false) {}
|
||||||
|
@ -641,62 +644,66 @@ MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id)
|
||||||
return Ptr();
|
return Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::writeState (ESM::InventoryState& state) const
|
void MWWorld::ContainerStore::writeState (ESM::InventoryState& state)
|
||||||
{
|
{
|
||||||
state.mItems.clear();
|
state.mItems.clear();
|
||||||
|
|
||||||
storeStates (potions, state.mItems);
|
int index = 0;
|
||||||
storeStates (appas, state.mItems);
|
storeStates (potions, state, index);
|
||||||
storeStates (armors, state.mItems, true);
|
storeStates (appas, state, index);
|
||||||
storeStates (books, state.mItems);
|
storeStates (armors, state, index, true);
|
||||||
storeStates (clothes, state.mItems, true);
|
storeStates (books, state, index, true); // not equipable as such, but for selectedEnchantItem
|
||||||
storeStates (ingreds, state.mItems);
|
storeStates (clothes, state, index, true);
|
||||||
storeStates (lockpicks, state.mItems, true);
|
storeStates (ingreds, state, index);
|
||||||
storeStates (miscItems, state.mItems);
|
storeStates (lockpicks, state, index, true);
|
||||||
storeStates (probes, state.mItems, true);
|
storeStates (miscItems, state, index);
|
||||||
storeStates (repairs, state.mItems);
|
storeStates (probes, state, index, true);
|
||||||
storeStates (weapons, state.mItems, true);
|
storeStates (repairs, state, index);
|
||||||
storeStates (lights, state.mItems, true);
|
storeStates (weapons, state, index, true);
|
||||||
|
storeStates (lights, state, index, true);
|
||||||
|
|
||||||
state.mLevelledItemMap = mLevelledItemMap;
|
state.mLevelledItemMap = mLevelledItemMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::readState (const ESM::InventoryState& state)
|
void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
for (std::vector<std::pair<ESM::ObjectState, int> >::const_iterator
|
int index = 0;
|
||||||
iter (state.mItems.begin()); iter!=state.mItems.end(); ++iter)
|
for (std::vector<ESM::ObjectState>::const_iterator
|
||||||
|
iter (inventory.mItems.begin()); iter!=inventory.mItems.end(); ++iter)
|
||||||
{
|
{
|
||||||
int slot = iter->second;
|
const ESM::ObjectState& state = *iter;
|
||||||
|
|
||||||
const ESM::ObjectState& state = iter->first;
|
|
||||||
|
|
||||||
int type = MWBase::Environment::get().getWorld()->getStore().find(state.mRef.mRefID);
|
int type = MWBase::Environment::get().getWorld()->getStore().find(state.mRef.mRefID);
|
||||||
|
|
||||||
|
int thisIndex = index++;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ESM::REC_ALCH: getState (potions, iter->first); break;
|
case ESM::REC_ALCH: getState (potions, state); break;
|
||||||
case ESM::REC_APPA: getState (appas, iter->first); break;
|
case ESM::REC_APPA: getState (appas, state); break;
|
||||||
case ESM::REC_ARMO: setSlot (getState (armors, iter->first), slot); break;
|
case ESM::REC_ARMO: readEquipmentState (getState (armors, state), thisIndex, inventory); break;
|
||||||
case ESM::REC_BOOK: getState (books, iter->first); break;
|
case ESM::REC_BOOK: readEquipmentState (getState (books, state), thisIndex, inventory); break; // not equipable as such, but for selectedEnchantItem
|
||||||
case ESM::REC_CLOT: setSlot (getState (clothes, iter->first), slot); break;
|
case ESM::REC_CLOT: readEquipmentState (getState (clothes, state), thisIndex, inventory); break;
|
||||||
case ESM::REC_INGR: getState (ingreds, iter->first); break;
|
case ESM::REC_INGR: getState (ingreds, state); break;
|
||||||
case ESM::REC_LOCK: setSlot (getState (lockpicks, iter->first), slot); break;
|
case ESM::REC_LOCK: readEquipmentState (getState (lockpicks, state), thisIndex, inventory); break;
|
||||||
case ESM::REC_MISC: getState (miscItems, iter->first); break;
|
case ESM::REC_MISC: getState (miscItems, state); break;
|
||||||
case ESM::REC_PROB: setSlot (getState (probes, iter->first), slot); break;
|
case ESM::REC_PROB: readEquipmentState (getState (probes, state), thisIndex, inventory); break;
|
||||||
case ESM::REC_REPA: getState (repairs, iter->first); break;
|
case ESM::REC_REPA: getState (repairs, state); break;
|
||||||
case ESM::REC_WEAP: setSlot (getState (weapons, iter->first), slot); break;
|
case ESM::REC_WEAP: readEquipmentState (getState (weapons, state), thisIndex, inventory); break;
|
||||||
case ESM::REC_LIGH: setSlot (getState (lights, iter->first), slot); break;
|
case ESM::REC_LIGH: readEquipmentState (getState (lights, state), thisIndex, inventory); break;
|
||||||
|
case 0:
|
||||||
|
std::cerr << "Dropping reference to '" << state.mRef.mRefID << "' (object no longer exists)" << std::endl;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "invalid item type in inventory state, refid " << state.mRef.mRefID << std::endl;
|
std::cerr << "Invalid item type in inventory state, refid " << state.mRef.mRefID << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mLevelledItemMap = state.mLevelledItemMap;
|
mLevelledItemMap = inventory.mLevelledItemMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,16 +85,13 @@ namespace MWWorld
|
||||||
void storeState (const LiveCellRef<T>& ref, ESM::ObjectState& state) const;
|
void storeState (const LiveCellRef<T>& ref, ESM::ObjectState& state) const;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void storeStates (const CellRefList<T>& collection,
|
void storeStates (CellRefList<T>& collection,
|
||||||
std::vector<std::pair<ESM::ObjectState, int> >& states,
|
ESM::InventoryState& inventory, int& index,
|
||||||
bool equipable = false) const;
|
bool equipable = false) const;
|
||||||
|
|
||||||
virtual int getSlot (const MWWorld::LiveCellRefBase& ref) const;
|
virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const;
|
||||||
///< Return inventory slot that \a ref is in or -1 (if \a ref is not in a slot).
|
|
||||||
|
|
||||||
virtual void setSlot (const MWWorld::ContainerStoreIterator& iter, int slot);
|
|
||||||
///< Set slot for \a iter. Ignored if \a iter is an end iterator or if slot==-1.
|
|
||||||
|
|
||||||
|
virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ContainerStore();
|
ContainerStore();
|
||||||
|
@ -171,7 +168,8 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr search (const std::string& id);
|
Ptr search (const std::string& id);
|
||||||
|
|
||||||
virtual void writeState (ESM::InventoryState& state) const;
|
/// \todo make this method const once const-correct ContainerStoreIterators are available
|
||||||
|
virtual void writeState (ESM::InventoryState& state);
|
||||||
|
|
||||||
virtual void readState (const ESM::InventoryState& state);
|
virtual void readState (const ESM::InventoryState& state);
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ void ESMStore::setUp()
|
||||||
mCreatureLists.write (writer, progress);
|
mCreatureLists.write (writer, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESMStore::readRecord (ESM::ESMReader& reader, int32_t type)
|
bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -233,7 +233,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
///< \return Known type?
|
///< \return Known type?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Globals::readRecord (ESM::ESMReader& reader, int32_t type)
|
bool Globals::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_GLOB)
|
if (type==ESM::REC_GLOB)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
///< Records for variables that do not exist are dropped silently.
|
///< Records for variables that do not exist are dropped silently.
|
||||||
///
|
///
|
||||||
/// \return Known type?
|
/// \return Known type?
|
||||||
|
|
|
@ -49,19 +49,47 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots_)
|
||||||
slots_.push_back (end());
|
slots_.push_back (end());
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWWorld::InventoryStore::getSlot (const MWWorld::LiveCellRefBase& ref) const
|
void MWWorld::InventoryStore::storeEquipmentState(const MWWorld::LiveCellRefBase &ref, int index, ESM::InventoryState &inventory) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i<static_cast<int> (mSlots.size()); ++i)
|
for (int i = 0; i<static_cast<int> (mSlots.size()); ++i)
|
||||||
if (mSlots[i].getType()!=-1 && mSlots[i]->getBase()==&ref)
|
if (mSlots[i].getType()!=-1 && mSlots[i]->getBase()==&ref)
|
||||||
return i;
|
{
|
||||||
|
inventory.mEquipmentSlots[index] = i;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
if (mSelectedEnchantItem.getType()!=-1 && mSelectedEnchantItem->getBase() == &ref)
|
||||||
|
inventory.mSelectedEnchantItem = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::InventoryStore::setSlot (const MWWorld::ContainerStoreIterator& iter, int slot)
|
void MWWorld::InventoryStore::readEquipmentState(const MWWorld::ContainerStoreIterator &iter, int index, const ESM::InventoryState &inventory)
|
||||||
{
|
{
|
||||||
if (iter!=end() && slot>=0 && slot<Slots)
|
if (index == inventory.mSelectedEnchantItem)
|
||||||
mSlots[slot] = iter;
|
mSelectedEnchantItem = iter;
|
||||||
|
|
||||||
|
std::map<int, int>::const_iterator found = inventory.mEquipmentSlots.find(index);
|
||||||
|
if (found != inventory.mEquipmentSlots.end())
|
||||||
|
{
|
||||||
|
if (found->second < 0 || found->second >= MWWorld::InventoryStore::Slots)
|
||||||
|
throw std::runtime_error("Invalid slot index in inventory state");
|
||||||
|
|
||||||
|
// make sure the item can actually be equipped in this slot
|
||||||
|
int slot = found->second;
|
||||||
|
std::pair<std::vector<int>, bool> allowedSlots = iter->getClass().getEquipmentSlots(*iter);
|
||||||
|
if (!allowedSlots.first.size())
|
||||||
|
return;
|
||||||
|
if (std::find(allowedSlots.first.begin(), allowedSlots.first.end(), slot) == allowedSlots.first.end())
|
||||||
|
slot = allowedSlots.first.front();
|
||||||
|
|
||||||
|
// unstack if required
|
||||||
|
if (!allowedSlots.second && iter->getRefData().getCount() > 1)
|
||||||
|
{
|
||||||
|
MWWorld::ContainerStoreIterator newIter = addNewStack(*iter, 1);
|
||||||
|
iter->getRefData().setCount(iter->getRefData().getCount()-1);
|
||||||
|
mSlots[slot] = newIter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mSlots[slot] = iter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStore::InventoryStore()
|
MWWorld::InventoryStore::InventoryStore()
|
||||||
|
@ -703,7 +731,7 @@ bool MWWorld::InventoryStore::isEquipped(const MWWorld::Ptr &item)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWWorld::InventoryStore::writeState(ESM::InventoryState &state) const
|
void MWWorld::InventoryStore::writeState(ESM::InventoryState &state)
|
||||||
{
|
{
|
||||||
MWWorld::ContainerStore::writeState(state);
|
MWWorld::ContainerStore::writeState(state);
|
||||||
|
|
||||||
|
|
|
@ -113,11 +113,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void fireEquipmentChangedEvent();
|
void fireEquipmentChangedEvent();
|
||||||
|
|
||||||
virtual int getSlot (const MWWorld::LiveCellRefBase& ref) const;
|
virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const;
|
||||||
///< Return inventory slot that \a ref is in or -1 (if \a ref is not in a slot).
|
virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory);
|
||||||
|
|
||||||
virtual void setSlot (const MWWorld::ContainerStoreIterator& iter, int slot);
|
|
||||||
///< Set slot for \a iter. Ignored if \a iter is an end iterator or if slot==-1.
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -209,7 +206,7 @@ namespace MWWorld
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
///< Empty container.
|
///< Empty container.
|
||||||
|
|
||||||
virtual void writeState (ESM::InventoryState& state) const;
|
virtual void writeState (ESM::InventoryState& state);
|
||||||
|
|
||||||
virtual void readState (const ESM::InventoryState& state);
|
virtual void readState (const ESM::InventoryState& state);
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace MWWorld
|
||||||
cellRef.mRefID = name;
|
cellRef.mRefID = name;
|
||||||
cellRef.mScale = 1;
|
cellRef.mScale = 1;
|
||||||
cellRef.mFactionRank = 0;
|
cellRef.mFactionRank = 0;
|
||||||
cellRef.mCharge = -1;
|
cellRef.mChargeInt = -1;
|
||||||
cellRef.mGoldValue = 1;
|
cellRef.mGoldValue = 1;
|
||||||
cellRef.mEnchantmentCharge = -1;
|
cellRef.mEnchantmentCharge = -1;
|
||||||
cellRef.mTeleport = false;
|
cellRef.mTeleport = false;
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace MWWorld
|
||||||
writer.endRecord (ESM::REC_PLAY);
|
writer.endRecord (ESM::REC_PLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::readRecord (ESM::ESMReader& reader, int32_t type)
|
bool Player::readRecord (ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type==ESM::REC_PLAY)
|
if (type==ESM::REC_PLAY)
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
int getNewCrimeId(); // get new id for witnesses
|
int getNewCrimeId(); // get new id for witnesses
|
||||||
void recordCrimeId(); // record the paid crime id when bounty is 0
|
void recordCrimeId(); // record the paid crime id when bounty is 0
|
||||||
|
|
|
@ -343,7 +343,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectileManager::readRecord(ESM::ESMReader &reader, int32_t type)
|
bool ProjectileManager::readRecord(ESM::ESMReader &reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if (type == ESM::REC_PROJ)
|
if (type == ESM::REC_PROJ)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MWWorld
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
int countSavedGameRecords() const;
|
int countSavedGameRecords() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -762,7 +762,7 @@ void WeatherManager::write(ESM::ESMWriter& writer, Loading::Listener& progress)
|
||||||
writer.endRecord(ESM::REC_WTHR);
|
writer.endRecord(ESM::REC_WTHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
|
bool WeatherManager::readRecord(ESM::ESMReader& reader, uint32_t type)
|
||||||
{
|
{
|
||||||
if(ESM::REC_WTHR == type)
|
if(ESM::REC_WTHR == type)
|
||||||
{
|
{
|
||||||
|
@ -770,14 +770,6 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
|
||||||
ESM::WeatherState state;
|
ESM::WeatherState state;
|
||||||
state.load(reader);
|
state.load(reader);
|
||||||
|
|
||||||
// reset other temporary state, now that we loaded successfully
|
|
||||||
stopSounds(); // let's hope this never throws
|
|
||||||
mRegionOverrides.clear();
|
|
||||||
mRegionMods.clear();
|
|
||||||
mThunderFlash = 0.0;
|
|
||||||
mThunderChance = 0.0;
|
|
||||||
mThunderChanceNeeded = 50.0;
|
|
||||||
|
|
||||||
// swap in the loaded values now that we can't fail
|
// swap in the loaded values now that we can't fail
|
||||||
mHour = state.mHour;
|
mHour = state.mHour;
|
||||||
mWindSpeed = state.mWindSpeed;
|
mWindSpeed = state.mWindSpeed;
|
||||||
|
@ -794,6 +786,16 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WeatherManager::clear()
|
||||||
|
{
|
||||||
|
stopSounds();
|
||||||
|
mRegionOverrides.clear();
|
||||||
|
mRegionMods.clear();
|
||||||
|
mThunderFlash = 0.0;
|
||||||
|
mThunderChance = 0.0;
|
||||||
|
mThunderChanceNeeded = 50.0;
|
||||||
|
}
|
||||||
|
|
||||||
void WeatherManager::switchToNextWeather(bool instantly)
|
void WeatherManager::switchToNextWeather(bool instantly)
|
||||||
{
|
{
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
|
|
@ -199,7 +199,9 @@ namespace MWWorld
|
||||||
|
|
||||||
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||||
|
|
||||||
bool readRecord(ESM::ESMReader& reader, int32_t type);
|
bool readRecord(ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float mHour;
|
float mHour;
|
||||||
|
|
|
@ -265,6 +265,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::clear()
|
void World::clear()
|
||||||
{
|
{
|
||||||
|
mWeatherManager->clear();
|
||||||
mRendering->clear();
|
mRendering->clear();
|
||||||
|
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
|
@ -345,7 +346,7 @@ namespace MWWorld
|
||||||
writer.endRecord(ESM::REC_CAM_);
|
writer.endRecord(ESM::REC_CAM_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::readRecord (ESM::ESMReader& reader, int32_t type,
|
void World::readRecord (ESM::ESMReader& reader, uint32_t type,
|
||||||
const std::map<int, int>& contentFileMap)
|
const std::map<int, int>& contentFileMap)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -2031,7 +2032,7 @@ namespace MWWorld
|
||||||
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
RefData &refdata = ptr.getRefData();
|
RefData &refdata = ptr.getRefData();
|
||||||
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||||
|
|
||||||
if(!physactor)
|
if(!physactor)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2049,7 +2050,7 @@ namespace MWWorld
|
||||||
mPhysEngine);
|
mPhysEngine);
|
||||||
if(tracer.mFraction < 1.0f) // collision, must be close to something below
|
if(tracer.mFraction < 1.0f) // collision, must be close to something below
|
||||||
{
|
{
|
||||||
const_cast<OEngine::Physic::PhysicActor *> (physactor)->setOnGround(true);
|
physactor->setOnGround(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -170,7 +170,7 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type,
|
virtual void readRecord (ESM::ESMReader& reader, uint32_t type,
|
||||||
const std::map<int, int>& contentFileMap);
|
const std::map<int, int>& contentFileMap);
|
||||||
|
|
||||||
virtual CellStore *getExterior (int x, int y);
|
virtual CellStore *getExterior (int x, int y);
|
||||||
|
|
|
@ -215,7 +215,7 @@ namespace Compiler
|
||||||
extensions.registerInstruction ("enablestatsmenu", "", opcodeEnableStatsMenu);
|
extensions.registerInstruction ("enablestatsmenu", "", opcodeEnableStatsMenu);
|
||||||
|
|
||||||
extensions.registerInstruction ("enablerest", "", opcodeEnableRest);
|
extensions.registerInstruction ("enablerest", "", opcodeEnableRest);
|
||||||
extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableRest);
|
extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableLevelupMenu);
|
||||||
|
|
||||||
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu, opcodeShowRestMenuExplicit);
|
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu, opcodeShowRestMenuExplicit);
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,7 @@ namespace Compiler
|
||||||
const int opcodeEnableMapMenu = 0x2000015;
|
const int opcodeEnableMapMenu = 0x2000015;
|
||||||
const int opcodeEnableStatsMenu = 0x2000016;
|
const int opcodeEnableStatsMenu = 0x2000016;
|
||||||
const int opcodeEnableRest = 0x2000017;
|
const int opcodeEnableRest = 0x2000017;
|
||||||
|
const int opcodeEnableLevelupMenu = 0x2000300;
|
||||||
const int opcodeShowRestMenu = 0x2000018;
|
const int opcodeShowRestMenu = 0x2000018;
|
||||||
const int opcodeShowRestMenuExplicit = 0x2000234;
|
const int opcodeShowRestMenuExplicit = 0x2000234;
|
||||||
const int opcodeGetButtonPressed = 0x2000137;
|
const int opcodeGetButtonPressed = 0x2000137;
|
||||||
|
|
|
@ -46,12 +46,12 @@ void ESM::CellRef::loadData(ESMReader &esm)
|
||||||
esm.getHNOT (mFactionRank, "INDX");
|
esm.getHNOT (mFactionRank, "INDX");
|
||||||
|
|
||||||
mGoldValue = 1;
|
mGoldValue = 1;
|
||||||
mCharge = -1;
|
mChargeInt = -1;
|
||||||
mEnchantmentCharge = -1;
|
mEnchantmentCharge = -1;
|
||||||
|
|
||||||
esm.getHNOT (mEnchantmentCharge, "XCHG");
|
esm.getHNOT (mEnchantmentCharge, "XCHG");
|
||||||
|
|
||||||
esm.getHNOT (mCharge, "INTV");
|
esm.getHNOT (mChargeInt, "INTV");
|
||||||
|
|
||||||
esm.getHNOT (mGoldValue, "NAM9");
|
esm.getHNOT (mGoldValue, "NAM9");
|
||||||
|
|
||||||
|
@ -106,8 +106,8 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory) cons
|
||||||
if (mEnchantmentCharge != -1)
|
if (mEnchantmentCharge != -1)
|
||||||
esm.writeHNT("XCHG", mEnchantmentCharge);
|
esm.writeHNT("XCHG", mEnchantmentCharge);
|
||||||
|
|
||||||
if (mCharge != -1)
|
if (mChargeInt != -1)
|
||||||
esm.writeHNT("INTV", mCharge);
|
esm.writeHNT("INTV", mChargeInt);
|
||||||
|
|
||||||
if (mGoldValue != 1) {
|
if (mGoldValue != 1) {
|
||||||
esm.writeHNT("NAM9", mGoldValue);
|
esm.writeHNT("NAM9", mGoldValue);
|
||||||
|
@ -146,7 +146,7 @@ void ESM::CellRef::blank()
|
||||||
mSoul.clear();
|
mSoul.clear();
|
||||||
mFaction.clear();
|
mFaction.clear();
|
||||||
mFactionRank = -2;
|
mFactionRank = -2;
|
||||||
mCharge = -1;
|
mChargeInt = -1;
|
||||||
mEnchantmentCharge = -1;
|
mEnchantmentCharge = -1;
|
||||||
mGoldValue = 0;
|
mGoldValue = 0;
|
||||||
mDestCell.clear();
|
mDestCell.clear();
|
||||||
|
|
|
@ -59,7 +59,11 @@ namespace ESM
|
||||||
|
|
||||||
// For weapon or armor, this is the remaining item health.
|
// For weapon or armor, this is the remaining item health.
|
||||||
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
|
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
|
||||||
int mCharge;
|
union
|
||||||
|
{
|
||||||
|
int mChargeInt;
|
||||||
|
float mChargeFloat;
|
||||||
|
};
|
||||||
|
|
||||||
// Remaining enchantment charge. This could be -1 if the charge was not touched yet (i.e. full).
|
// Remaining enchantment charge. This could be -1 if the charge was not touched yet (i.e. full).
|
||||||
float mEnchantmentCharge;
|
float mEnchantmentCharge;
|
||||||
|
|
|
@ -96,15 +96,17 @@ enum RecNameInts
|
||||||
REC_WEAP = 0x50414557,
|
REC_WEAP = 0x50414557,
|
||||||
|
|
||||||
// format 0 - saved games
|
// format 0 - saved games
|
||||||
REC_SAVE = 0x45564153,
|
REC_SAVE = FourCC<'S','A','V','E'>::value,
|
||||||
REC_JOUR = 0x524f55a4,
|
REC_JOUR_LEGACY = FourCC<0xa4,'U','O','R'>::value, // "\xa4UOR", rather than "JOUR", little oversight when magic numbers were
|
||||||
REC_QUES = 0x53455551,
|
// calculated by hand, needs to be supported for older files now
|
||||||
REC_GSCR = 0x52435347,
|
REC_JOUR = FourCC<'J','O','U','R'>::value,
|
||||||
REC_PLAY = 0x59414c50,
|
REC_QUES = FourCC<'Q','U','E','S'>::value,
|
||||||
REC_CSTA = 0x41545343,
|
REC_GSCR = FourCC<'G','S','C','R'>::value,
|
||||||
REC_GMAP = 0x50414d47,
|
REC_PLAY = FourCC<'P','L','A','Y'>::value,
|
||||||
REC_DIAS = 0x53414944,
|
REC_CSTA = FourCC<'C','S','T','A'>::value,
|
||||||
REC_WTHR = 0x52485457,
|
REC_GMAP = FourCC<'G','M','A','P'>::value,
|
||||||
|
REC_DIAS = FourCC<'D','I','A','S'>::value,
|
||||||
|
REC_WTHR = FourCC<'W','T','H','R'>::value,
|
||||||
REC_KEYS = FourCC<'K','E','Y','S'>::value,
|
REC_KEYS = FourCC<'K','E','Y','S'>::value,
|
||||||
REC_DYNA = FourCC<'D','Y','N','A'>::value,
|
REC_DYNA = FourCC<'D','Y','N','A'>::value,
|
||||||
REC_ASPL = FourCC<'A','S','P','L'>::value,
|
REC_ASPL = FourCC<'A','S','P','L'>::value,
|
||||||
|
@ -117,7 +119,7 @@ enum RecNameInts
|
||||||
REC_CAM_ = FourCC<'C','A','M','_'>::value,
|
REC_CAM_ = FourCC<'C','A','M','_'>::value,
|
||||||
|
|
||||||
// format 1
|
// format 1
|
||||||
REC_FILT = 0x544C4946,
|
REC_FILT = FourCC<'F','I','L','T'>::value,
|
||||||
REC_DBGP = FourCC<'D','B','G','P'>::value ///< only used in project files
|
REC_DBGP = FourCC<'D','B','G','P'>::value ///< only used in project files
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ void ESM::DialogueState::load (ESMReader &esm)
|
||||||
while (esm.isNextSub ("REAC"))
|
while (esm.isNextSub ("REAC"))
|
||||||
{
|
{
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
esm.getSubHeader();
|
esm.getSubName();
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ template <int LEN>
|
||||||
union NAME_T
|
union NAME_T
|
||||||
{
|
{
|
||||||
char name[LEN];
|
char name[LEN];
|
||||||
int32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
bool operator==(const char *str) const
|
bool operator==(const char *str) const
|
||||||
{
|
{
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue