openMW_test_suite compiles and runs

Slowly moving through the open-cs errors

Good progress in openCS

Very good progress on openCS

Getting closer with openCS

OpenCS compiles and runs! Didn't have time to test it all though

ix openMW

everything compiles on windows??

Fix gcc

Fix Clang
iwyu_full
fteppe 2 years ago committed by florent.teppe
parent 2f2e401559
commit 20da0892ef

@ -560,7 +560,7 @@ namespace EsmTool
std::cout << " Name: " << mData.mName << std::endl;
std::cout << " Texture: " << mData.mTexture << std::endl;
std::cout << " Description: " << mData.mDescription << std::endl;
for (const std::string& power : mData.mPowers.mList)
for (const auto& power : mData.mPowers.mList)
std::cout << " Power: " << power << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl;
}
@ -704,7 +704,7 @@ namespace EsmTool
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
<< " Item: " << item.mItem << std::endl;
for (const std::string& spell : mData.mSpells.mList)
for (const auto& spell : mData.mSpells.mList)
std::cout << " Spell: " << spell << std::endl;
printTransport(mData.getTransport());
@ -1102,7 +1102,7 @@ namespace EsmTool
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
<< " Item: " << item.mItem << std::endl;
for (const std::string& spell : mData.mSpells.mList)
for (const auto& spell : mData.mSpells.mList)
std::cout << " Spell: " << spell << std::endl;
printTransport(mData.getTransport());
@ -1187,7 +1187,7 @@ namespace EsmTool
std::cout << " Skill: " << skillLabel(mData.mData.mBonus[i].mSkill) << " ("
<< mData.mData.mBonus[i].mSkill << ") = " << mData.mData.mBonus[i].mBonus << std::endl;
for (const std::string& power : mData.mPowers.mList)
for (const auto& power : mData.mPowers.mList)
std::cout << " Power: " << power << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl;

@ -70,7 +70,7 @@ namespace EsmTool
{
}
std::string getId() const override { return mData.mId; }
std::string getId() const override { return mData.mId.getRefIdString(); }
T& get() { return mData; }

@ -71,7 +71,7 @@ namespace
std::string refId;
splitIndexedRefId(indexedRefId, refIndex, refId);
auto it = context.mActorIdMap.find(std::make_pair(refIndex, refId));
auto it = context.mActorIdMap.find(std::make_pair(refIndex, ESM::RefId::stringRefId(refId)));
if (it == context.mActorIdMap.end())
return -1;
return it->second;
@ -338,13 +338,12 @@ namespace ESSImport
{
// non-indexed RefNum, i.e. no CREC/NPCC/CNTC record associated with it
// this could be any type of object really (even creatures/npcs too)
out.mRefID = cellref.mIndexedRefId;
std::string idLower = Misc::StringUtils::lowerCase(out.mRefID);
out.mRefID = ESM::RefId::stringRefId(cellref.mIndexedRefId);
ESM::ObjectState objstate;
objstate.blank();
objstate.mRef = out;
objstate.mRef.mRefID = idLower;
objstate.mRef.mRefID = out.mRefID;
objstate.mHasCustomState = false;
convertCellRef(cellref, objstate);
esm.writeHNT("OBJE", 0);
@ -354,9 +353,9 @@ namespace ESSImport
else
{
int refIndex = 0;
splitIndexedRefId(cellref.mIndexedRefId, refIndex, out.mRefID);
std::string idLower = Misc::StringUtils::lowerCase(out.mRefID);
std::string outStringId;
splitIndexedRefId(cellref.mIndexedRefId, refIndex, outStringId);
out.mRefID = ESM::RefId::stringRefId(outStringId);
auto npccIt = mContext->mNpcChanges.find(std::make_pair(refIndex, out.mRefID));
if (npccIt != mContext->mNpcChanges.end())
@ -364,7 +363,7 @@ namespace ESSImport
ESM::NpcState objstate;
objstate.blank();
objstate.mRef = out;
objstate.mRef.mRefID = idLower;
objstate.mRef.mRefID = out.mRefID;
// TODO: need more micromanagement here so we don't overwrite values
// from the ESM with default values
if (cellref.mActorData.mHasACDT)
@ -392,7 +391,7 @@ namespace ESSImport
ESM::ContainerState objstate;
objstate.blank();
objstate.mRef = out;
objstate.mRef.mRefID = idLower;
objstate.mRef.mRefID = out.mRefID;
convertCNTC(cntcIt->second, objstate);
convertCellRef(cellref, objstate);
esm.writeHNT("OBJE", ESM::REC_CONT);
@ -406,7 +405,7 @@ namespace ESSImport
ESM::CreatureState objstate;
objstate.blank();
objstate.mRef = out;
objstate.mRef.mRefID = idLower;
objstate.mRef.mRefID = out.mRefID;
// TODO: need more micromanagement here so we don't overwrite values
// from the ESM with default values
if (cellref.mActorData.mHasACDT)
@ -466,7 +465,7 @@ namespace ESSImport
ESM::ProjectileState out;
convertBaseState(out, pnam);
out.mBowId = pnam.mBowId.toString();
out.mBowId = ESM::RefId::stringRefId(pnam.mBowId.toString());
out.mVelocity = pnam.mVelocity;
out.mAttackStrength = pnam.mAttackStrength;
@ -489,7 +488,7 @@ namespace ESSImport
continue;
}
out.mSpellId = it->mSPDT.mId.toString();
out.mSpellId = ESM::RefId::stringRefId(it->mSPDT.mId.toString());
out.mSpeed = pnam.mSpeed * 0.001f; // not sure where this factor comes from
out.mSlot = 0;
@ -502,7 +501,7 @@ namespace ESSImport
void ConvertPROJ::convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam)
{
base.mId = pnam.mArrowId.toString();
base.mId = ESM::RefId::stringRefId(pnam.mArrowId.toString());
base.mPosition = pnam.mPosition;
osg::Quat orient;

@ -45,6 +45,7 @@
#include "convertnpcc.hpp"
#include "convertplayer.hpp"
#include "convertscpt.hpp"
#include <components/esm/refid.hpp>
namespace ESSImport
{
@ -89,7 +90,7 @@ namespace ESSImport
void write(ESM::ESMWriter& esm) override
{
for (typename std::map<std::string, T>::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it)
for (auto it = mRecords.begin(); it != mRecords.end(); ++it)
{
esm.startRecord(T::sRecordId);
it->second.save(esm);
@ -98,7 +99,7 @@ namespace ESSImport
}
protected:
std::map<std::string, T> mRecords;
std::map<ESM::RefId, T> mRecords;
};
class ConvertNPC : public Converter
@ -110,12 +111,12 @@ namespace ESSImport
bool isDeleted = false;
npc.load(esm, isDeleted);
if (npc.mId != "player")
if (npc.mId != ESM::RefId::stringRefId("player"))
{
// Handles 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.
mContext->mNpcs[Misc::StringUtils::lowerCase(npc.mId)] = npc;
mContext->mNpcs[npc.mId] = npc;
}
else
{
@ -146,7 +147,7 @@ namespace ESSImport
bool isDeleted = false;
creature.load(esm, isDeleted);
mContext->mCreatures[Misc::StringUtils::lowerCase(creature.mId)] = creature;
mContext->mCreatures[creature.mId] = creature;
}
};
@ -163,13 +164,13 @@ namespace ESSImport
bool isDeleted = false;
global.load(esm, isDeleted);
if (Misc::StringUtils::ciEqual(global.mId, "gamehour"))
if (global.mId == ESM::RefId::stringRefId("gamehour"))
mContext->mHour = global.mValue.getFloat();
if (Misc::StringUtils::ciEqual(global.mId, "day"))
if (global.mId == ESM::RefId::stringRefId("day"))
mContext->mDay = global.mValue.getInteger();
if (Misc::StringUtils::ciEqual(global.mId, "month"))
if (global.mId == ESM::RefId::stringRefId("month"))
mContext->mMonth = global.mValue.getInteger();
if (Misc::StringUtils::ciEqual(global.mId, "year"))
if (global.mId == ESM::RefId::stringRefId("year"))
mContext->mYear = global.mValue.getInteger();
mRecords[global.mId] = global;
}
@ -184,7 +185,7 @@ namespace ESSImport
bool isDeleted = false;
class_.load(esm, isDeleted);
if (class_.mId == "NEWCLASSID_CHARGEN")
if (class_.mId == ESM::RefId::stringRefId("NEWCLASSID_CHARGEN"))
mContext->mCustomPlayerClassName = class_.mName;
mRecords[class_.mId] = class_;
@ -201,7 +202,7 @@ namespace ESSImport
book.load(esm, isDeleted);
if (book.mData.mSkillId == -1)
mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(Misc::StringUtils::lowerCase(book.mId));
mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(book.mId);
mRecords[book.mId] = book;
}
@ -212,10 +213,10 @@ namespace ESSImport
public:
void read(ESM::ESMReader& esm) override
{
std::string id = esm.getHNString("NAME");
auto id = ESM::RefId::stringRefId(esm.getHNString("NAME"));
NPCC npcc;
npcc.load(esm);
if (id == "PlayerSaveGame")
if (id == ESM::RefId::stringRefId("PlayerSaveGame"))
{
convertNPCC(npcc, mContext->mPlayer.mObject);
}
@ -251,8 +252,7 @@ namespace ESSImport
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))
if (invState.mItems[i].mRef.mRefID == ESM::RefId::stringRefId(refr.mActorData.mSelectedEnchantItem))
invState.mSelectedEnchantItem = i;
}
}
@ -308,7 +308,7 @@ namespace ESSImport
{
void read(ESM::ESMReader& esm) override
{
std::string id = esm.getHNString("NAME");
auto id = ESM::RefId::stringRefId(esm.getHNString("NAME"));
CNTC cntc;
cntc.load(esm);
mContext->mContainerChanges.insert(std::make_pair(std::make_pair(cntc.mIndex, id), cntc));
@ -320,7 +320,7 @@ namespace ESSImport
public:
void read(ESM::ESMReader& esm) override
{
std::string id = esm.getHNString("NAME");
auto id = ESM::RefId::stringRefId(esm.getHNString("NAME"));
CREC crec;
crec.load(esm);
mContext->mCreatureChanges.insert(std::make_pair(std::make_pair(crec.mIndex, id), crec));
@ -395,11 +395,11 @@ namespace ESSImport
bool isDeleted = false;
faction.load(esm, isDeleted);
std::string id = Misc::StringUtils::lowerCase(faction.mId);
const auto& id = faction.mId;
for (auto it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it)
{
std::string faction2 = Misc::StringUtils::lowerCase(it->first);
const auto& faction2 = it->first;
mContext->mDialogueState.mChangedFactionReaction[id].insert(std::make_pair(faction2, it->second));
}
}
@ -433,10 +433,10 @@ namespace ESSImport
ESM::StolenItems items;
for (auto it = mStolenItems.begin(); it != mStolenItems.end(); ++it)
{
std::map<std::pair<std::string, bool>, int> owners;
std::map<std::pair<ESM::RefId, bool>, int> owners;
for (const auto& ownerIt : it->second)
{
owners.insert(std::make_pair(std::make_pair(ownerIt.first, ownerIt.second)
owners.insert(std::make_pair(std::make_pair(ESM::RefId::stringRefId(ownerIt.first), ownerIt.second)
// Since OpenMW doesn't suffer from the owner contamination bug,
// it needs a count argument. But for legacy savegames, we don't know
// this count, so must assume all items of that ID are stolen,
@ -445,7 +445,7 @@ namespace ESSImport
std::numeric_limits<int>::max()));
}
items.mStolenItems.insert(std::make_pair(it->first, owners));
items.mStolenItems.insert(std::make_pair(ESM::RefId::stringRefId(it->first), owners));
}
esm.startRecord(ESM::REC_STLN);
@ -494,7 +494,7 @@ namespace ESSImport
ESM::QuestState state;
state.mFinished = 0;
state.mState = it->second.mIndex;
state.mTopic = Misc::StringUtils::lowerCase(it->first);
state.mTopic = ESM::RefId::stringRefId(it->first);
state.save(esm);
esm.endRecord(ESM::REC_QUES);
}

@ -15,7 +15,7 @@ namespace ESSImport
ESM::ObjectState objstate;
objstate.blank();
objstate.mRef = item;
objstate.mRef.mRefID = Misc::StringUtils::lowerCase(item.mId);
objstate.mRef.mRefID = ESM::RefId::stringRefId(item.mId);
objstate.mCount = std::abs(item.mCount); // restocking items have negative count in the savefile
// openmw handles them differently, so no need to set any flags
state.mItems.push_back(objstate);

@ -8,13 +8,13 @@
namespace ESSImport
{
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics,
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<ESM::RefId>& outDialogueTopics,
bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls)
{
out.mObject.mPosition.rot[0]
= -atan2(pcdt.mPNAM.mVerticalRotation.mData[2][1], pcdt.mPNAM.mVerticalRotation.mData[2][2]);
out.mBirthsign = pcdt.mBirthsign;
out.mBirthsign = ESM::RefId::stringRefId(pcdt.mBirthsign);
out.mObject.mNpcStats.mBounty = pcdt.mBounty;
for (const auto& essFaction : pcdt.mFactions)
{
@ -22,7 +22,7 @@ namespace ESSImport
faction.mExpelled = (essFaction.mFlags & 0x2) != 0;
faction.mRank = essFaction.mRank;
faction.mReputation = essFaction.mReputation;
out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(essFaction.mFactionName.toString())] = faction;
out.mObject.mNpcStats.mFactions[ESM::RefId::stringRefId(essFaction.mFactionName.toString())] = faction;
}
for (int i = 0; i < 3; ++i)
out.mObject.mNpcStats.mSpecIncreases[i] = pcdt.mPNAM.mSpecIncreases[i];
@ -43,7 +43,7 @@ namespace ESSImport
for (const auto& knownDialogueTopic : pcdt.mKnownDialogueTopics)
{
outDialogueTopics.push_back(Misc::StringUtils::lowerCase(knownDialogueTopic));
outDialogueTopics.push_back(ESM::RefId::stringRefId(knownDialogueTopic));
}
controls.mViewSwitchDisabled = pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_ViewSwitchDisabled;

@ -9,7 +9,7 @@
namespace ESSImport
{
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics,
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<ESM::RefId>& outDialogueTopics,
bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls);
}

@ -9,7 +9,7 @@ namespace ESSImport
void convertSCPT(const SCPT& scpt, ESM::GlobalScript& out)
{
out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString());
out.mId = ESM::RefId::stringRefId(scpt.mSCHD.mName.toString());
out.mRunning = scpt.mRunning;
out.mTargetRef.unset(); // TODO: convert target reference of global script
convertSCRI(scpt.mSCRI, out.mLocals);

@ -373,8 +373,8 @@ namespace ESSImport
profile.mInGameTime.mMonth = context.mMonth;
profile.mInGameTime.mYear = context.mYear;
profile.mTimePlayed = 0;
profile.mPlayerCell = header.mGameData.mCurrentCell.toString();
if (context.mPlayerBase.mClass == "NEWCLASSID_CHARGEN")
profile.mPlayerCell = ESM::RefId::stringRefId(header.mGameData.mCurrentCell.toString());
if (context.mPlayerBase.mClass == ESM::RefId::stringRefId("NEWCLASSID_CHARGEN"))
profile.mPlayerClassName = context.mCustomPlayerClassName;
else
profile.mPlayerClassId = context.mPlayerBase.mClass;
@ -397,7 +397,7 @@ namespace ESSImport
}
writer.startRecord(ESM::REC_NPC_);
context.mPlayerBase.mId = "player";
context.mPlayerBase.mId = ESM::RefId::stringRefId("player");
context.mPlayerBase.save(writer);
writer.endRecord(ESM::REC_NPC_);

@ -40,15 +40,15 @@ namespace ESSImport
float mHour;
// key <refIndex, refId>
std::map<std::pair<int, std::string>, CREC> mCreatureChanges;
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
std::map<std::pair<int, ESM::RefId>, CREC> mCreatureChanges;
std::map<std::pair<int, ESM::RefId>, NPCC> mNpcChanges;
std::map<std::pair<int, ESM::RefId>, CNTC> mContainerChanges;
std::map<std::pair<int, std::string>, int> mActorIdMap;
std::map<std::pair<int, ESM::RefId>, int> mActorIdMap;
int mNextActorId;
std::map<std::string, ESM::Creature> mCreatures;
std::map<std::string, ESM::NPC> mNpcs;
std::map<ESM::RefId, ESM::Creature> mCreatures;
std::map<ESM::RefId, ESM::NPC> mNpcs;
std::vector<SPLM::ActiveSpell> mActiveSpells;
@ -70,7 +70,7 @@ namespace ESSImport
mPlayer.mPaidCrimeId = -1;
mPlayer.mObject.blank();
mPlayer.mObject.mEnabled = true;
mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame
mPlayer.mObject.mRef.mRefID = ESM::RefId::stringRefId("player"); // REFR.mRefID would be PlayerSaveGame
mPlayer.mObject.mCreatureStats.mActorId = generateActorId();
mGlobalMapState.mBounds.mMinX = 0;

@ -229,7 +229,7 @@ namespace NavMeshTool
DetourNavigator::RecastGlobalAllocator::init();
DetourNavigator::Settings navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager();
navigatorSettings.mRecast.mSwimHeightScale
= EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat();
= EsmLoader::getGameSetting(esmData.mGameSettings, ESM::RefId::stringRefId("fSwimHeightScale")).getFloat();
WorldspaceData cellsData = gatherWorldspaceData(
navigatorSettings, readers, vfs, bulletShapeManager, esmData, processInteriorCells, writeBinaryLog);

@ -36,7 +36,7 @@
#include <tuple>
#include <utility>
#include <vector>
#include <components/esm/refid.hpp>
namespace NavMeshTool
{
namespace
@ -52,12 +52,12 @@ namespace NavMeshTool
{
ESM::RecNameInts mType;
ESM::RefNum mRefNum;
std::string mRefId;
ESM::RefId mRefId;
float mScale;
ESM::Position mPos;
CellRef(
ESM::RecNameInts type, ESM::RefNum refNum, std::string&& refId, float scale, const ESM::Position& pos)
ESM::RecNameInts type, ESM::RefNum refNum, ESM::RefId&& refId, float scale, const ESM::Position& pos)
: mType(type)
, mRefNum(refNum)
, mRefId(std::move(refId))
@ -67,7 +67,7 @@ namespace NavMeshTool
}
};
ESM::RecNameInts getType(const EsmLoader::EsmData& esmData, std::string_view refId)
ESM::RecNameInts getType(const EsmLoader::EsmData& esmData, const ESM::RefId& refId)
{
const auto it = std::lower_bound(
esmData.mRefIdTypes.begin(), esmData.mRefIdTypes.end(), refId, EsmLoader::LessById{});
@ -89,7 +89,6 @@ namespace NavMeshTool
bool deleted = false;
while (ESM::Cell::getNextRef(*reader, cellRef, deleted))
{
Misc::StringUtils::lowerCaseInPlace(cellRef.mRefID);
const ESM::RecNameInts type = getType(esmData, cellRef.mRefID);
if (type == ESM::RecNameInts{})
continue;

@ -46,7 +46,7 @@ void CSMDoc::Document::addGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::Floats[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Floats[i]);
gmst.mValue.setType(ESM::VT_Float);
gmst.mRecordFlags = 0;
gmst.mValue.setFloat(CSMWorld::DefaultGmsts::FloatsDefaultValues[i]);
@ -56,7 +56,7 @@ void CSMDoc::Document::addGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::Ints[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Ints[i]);
gmst.mValue.setType(ESM::VT_Int);
gmst.mRecordFlags = 0;
gmst.mValue.setInteger(CSMWorld::DefaultGmsts::IntsDefaultValues[i]);
@ -66,7 +66,7 @@ void CSMDoc::Document::addGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::Strings[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Strings[i]);
gmst.mValue.setType(ESM::VT_String);
gmst.mRecordFlags = 0;
gmst.mValue.setString("");
@ -79,7 +79,7 @@ void CSMDoc::Document::addOptionalGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalFloatCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::OptionalFloats[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::OptionalFloats[i]);
gmst.blank();
gmst.mValue.setType(ESM::VT_Float);
addOptionalGmst(gmst);
@ -88,7 +88,7 @@ void CSMDoc::Document::addOptionalGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalIntCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::OptionalInts[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::OptionalInts[i]);
gmst.blank();
gmst.mValue.setType(ESM::VT_Int);
addOptionalGmst(gmst);
@ -97,7 +97,7 @@ void CSMDoc::Document::addOptionalGmsts()
for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalStringCount; ++i)
{
ESM::GameSetting gmst;
gmst.mId = CSMWorld::DefaultGmsts::OptionalStrings[i];
gmst.mId = ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::OptionalStrings[i]);
gmst.blank();
gmst.mValue.setType(ESM::VT_String);
gmst.mValue.setString("<no text>");
@ -117,7 +117,7 @@ void CSMDoc::Document::addOptionalGlobals()
for (int i = 0; sGlobals[i]; ++i)
{
ESM::Global global;
global.mId = sGlobals[i];
global.mId = ESM::RefId::stringRefId(sGlobals[i]);
global.blank();
global.mValue.setType(ESM::VT_Long);
@ -134,7 +134,7 @@ void CSMDoc::Document::addOptionalMagicEffects()
{
ESM::MagicEffect effect;
effect.mIndex = i;
effect.mId = ESM::MagicEffect::indexToId(i);
effect.mId = ESM::RefId::stringRefId(ESM::MagicEffect::indexToId(i));
effect.blank();
addOptionalMagicEffect(effect);
@ -191,7 +191,7 @@ void CSMDoc::Document::createBase()
for (int i = 0; sGlobals[i]; ++i)
{
ESM::Global record;
record.mId = sGlobals[i];
record.mId = ESM::RefId::stringRefId(sGlobals[i]);
record.mRecordFlags = 0;
record.mValue.setType(i == 2 ? ESM::VT_Float : ESM::VT_Long);
@ -207,7 +207,7 @@ void CSMDoc::Document::createBase()
{
ESM::Skill record;
record.mIndex = i;
record.mId = ESM::Skill::indexToId(record.mIndex);
record.mId = ESM::RefId::stringRefId(ESM::Skill::indexToId(record.mIndex));
record.blank();
getData().getSkills().add(record);
@ -228,7 +228,7 @@ void CSMDoc::Document::createBase()
for (int i = 0; sVoice[i]; ++i)
{
ESM::Dialogue record;
record.mId = sVoice[i];
record.mId = ESM::RefId::stringRefId(sVoice[i]);
record.mType = ESM::Dialogue::Voice;
record.blank();
@ -252,7 +252,7 @@ void CSMDoc::Document::createBase()
for (int i = 0; sGreetings[i]; ++i)
{
ESM::Dialogue record;
record.mId = sGreetings[i];
record.mId = ESM::RefId::stringRefId(sGreetings[i]);
record.mType = ESM::Dialogue::Greeting;
record.blank();
@ -276,7 +276,7 @@ void CSMDoc::Document::createBase()
for (int i = 0; sPersuasion[i]; ++i)
{
ESM::Dialogue record;
record.mId = sPersuasion[i];
record.mId = ESM::RefId::stringRefId(sPersuasion[i]);
record.mType = ESM::Dialogue::Persuasion;
record.blank();
@ -288,7 +288,7 @@ void CSMDoc::Document::createBase()
ESM::MagicEffect record;
record.mIndex = i;
record.mId = ESM::MagicEffect::indexToId(i);
record.mId = ESM::RefId::stringRefId(ESM::MagicEffect::indexToId(i));
record.blank();
@ -504,7 +504,7 @@ void CSMDoc::Document::startRunning(const std::string& profile, const std::strin
contentFiles.emplace_back(mContentFile.filename());
}
mRunner.configure(getData().getDebugProfiles().getRecord(profile).get(), contentFiles, startupInstruction);
mRunner.configure(getData().getDebugProfiles().getRecord(ESM::RefId::stringRefId(profile)).get(), contentFiles, startupInstruction);
int state = getState();

@ -145,7 +145,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform(int stage, Messages& messages
// Test, if we need to save anything associated info records.
bool infoModified = false;
CSMWorld::InfoCollection::Range range = mInfos.getTopicRange(topic.get().mId);
CSMWorld::InfoCollection::Range range = mInfos.getTopicRange(topic.get().mId.getRefIdString());
for (CSMWorld::InfoCollection::RecordConstIterator iter(range.first); iter != range.second; ++iter)
{
@ -178,24 +178,26 @@ void CSMDoc::WriteDialogueCollectionStage::perform(int stage, Messages& messages
if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted)
{
ESM::DialInfo info = (*iter)->get();
info.mId = info.mId.substr(info.mId.find_last_of('#') + 1);
std::string infoIdString = info.mId.getRefIdString();
info.mId = ESM::RefId::stringRefId(infoIdString.substr(infoIdString.find_last_of('#') + 1));
info.mPrev.clear();
info.mPrev = ESM::RefId::sEmpty;
if (iter != range.first)
{
CSMWorld::InfoCollection::RecordConstIterator prev = iter;
--prev;
info.mPrev = (*prev)->get().mId.substr((*prev)->get().mId.find_last_of('#') + 1);
std::string prevIdString = (*prev)->get().mId.getRefIdString();
info.mPrev = ESM::RefId::stringRefId(prevIdString.substr(prevIdString.find_last_of('#') + 1));
}
CSMWorld::InfoCollection::RecordConstIterator next = iter;
++next;
info.mNext.clear();
info.mNext = ESM::RefId::sEmpty;
if (next != range.second)
{
info.mNext = (*next)->get().mId.substr((*next)->get().mId.find_last_of('#') + 1);
std::string nextIdString = (*next)->get().mId.getRefIdString();
info.mNext = ESM::RefId::stringRefId(nextIdString.substr(nextIdString.find_last_of('#') + 1));
}
writer.startRecord(info.sRecordId);
@ -251,12 +253,12 @@ void CSMDoc::CollectionReferencesStage::perform(int stage, Messages& messages)
if (record.isModified() || record.mState == CSMWorld::RecordBase::State_Deleted)
{
std::string cellId = record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell;
ESM::RefId cellId = record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell;
std::deque<int>& indices = mState.getSubRecords()[Misc::StringUtils::lowerCase(cellId)];
std::deque<int>& indices = mState.getSubRecords()[cellId.getRefIdString()];
// collect moved references at the end of the container
bool interior = cellId.substr(0, 1) != "#";
bool interior = cellId.getRefIdString().substr(0, 1) != "#";
std::ostringstream stream;
if (!interior)
{
@ -267,7 +269,7 @@ void CSMDoc::CollectionReferencesStage::perform(int stage, Messages& messages)
// An empty mOriginalCell is meant to indicate that it is the same as
// the current cell. It is possible that a moved ref is moved again.
if ((record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell) != stream.str()
if ((record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell) != ESM::RefId::stringRefId(stream.str())
&& !interior && record.mState != CSMWorld::RecordBase::State_ModifiedOnly && !record.get().mNew)
indices.push_back(i);
else
@ -312,13 +314,14 @@ void CSMDoc::WriteCellCollectionStage::writeReferences(
stream << "#" << index.first << " " << index.second;
}
ESM::RefId streamId = ESM::RefId::stringRefId(stream.str());
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0
|| (!interior && ref.mState == CSMWorld::RecordBase::State_ModifiedOnly
&& refRecord.mCell != stream.str()))
&& refRecord.mCell != streamId))
{
refRecord.mRefNum.mIndex = newRefNum++;
}
else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != stream.str()
else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != streamId
&& !interior)
{
// An empty mOriginalCell is meant to indicate that it is the same as
@ -353,13 +356,13 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
std::deque<int> persistentRefs;
std::map<std::string, std::deque<int>>::const_iterator references
= mState.getSubRecords().find(Misc::StringUtils::lowerCase(cell.get().mId));
= mState.getSubRecords().find(cell.get().mId.getRefIdString());
if (cell.isModified() || cell.mState == CSMWorld::RecordBase::State_Deleted
|| references != mState.getSubRecords().end())
{
CSMWorld::Cell cellRecord = cell.get();
bool interior = cellRecord.mId.substr(0, 1) != "#";
bool interior = cellRecord.mId.getRefIdString().substr(0, 1) != "#";
// count new references and adjust RefNumCount accordingsly
unsigned int newRefNum = cellRecord.mRefNumCounter;
@ -387,7 +390,7 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
if (refRecord.mNew
|| (!interior && ref.mState == CSMWorld::RecordBase::State_ModifiedOnly &&
/// \todo consider worldspace
CSMWorld::CellCoordinates(refRecord.getCellIndex()).getId("") != refRecord.mCell))
ESM::RefId::stringRefId(CSMWorld::CellCoordinates( refRecord.getCellIndex()).getId("")) != refRecord.mCell))
++cellRecord.mRefNumCounter;
if (refRecord.mRefNum.mIndex >= newRefNum)
@ -404,7 +407,7 @@ void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages)
{
cellRecord.mData.mFlags &= ~ESM::Cell::Interior;
std::istringstream stream(cellRecord.mId.c_str());
std::istringstream stream(cellRecord.mId.getRefIdString().c_str());
char ignore;
stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY;
}
@ -442,10 +445,10 @@ void CSMDoc::WritePathgridCollectionStage::perform(int stage, Messages& messages
if (pathgrid.isModified() || pathgrid.mState == CSMWorld::RecordBase::State_Deleted)
{
CSMWorld::Pathgrid record = pathgrid.get();
if (record.mId.substr(0, 1) == "#")
std::string recordIdString = record.mId.getRefIdString();
if (recordIdString.substr(0, 1) == "#")
{
std::istringstream stream(record.mId.c_str());
std::istringstream stream(recordIdString.c_str());
char ignore;
stream >> ignore >> record.mData.mX >> record.mData.mY;
}

@ -97,7 +97,7 @@ namespace CSMDoc
template <class CollectionT>
void WriteCollectionStage<CollectionT>::perform(int stage, Messages& messages)
{
if (CSMWorld::getScopeFromId(mCollection.getRecord(stage).get().mId) != mScope)
if (CSMWorld::getScopeFromId(mCollection.getRecord(stage).get().mId.getRefIdString()) != mScope)
return;
ESM::ESMWriter& writer = mState.getWriter();

@ -61,6 +61,6 @@ void CSMTools::BodyPartCheckStage::perform(int stage, CSMDoc::Messages& messages
if (bodyPart.mRace.empty())
messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error);
else if (mRaces.searchId(bodyPart.mRace) == -1)
messages.add(id, "Race '" + bodyPart.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Race '" + bodyPart.mRace.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
}
}

@ -40,18 +40,18 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
const ESM::GameSetting& gmst = record.get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Gmst, gmst.mId);
std::string gmstIdString = gmst.mId.getRefIdString();
// Test for empty string
if (gmst.mValue.getType() == ESM::VT_String && gmst.mValue.getString().empty())
messages.add(id, gmst.mId + " is an empty string", "", CSMDoc::Message::Severity_Warning);
messages.add(id, gmstIdString + " is an empty string", "", CSMDoc::Message::Severity_Warning);
// Checking type and limits
// optimization - compare it to lists based on naming convention (f-float,i-int,s-string)
if (gmst.mId[0] == 'f')
if (gmstIdString[0] == 'f')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Floats[i])
if (gmst.mId == ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Floats[i]))
{
if (gmst.mValue.getType() != ESM::VT_Float)
{
@ -64,21 +64,21 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
if (gmst.mValue.getFloat() < CSMWorld::DefaultGmsts::FloatLimits[i * 2])
messages.add(
id, gmst.mId + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning);
id, gmstIdString + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning);
if (gmst.mValue.getFloat() > CSMWorld::DefaultGmsts::FloatLimits[i * 2 + 1])
messages.add(
id, gmst.mId + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning);
id, gmstIdString + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning);
break; // for loop
}
}
}
else if (gmst.mId[0] == 'i')
else if (gmstIdString[0] == 'i')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Ints[i])
if (gmst.mId == ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Ints[i]))
{
if (gmst.mValue.getType() != ESM::VT_Int)
{
@ -91,28 +91,28 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages)
if (gmst.mValue.getInteger() < CSMWorld::DefaultGmsts::IntLimits[i * 2])
messages.add(
id, gmst.mId + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning);
id, gmstIdString + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning);
if (gmst.mValue.getInteger() > CSMWorld::DefaultGmsts::IntLimits[i * 2 + 1])
messages.add(
id, gmst.mId + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning);
id, gmstIdString + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning);
break; // for loop
}
}
}
else if (gmst.mId[0] == 's')
else if (gmstIdString[0] == 's')
{
for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i)
{
if (gmst.mId == CSMWorld::DefaultGmsts::Strings[i])
if (gmst.mId == ESM::RefId::stringRefId(CSMWorld::DefaultGmsts::Strings[i]))
{
ESM::VarType type = gmst.mValue.getType();
if (type != ESM::VT_String && type != ESM::VT_None)
{
std::ostringstream stream;
stream << "Expected string or none type for " << gmst.mId << " but found "
stream << "Expected string or none type for " << gmstIdString << " but found "
<< varTypeToString(gmst.mValue.getType()) << " type";
messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error);

@ -50,7 +50,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages)
int totalInfoCount = 0;
std::set<int> questIndices;
CSMWorld::InfoCollection::Range range = mJournalInfos.getTopicRange(journal.mId);
CSMWorld::InfoCollection::Range range = mJournalInfos.getTopicRange(journal.mId.getRefIdString());
for (CSMWorld::InfoCollection::RecordConstIterator it = range.first; it != range.second; ++it)
{

@ -20,13 +20,13 @@ namespace ESM
}
std::string CSMTools::MagicEffectCheckStage::checkObject(
const std::string& id, const CSMWorld::UniversalId& type, const std::string& column) const
const ESM::RefId& id, const CSMWorld::UniversalId& type, const std::string& column) const
{
CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id);
if (index.first == -1)
return (column + " '" + id + "' does not exist");
return (column + " '" + id.getRefIdString() + "' does not exist");
else if (index.second != type.getType())
return (column + " '" + id + "' does not have " + type.getTypeName() + " type");
return (column + " '" + id.getRefIdString() + "' does not have " + type.getTypeName() + " type");
return std::string();
}
@ -125,11 +125,11 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages& messa
if (!effect.mCastSound.empty() && mSounds.searchId(effect.mCastSound) == -1)
messages.add(
id, "Casting sound '" + effect.mCastSound + "' does not exist", "", CSMDoc::Message::Severity_Error);
id, "Casting sound '" + effect.mCastSound.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (!effect.mHitSound.empty() && mSounds.searchId(effect.mHitSound) == -1)
messages.add(id, "Hit sound '" + effect.mHitSound + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Hit sound '" + effect.mHitSound.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (!effect.mAreaSound.empty() && mSounds.searchId(effect.mAreaSound) == -1)
messages.add(id, "Area sound '" + effect.mAreaSound + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Area sound '" + effect.mAreaSound.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (!effect.mBoltSound.empty() && mSounds.searchId(effect.mBoltSound) == -1)
messages.add(id, "Bolt sound '" + effect.mBoltSound + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Bolt sound '" + effect.mBoltSound.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
}

@ -42,7 +42,7 @@ namespace CSMTools
private:
std::string checkObject(
const std::string& id, const CSMWorld::UniversalId& type, const std::string& column) const;
const ESM::RefId& id, const CSMWorld::UniversalId& type, const std::string& column) const;
public:
MagicEffectCheckStage(const CSMWorld::IdCollection<ESM::MagicEffect>& effects,

@ -10,7 +10,7 @@
#include <apps/opencs/model/world/universalid.hpp>
CSMTools::MandatoryIdStage::MandatoryIdStage(const CSMWorld::CollectionBase& idCollection,
const CSMWorld::UniversalId& collectionId, const std::vector<std::string>& ids)
const CSMWorld::UniversalId& collectionId, const std::vector<ESM::RefId>& ids)
: mIdCollection(idCollection)
, mCollectionId(collectionId)
, mIds(ids)
@ -25,5 +25,5 @@ int CSMTools::MandatoryIdStage::setup()
void CSMTools::MandatoryIdStage::perform(int stage, CSMDoc::Messages& messages)
{
if (mIdCollection.searchId(mIds.at(stage)) == -1 || mIdCollection.getRecord(mIds.at(stage)).isDeleted())
messages.add(mCollectionId, "Missing mandatory record: " + mIds.at(stage));
messages.add(mCollectionId, "Missing mandatory record: " + mIds.at(stage).getRefIdString());
}

@ -5,7 +5,7 @@
#include <vector>
#include "../world/universalid.hpp"
#include <components/esm/refid.hpp>
#include "../doc/stage.hpp"
namespace CSMDoc
@ -25,11 +25,11 @@ namespace CSMTools
{
const CSMWorld::CollectionBase& mIdCollection;
CSMWorld::UniversalId mCollectionId;
std::vector<std::string> mIds;
std::vector<ESM::RefId> mIds;
public:
MandatoryIdStage(const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId,
const std::vector<std::string>& ids);
const std::vector<ESM::RefId>& ids);
int setup() override;
///< \return number of steps

@ -68,7 +68,7 @@ void CSMTools::FinishMergedDocumentStage::perform(int stage, CSMDoc::Messages& m
reader.open(path);
CSMWorld::MetaData source;
source.mId = "sys::meta";
source.mId = ESM::RefId::stringRefId("sys::meta");
source.load(reader);
CSMWorld::MetaData target = mState.mTarget->getData().getMetaData();
@ -117,7 +117,7 @@ void CSMTools::MergeReferencesStage::perform(int stage, CSMDoc::Messages& messag
ref.mOriginalCell = ref.mCell;
ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase(ref.mCell)]++;
ref.mRefNum.mIndex = mIndex[ref.mCell.getRefIdString()]++;
ref.mRefNum.mContentFile = 0;
ref.mNew = false;
@ -190,7 +190,7 @@ void CSMTools::FixLandsAndLandTexturesMergeStage::perform(int stage, CSMDoc::Mes
CSMWorld::IdTable& ltexTable = dynamic_cast<CSMWorld::IdTable&>(
*mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures));
std::string id = mState.mTarget->getData().getLand().getId(stage);
std::string id = mState.mTarget->getData().getLand().getId(stage).getRefIdString();
CSMWorld::TouchLandCommand cmd(landTable, ltexTable, id);
cmd.redo();

@ -520,9 +520,9 @@ void CSMTools::ReferenceableCheckStage::creatureCheck(
CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(creature.mOriginal);
if (index.first == -1)
messages.add(
id, "Parent creature '" + creature.mOriginal + "' does not exist", "", CSMDoc::Message::Severity_Error);
id, "Parent creature '" + creature.mOriginal.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
else if (index.second != CSMWorld::UniversalId::Type_Creature)
messages.add(id, "'" + creature.mOriginal + "' is not a creature", "", CSMDoc::Message::Severity_Error);
messages.add(id, "'" + creature.mOriginal.getRefIdString() + "' is not a creature", "", CSMDoc::Message::Severity_Error);
}
// Check inventory
@ -681,7 +681,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck(
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, npc.mId);
// Detect if player is present
if (Misc::StringUtils::ciEqual(npc.mId, "player")) // Happy now, scrawl?
if (npc.mId == ESM::RefId::stringRefId("player")) // Happy now, scrawl?
mPlayerPresent = true;
// Skip "Base" records (setting!)
@ -738,23 +738,23 @@ void CSMTools::ReferenceableCheckStage::npcCheck(
if (npc.mClass.empty())
messages.add(id, "Class is missing", "", CSMDoc::Message::Severity_Error);
else if (mClasses.searchId(npc.mClass) == -1)
messages.add(id, "Class '" + npc.mClass + "' does not exist", "", CSMDoc::Message::Severity_Error);
else if (mClasses.searchId(npc.mClass.getRefIdString()) == -1)
messages.add(id, "Class '" + npc.mClass.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (npc.mRace.empty())
messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error);
else if (mRaces.searchId(npc.mRace) == -1)
messages.add(id, "Race '" + npc.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error);
else if (mRaces.searchId(npc.mRace.getRefIdString()) == -1)
messages.add(id, "Race '" + npc.mRace.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (!npc.mFaction.empty() && mFactions.searchId(npc.mFaction) == -1)
messages.add(id, "Faction '" + npc.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (!npc.mFaction.empty() && mFactions.searchId(npc.mFaction.getRefIdString()) == -1)
messages.add(id, "Faction '" + npc.mFaction.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (npc.mHead.empty())
messages.add(id, "Head is missing", "", CSMDoc::Message::Severity_Error);
else
{
if (mBodyParts.searchId(npc.mHead) == -1)
messages.add(id, "Head body part '" + npc.mHead + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (mBodyParts.searchId(npc.mHead.getRefIdString()) == -1)
messages.add(id, "Head body part '" + npc.mHead.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
/// \todo Check gender, race and other body parts stuff validity for the specific NPC
}
@ -762,8 +762,8 @@ void CSMTools::ReferenceableCheckStage::npcCheck(
messages.add(id, "Hair is missing", "", CSMDoc::Message::Severity_Error);
else
{
if (mBodyParts.searchId(npc.mHair) == -1)
messages.add(id, "Hair body part '" + npc.mHair + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (mBodyParts.searchId(npc.mHair.getRefIdString()) == -1)
messages.add(id, "Hair body part '" + npc.mHair.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
/// \todo Check gender, race and other body part stuff validity for the specific NPC
}
@ -784,22 +784,22 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
return;
const ESM::Weapon& weapon = (dynamic_cast<const CSMWorld::Record<ESM::Weapon>&>(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, weapon.mId);
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, weapon.mId);
// TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present
if ( // THOSE ARE HARDCODED!
!(weapon.mId == "VFX_Hands" || weapon.mId == "VFX_Absorb" || weapon.mId == "VFX_Reflect"
|| weapon.mId == "VFX_DefaultBolt" ||
!(weapon.mId == ESM::RefId::stringRefId("VFX_Hands") || weapon.mId == ESM::RefId::stringRefId("VFX_Absorb") || weapon.mId == ESM::RefId::stringRefId("VFX_Reflect")
|| weapon.mId == ESM::RefId::stringRefId("VFX_DefaultBolt") ||
// TODO I don't know how to get full list of effects :/
// DANGER!, ACHTUNG! FIXME! The following is the list of the magical bolts, valid for Morrowind.esm. However
// those are not hardcoded.
weapon.mId == "magic_bolt" || weapon.mId == "shock_bolt" || weapon.mId == "shield_bolt"
|| weapon.mId == "VFX_DestructBolt" || weapon.mId == "VFX_PoisonBolt" || weapon.mId == "VFX_RestoreBolt"
|| weapon.mId == "VFX_AlterationBolt" || weapon.mId == "VFX_ConjureBolt" || weapon.mId == "VFX_FrostBolt"
|| weapon.mId == "VFX_MysticismBolt" || weapon.mId == "VFX_IllusionBolt" || weapon.mId == "VFX_Multiple2"
|| weapon.mId == "VFX_Multiple3" || weapon.mId == "VFX_Multiple4" || weapon.mId == "VFX_Multiple5"
|| weapon.mId == "VFX_Multiple6" || weapon.mId == "VFX_Multiple7" || weapon.mId == "VFX_Multiple8"
|| weapon.mId == "VFX_Multiple9"))
weapon.mId == ESM::RefId::stringRefId("magic_bolt") || weapon.mId == ESM::RefId::stringRefId("shock_bolt") || weapon.mId == ESM::RefId::stringRefId("shield_bolt")
|| weapon.mId == ESM::RefId::stringRefId("VFX_DestructBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_PoisonBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_RestoreBolt")
|| weapon.mId == ESM::RefId::stringRefId("VFX_AlterationBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_ConjureBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_FrostBolt")
|| weapon.mId == ESM::RefId::stringRefId("VFX_MysticismBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_IllusionBolt") || weapon.mId == ESM::RefId::stringRefId("VFX_Multiple2")
|| weapon.mId == ESM::RefId::stringRefId("VFX_Multiple3") || weapon.mId == ESM::RefId::stringRefId("VFX_Multiple4") || weapon.mId == ESM::RefId::stringRefId("VFX_Multiple5")
|| weapon.mId == ESM::RefId::stringRefId("VFX_Multiple6") || weapon.mId == ESM::RefId::stringRefId("VFX_Multiple7") || weapon.mId == ESM::RefId::stringRefId("VFX_Multiple8")
|| weapon.mId == ESM::RefId::stringRefId("VFX_Multiple9")))
{
inventoryItemCheck<ESM::Weapon>(weapon, messages, id.toString(), true);
@ -903,8 +903,9 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck(
{
for (size_t i = 0; i < itemList.size(); ++i)
{
std::string itemName = itemList[i].mItem;
CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName);
ESM::RefId item = itemList[i].mItem;
auto itemName = item.getRefIdString();
CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(item);
if (localIndex.first == -1)
messages.add(id, "Item '" + itemName + "' does not exist", "", CSMDoc::Message::Severity_Error);
@ -1036,10 +1037,10 @@ void CSMTools::ReferenceableCheckStage::listCheck(
{
if (mReferencables.searchId(someList.mList[i].mId).first == -1)
messages.add(
someID, "Object '" + someList.mList[i].mId + "' does not exist", "", CSMDoc::Message::Severity_Error);
someID, "Object '" + someList.mList[i].mId.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (someList.mList[i].mLevel < 1)
messages.add(someID, "Level of item '" + someList.mList[i].mId + "' is non-positive", "",
messages.add(someID, "Level of item '" + someList.mList[i].mId.getRefIdString() + "' is non-positive", "",
CSMDoc::Message::Severity_Error);
}
}
@ -1052,6 +1053,6 @@ void CSMTools::ReferenceableCheckStage::scriptCheck(
{
if (mScripts.searchId(someTool.mScript) == -1)
messages.add(
someID, "Script '" + someTool.mScript + "' does not exist", "", CSMDoc::Message::Severity_Error);
someID, "Script '" + someTool.mScript.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
}
}

@ -51,7 +51,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& message
// Check for non existing referenced object
if (mObjects.searchId(cellRef.mRefID) == -1)
messages.add(
id, "Instance of a non-existent object '" + cellRef.mRefID + "'", "", CSMDoc::Message::Severity_Error);
id, "Instance of a non-existent object '" + cellRef.mRefID.getRefIdString() + "'", "", CSMDoc::Message::Severity_Error);
else
{
// Check if reference charge is valid for it's proper referenced type
@ -64,13 +64,13 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& message
// If object have owner, check if that owner reference is valid
if (!cellRef.mOwner.empty() && mObjects.searchId(cellRef.mOwner) == -1)
messages.add(id, "Owner object '" + cellRef.mOwner + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Owner object '" + cellRef.mOwner.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
// If object have creature soul trapped, check if that creature reference is valid
if (!cellRef.mSoul.empty())
if (mObjects.searchId(cellRef.mSoul) == -1)
messages.add(
id, "Trapped soul object '" + cellRef.mSoul + "' does not exist", "", CSMDoc::Message::Severity_Error);
id, "Trapped soul object '" + cellRef.mSoul.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
if (cellRef.mFaction.empty())
{
@ -80,7 +80,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& message
else
{
if (mFactions.searchId(cellRef.mFaction) == -1)
messages.add(id, "Faction '" + cellRef.mFaction + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Faction '" + cellRef.mFaction.getRefIdString() + "' does not exist", "", CSMDoc::Message::Severity_Error);
else if (cellRef.mFactionRank < -1)
messages.add(id, "Invalid faction rank", "", CSMDoc::Message::Severity_Error);
}

@ -56,7 +56,7 @@ void CSMTools::RegionCheckStage::perform(int stage, CSMDoc::Messages& messages)
for (const ESM::Region::SoundRef& sound : region.mSoundList)
{
if (sound.mChance > 100)
messages.add(id, "Chance of '" + sound.mSound + "' sound to play is over 100 percent", "",
messages.add(id, "Chance of '" + sound.mSound.getRefIdString() + "' sound to play is over 100 percent", "",
CSMDoc::Message::Severity_Warning);
}

@ -92,7 +92,7 @@ int CSMTools::ScriptCheckStage::setup()
mContext.clear();
mMessages = nullptr;
mId.clear();
mId = ESM::RefId::sEmpty;
Compiler::ErrorHandler::reset();
mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue();
@ -130,7 +130,7 @@ void CSMTools::ScriptCheckStage::perform(int stage, CSMDoc::Messages& messages)
try
{
mFile = record.get().mId;
mFile = record.get().mId.getRefIdString();
std::istringstream input(record.get().mScriptText);
Compiler::Scanner scanner(*this, input, mContext.getExtensions());

@ -37,7 +37,7 @@ namespace CSMTools
const CSMDoc::Document& mDocument;
Compiler::Extensions mExtensions;
CSMWorld::ScriptContext mContext;
std::string mId;
ESM::RefId mId;
std::string mFile;
CSMDoc::Messages* mMessages;
WarningMode mWarningMode;

@ -50,11 +50,11 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages& messages
if (creatureIndex.first == -1)
{
messages.add(
id, "Creature '" + soundGen.mCreature + "' doesn't exist", "", CSMDoc::Message::Severity_Error);
id, "Creature '" + soundGen.mCreature.getRefIdString() + "' doesn't exist", "", CSMDoc::Message::Severity_Error);
}
else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature)
{
messages.add(id, "'" + soundGen.mCreature + "' is not a creature", "", CSMDoc::Message::Severity_Error);
messages.add(id, "'" + soundGen.mCreature.getRefIdString() + "' is not a creature", "", CSMDoc::Message::Severity_Error);
}
}
@ -64,6 +64,6 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages& messages
}
else if (mSounds.searchId(soundGen.mSound) == -1)
{
messages.add(id, "Sound '" + soundGen.mSound + "' doesn't exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Sound '" + soundGen.mSound.getRefIdString() + "' doesn't exist", "", CSMDoc::Message::Severity_Error);
}
}

@ -35,12 +35,12 @@ void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messa
if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted())
return;
std::string scriptId = record.get().mId;
auto scriptId = record.get().mId;
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_StartScript, scriptId);
if (mScripts.searchId(Misc::StringUtils::lowerCase(scriptId)) == -1)
messages.add(id, "Start script " + scriptId + " does not exist", "", CSMDoc::Message::Severity_Error);
if (mScripts.searchId(scriptId) == -1)
messages.add(id, "Start script " + scriptId.getRefIdString() + " does not exist", "", CSMDoc::Message::Severity_Error);
}
int CSMTools::StartScriptCheckStage::setup()

@ -79,8 +79,12 @@ CSMDoc::OperationHolder* CSMTools::Tools::getVerifier()
std::vector<std::string> mandatoryIds{ "Day", "DaysPassed", "GameHour", "Month", "PCRace" };
std::vector<ESM::RefId> mandatoryRefIds;
for (auto& id : mandatoryIds)
mandatoryRefIds.push_back(ESM::RefId::stringRefId(id));
mVerifierOperation->appendStage(new MandatoryIdStage(
mData.getGlobals(), CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Globals), mandatoryIds));
mData.getGlobals(), CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Globals), mandatoryRefIds));
mVerifierOperation->appendStage(new SkillCheckStage(mData.getSkills()));

@ -181,18 +181,19 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message
// Verification functions
bool CSMTools::TopicInfoCheckStage::verifyActor(
const std::string& actor, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
const ESM::RefId& actor, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{
std::string actorString = actor.getRefIdString();
CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(actor);
if (index.first == -1)
{
messages.add(id, "Actor '" + actor + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Actor '" + actorString + "' does not exist", "", CSMDoc::Message::Severity_Error);
return false;
}
else if (mReferencables.getRecord(index).isDeleted())
{
messages.add(id, "Deleted actor '" + actor + "' is being referenced", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Deleted actor '" + actorString + "' is being referenced", "", CSMDoc::Message::Severity_Error);
return false;
}
else if (index.second != CSMWorld::UniversalId::Type_Npc && index.second != CSMWorld::UniversalId::Type_Creature)
@ -209,11 +210,12 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(
}
bool CSMTools::TopicInfoCheckStage::verifyCell(
const std::string& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
const ESM::RefId& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{
if (mCellNames.find(cell) == mCellNames.end())
std::string cellName = cell.getRefIdString();
if (mCellNames.find(cellName) == mCellNames.end())
{
messages.add(id, "Cell '" + cell + "' does not exist", "", CSMDoc::Message::Severity_Error);
messages.add(id, "Cell '" + cellName + "' does not exist", "", CSMDoc::Message::Severity_Error);
return false;
}
@ -221,7 +223,7 @@ bool CSMTools::TopicInfoCheckStage::verifyCell(
}
bool CSMTools::TopicInfoCheckStage::verifyFactionRank(
const std::string& factionName, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
const ESM::RefId& factionName, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{
if (rank < -1)
{
@ -256,18 +258,19 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(
}
bool CSMTools::TopicInfoCheckStage::verifyItem(
const std::string& item, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
const ESM::RefId& item, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{
std::string idString = item.getRefIdString();
CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(item);
if (index.first == -1)
{
messages.add(id, ("Item '" + item + "' does not exist"), "", CSMDoc::Message::Severity_Error);
messages.add(id, ("Item '" + idString + "' does not exist"), "", CSMDoc::Message::Severity_Error);
return false;
}
else if (mReferencables.getRecord(index).isDeleted())
{
messages.add(id, ("Deleted item '" + item + "' is being referenced"), "", CSMDoc::Message::Severity_Error);
messages.add(id, ("Deleted item '" + idString + "' is being referenced"), "", CSMDoc::Message::Severity_Error);
return false;
}
else
@ -363,47 +366,47 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(
// Id checks
if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Global
&& !verifyId(infoCondition.getVariableName(), mGlobals, id, messages))
&& !verifyId(ESM::RefId::stringRefId(infoCondition.getVariableName()), mGlobals, id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Journal
&& !verifyId(infoCondition.getVariableName(), mJournals, id, messages))
&& !verifyId(ESM::RefId::stringRefId(infoCondition.getVariableName()), mJournals, id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Item
&& !verifyItem(infoCondition.getVariableName(), id, messages))
&& !verifyItem(ESM::RefId::stringRefId(infoCondition.getVariableName()), id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Dead
&& !verifyActor(infoCondition.getVariableName(), id, messages))
&& !verifyActor(ESM::RefId::stringRefId(infoCondition.getVariableName()), id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotId
&& !verifyActor(infoCondition.getVariableName(), id, messages))
&& !verifyActor(ESM::RefId::stringRefId(infoCondition.getVariableName()), id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotFaction
&& !verifyId(infoCondition.getVariableName(), mFactions, id, messages))
&& !verifyId(ESM::RefId::stringRefId(infoCondition.getVariableName()), mFactions, id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotClass
&& !verifyId(infoCondition.getVariableName(), mClasses, id, messages))
&& !verifyId(ESM::RefId::stringRefId(infoCondition.getVariableName()), mClasses, id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotRace
&& !verifyId(infoCondition.getVariableName(), mRaces, id, messages))
&& !verifyId(ESM::RefId::stringRefId(infoCondition.getVariableName()), mRaces, id, messages))
{
return false;
}
else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotCell
&& !verifyCell(infoCondition.getVariableName(), id, messages))
&& !verifyCell(ESM::RefId::stringRefId(infoCondition.getVariableName()), id, messages))
{
return false;
}
@ -424,20 +427,20 @@ bool CSMTools::TopicInfoCheckStage::verifySound(
}
template <typename T>
bool CSMTools::TopicInfoCheckStage::verifyId(const std::string& name, const CSMWorld::IdCollection<T>& collection,
bool CSMTools::TopicInfoCheckStage::verifyId(const ESM::RefId& name, const CSMWorld::IdCollection<T>& collection,
const CSMWorld::UniversalId& id, CSMDoc::Messages& messages)
{
int index = collection.searchId(name);
if (index == -1)
{
messages.add(id, std::string(T::getRecordType()) + " '" + name + "' does not exist", "",
messages.add(id, std::string(T::getRecordType()) + " '" + name.getRefIdString() + "' does not exist", "",
CSMDoc::Message::Severity_Error);
return false;
}
else if (collection.getRecord(index).isDeleted())
{
messages.add(id, "Deleted " + std::string(T::getRecordType()) + " record '" + name + "' is being referenced",
messages.add(id, "Deleted " + std::string(T::getRecordType()) + " record '" + name.getRefIdString() + "' is being referenced",
"", CSMDoc::Message::Severity_Error);
return false;
}

@ -77,17 +77,17 @@ namespace CSMTools
bool mIgnoreBaseRecords;
// These return false when not successful and write an error
bool verifyActor(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyCell(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyActor(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyCell(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyFactionRank(
const std::string& name, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyItem(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
const ESM::RefId& name, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifyItem(const ESM::RefId& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifySelectStruct(
const ESM::DialInfo::SelectStruct& select, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
bool verifySound(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
template <typename T>
bool verifyId(const std::string& name, const CSMWorld::IdCollection<T>& collection,
bool verifyId(const ESM::RefId& name, const CSMWorld::IdCollection<T>& collection,
const CSMWorld::UniversalId& id, CSMDoc::Messages& messages);
};
}

@ -26,7 +26,7 @@
namespace CSMWorld
{
const std::string& ActorAdapter::RaceData::getId() const
const ESM::RefId& ActorAdapter::RaceData::getId() const
{
return mId;
}
@ -56,47 +56,47 @@ namespace CSMWorld
}
}
const std::string& ActorAdapter::RaceData::getFemalePart(ESM::PartReferenceType index) const
const ESM::RefId& ActorAdapter::RaceData::getFemalePart(ESM::PartReferenceType index) const
{
return mFemaleParts[ESM::getMeshPart(index)];
}
const std::string& ActorAdapter::RaceData::getMalePart(ESM::PartReferenceType index) const
const ESM::RefId& ActorAdapter::RaceData::getMalePart(ESM::PartReferenceType index) const
{
return mMaleParts[ESM::getMeshPart(index)];
}
bool ActorAdapter::RaceData::hasDependency(const std::string& id) const
bool ActorAdapter::RaceData::hasDependency(const ESM::RefId& id) const
{
return mDependencies.find(id) != mDependencies.end();
}
void ActorAdapter::RaceData::setFemalePart(ESM::BodyPart::MeshPart index, const std::string& partId)
void ActorAdapter::RaceData::setFemalePart(ESM::BodyPart::MeshPart index, const ESM::RefId& partId)
{
mFemaleParts[index] = partId;
addOtherDependency(partId);
}
void ActorAdapter::RaceData::setMalePart(ESM::BodyPart::MeshPart index, const std::string& partId)
void ActorAdapter::RaceData::setMalePart(ESM::BodyPart::MeshPart index, const ESM::RefId& partId)
{
mMaleParts[index] = partId;
addOtherDependency(partId);
}
void ActorAdapter::RaceData::addOtherDependency(const std::string& id)
void ActorAdapter::RaceData::addOtherDependency(const ESM::RefId& id)
{
if (!id.empty())
mDependencies.emplace(id);
}
void ActorAdapter::RaceData::reset_data(const std::string& id, bool isBeast)
void ActorAdapter::RaceData::reset_data(const ESM::RefId& id, bool isBeast)
{
mId = id;
mIsBeast = isBeast;
for (auto& str : mFemaleParts)
str.clear();
str = ESM::RefId::sEmpty;
for (auto& str : mMaleParts)
str.clear();
str = ESM::RefId::sEmpty;
mDependencies.clear();
// Mark self as a dependency
@ -109,7 +109,7 @@ namespace CSMWorld
mFemale = false;
}
const std::string& ActorAdapter::ActorData::getId() const
const ESM::RefId& ActorAdapter::ActorData::getId() const
{
return mId;
}
@ -146,12 +146,12 @@ namespace CSMWorld
if (mFemale)
{
// Note: we should use male parts for females as fallback
const std::string& femalePart = mRaceData->getFemalePart(index);
const std::string& femalePart = mRaceData->getFemalePart(index).getRefIdString();
if (!femalePart.empty())
return femalePart;
}
return mRaceData->getMalePart(index);
return mRaceData->getMalePart(index).getRefIdString();
}
return {};
@ -160,12 +160,12 @@ namespace CSMWorld
return it->second.first;
}
bool ActorAdapter::ActorData::hasDependency(const std::string& id) const
bool ActorAdapter::ActorData::hasDependency(const ESM::RefId& id) const
{
return mDependencies.find(id) != mDependencies.end();
}
void ActorAdapter::ActorData::setPart(ESM::PartReferenceType index, const std::string& partId, int priority)
void ActorAdapter::ActorData::setPart(ESM::PartReferenceType index, const ESM::RefId& partId, int priority)
{
auto it = mParts.find(index);
if (it != mParts.end())
@ -174,18 +174,18 @@ namespace CSMWorld
return;
}
mParts[index] = std::make_pair(partId, priority);
mParts[index] = std::make_pair(partId.getRefIdString(), priority);
addOtherDependency(partId);
}
void ActorAdapter::ActorData::addOtherDependency(const std::string& id)
void ActorAdapter::ActorData::addOtherDependency(const ESM::RefId& id)
{
if (!id.empty())
mDependencies.emplace(id);
}
void ActorAdapter::ActorData::reset_data(
const std::string& id, const std::string& skeleton, bool isCreature, bool isFemale, RaceDataPtr raceData)
const ESM::RefId& id, const std::string& skeleton, bool isCreature, bool isFemale, RaceDataPtr raceData)
{
mId = id;
mCreature = isCreature;
@ -225,7 +225,7 @@ namespace CSMWorld
partModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ActorAdapter::handleBodyPartsAboutToBeRemoved);
}
ActorAdapter::ActorDataPtr ActorAdapter::getActorData(const std::string& id)
ActorAdapter::ActorDataPtr ActorAdapter::getActorData(const ESM::RefId& id)
{
// Return cached actor data if it exists
ActorDataPtr data = mCachedActors.get(id);
@ -248,7 +248,7 @@ namespace CSMWorld
{
for (int row = start; row <= end; ++row)
{
std::string refId = mReferenceables.getId(row);
auto refId = mReferenceables.getId(row);
markDirtyDependency(refId);
}
}
@ -269,7 +269,7 @@ namespace CSMWorld
// Handle each record
for (int row = start; row <= end; ++row)
{
std::string refId = mReferenceables.getId(row);
auto refId = mReferenceables.getId(row);
markDirtyDependency(refId);
}
@ -284,7 +284,7 @@ namespace CSMWorld
{
for (int row = start; row <= end; ++row)
{
std::string refId = mReferenceables.getId(row);
auto refId = mReferenceables.getId(row);
markDirtyDependency(refId);
}
}
@ -303,7 +303,7 @@ namespace CSMWorld
{
for (int row = start; row <= end; ++row)
{
std::string raceId = mReferenceables.getId(row);
auto raceId = mReferenceables.getId(row);
markDirtyDependency(raceId);
}
}
@ -323,7 +323,7 @@ namespace CSMWorld
for (int row = start; row <= end; ++row)
{
std::string raceId = mRaces.getId(row);
auto raceId = mRaces.getId(row);
markDirtyDependency(raceId);
}
@ -338,7 +338,7 @@ namespace CSMWorld
{
for (int row = start; row <= end; ++row)
{
std::string raceId = mRaces.getId(row);
auto raceId = mRaces.getId(row);
markDirtyDependency(raceId);
}
}
@ -364,7 +364,7 @@ namespace CSMWorld
markDirtyDependency(record.get().mRace);
}
std::string partId = mBodyParts.getId(row);
auto partId = mBodyParts.getId(row);
markDirtyDependency(partId);
}
}
@ -392,7 +392,7 @@ namespace CSMWorld
}
// Update entries with a tracked dependency
std::string partId = mBodyParts.getId(row);
auto partId = mBodyParts.getId(row);
markDirtyDependency(partId);
}
@ -407,7 +407,7 @@ namespace CSMWorld
{
for (int row = start; row <= end; ++row)
{
std::string partId = mBodyParts.getId(row);
auto partId = mBodyParts.getId(row);
markDirtyDependency(partId);
}
}
@ -431,7 +431,7 @@ namespace CSMWorld
return name.size() >= 4 && name.find(".1st", name.size() - 4) != std::string::npos;
}
ActorAdapter::RaceDataPtr ActorAdapter::getRaceData(const std::string& id)
ActorAdapter::RaceDataPtr ActorAdapter::getRaceData(const ESM::RefId& id)
{
// Return cached race data if it exists
RaceDataPtr data = mCachedRaces.get(id);
@ -445,7 +445,7 @@ namespace CSMWorld
return data;
}
void ActorAdapter::setupActor(const std::string& id, ActorDataPtr data)
void ActorAdapter::setupActor(const ESM::RefId& id, ActorDataPtr data)
{
int index = mReferenceables.searchId(id);
if (index == -1)
@ -487,7 +487,7 @@ namespace CSMWorld
}
}
void ActorAdapter::setupRace(const std::string& id, RaceDataPtr data)
void ActorAdapter::setupRace(const ESM::RefId& id, RaceDataPtr data)
{
int index = mRaces.searchId(id);
if (index == -1)
@ -511,7 +511,7 @@ namespace CSMWorld
// Setup body parts
for (int i = 0; i < mBodyParts.getSize(); ++i)
{
std::string partId = mBodyParts.getId(i);
auto partId = mBodyParts.getId(i);
auto& partRecord = mBodyParts.getRecord(i);
if (partRecord.isDeleted())
@ -521,7 +521,7 @@ namespace CSMWorld
}
auto& part = partRecord.get();
if (part.mRace == id && part.mData.mType == ESM::BodyPart::MT_Skin && !is1stPersonPart(part.mId))
if (part.mRace == id && part.mData.mType == ESM::BodyPart::MT_Skin && !is1stPersonPart(part.mId.getRefIdString()))
{
auto type = (ESM::BodyPart::MeshPart)part.mData.mPart;
bool female = part.mData.mFlags & ESM::BodyPart::BPF_Female;
@ -533,7 +533,7 @@ namespace CSMWorld
}
}
void ActorAdapter::setupNpc(const std::string& id, ActorDataPtr data)
void ActorAdapter::setupNpc(const ESM::RefId& id, ActorDataPtr data)
{
// Common setup, record is known to exist and is not deleted
int index = mReferenceables.searchId(id);
@ -551,12 +551,12 @@ namespace CSMWorld
{
if (item.mCount <= 0)
continue;
std::string itemId = item.mItem;
auto itemId = item.mItem;
addNpcItem(itemId, data);
}
}
void ActorAdapter::addNpcItem(const std::string& itemId, ActorDataPtr data)
void ActorAdapter::addNpcItem(const ESM::RefId& itemId, ActorDataPtr data)
{
int index = mReferenceables.searchId(itemId);
if (index == -1)
@ -578,7 +578,7 @@ namespace CSMWorld
auto addParts = [&](const std::vector<ESM::PartReference>& list, int priority) {
for (auto& part : list)
{
std::string partId;
ESM::RefId partId;
auto partType = (ESM::PartReferenceType)part.mPart;
if (data->isFemale())
@ -590,7 +590,7 @@ namespace CSMWorld
// An another vanilla quirk: hide hairs if an item replaces Head part
if (partType == ESM::PRT_Head)
data->setPart(ESM::PRT_Hair, "", priority);
data->setPart(ESM::PRT_Hair, ESM::RefId::sEmpty, priority);
}
};
@ -637,7 +637,7 @@ namespace CSMWorld
}
}
void ActorAdapter::setupCreature(const std::string& id, ActorDataPtr data)
void ActorAdapter::setupCreature(const ESM::RefId& id, ActorDataPtr data)
{
// Record is known to exist and is not deleted
int index = mReferenceables.searchId(id);
@ -646,7 +646,7 @@ namespace CSMWorld
data->reset_data(id, creature.mModel, true);
}
void ActorAdapter::markDirtyDependency(const std::string& dep)
void ActorAdapter::markDirtyDependency(const ESM::RefId& dep)
{
for (auto raceIt : mCachedRaces)
{

@ -37,9 +37,9 @@ namespace CSMWorld
/// A list indexed by ESM::PartReferenceType
using ActorPartList = std::map<ESM::PartReferenceType, std::pair<std::string, int>>;
/// A list indexed by ESM::BodyPart::MeshPart
using RacePartList = std::array<std::string, ESM::BodyPart::MP_Count>;
using RacePartList = std::array<ESM::RefId, ESM::BodyPart::MP_Count>;
/// Tracks unique strings
using StringSet = std::unordered_set<std::string>;
using RefIdSet = std::unordered_set<ESM::RefId>;
/// Contains base race data shared between actors
class RaceData
@ -48,34 +48,34 @@ namespace CSMWorld
RaceData();
/// Retrieves the id of the race represented
const std::string& getId() const;
const ESM::RefId& getId() const;
/// Checks if it's a beast race
bool isBeast() const;
/// Checks if a part could exist for the given type
bool handlesPart(ESM::PartReferenceType type) const;
/// Retrieves the associated body part
const std::string& getFemalePart(ESM::PartReferenceType index) const;
const ESM::RefId& getFemalePart(ESM::PartReferenceType index) const;
/// Retrieves the associated body part
const std::string& getMalePart(ESM::PartReferenceType index) const;
const ESM::RefId& getMalePart(ESM::PartReferenceType index) const;
/// Checks if the race has a data dependency
bool hasDependency(const std::string& id) const;
bool hasDependency(const ESM::RefId& id) const;
/// Sets the associated part if it's empty and marks a dependency
void setFemalePart(ESM::BodyPart::MeshPart partIndex, const std::string& partId);
void setFemalePart(ESM::BodyPart::MeshPart partIndex, const ESM::RefId& partId);
/// Sets the associated part if it's empty and marks a dependency
void setMalePart(ESM::BodyPart::MeshPart partIndex, const std::string& partId);
void setMalePart(ESM::BodyPart::MeshPart partIndex, const ESM::RefId& partId);
/// Marks an additional dependency
void addOtherDependency(const std::string& id);
void addOtherDependency(const ESM::RefId& id);
/// Clears parts and dependencies
void reset_data(const std::string& raceId, bool isBeast = false);
void reset_data(const ESM::RefId& raceId, bool isBeast = false);
private:
bool handles(ESM::PartReferenceType type) const;
std::string mId;
ESM::RefId mId;
bool mIsBeast;
RacePartList mFemaleParts;
RacePartList mMaleParts;
StringSet mDependencies;
RefIdSet mDependencies;
};
using RaceDataPtr = std::shared_ptr<RaceData>;
@ -87,7 +87,7 @@ namespace CSMWorld
ActorData();
/// Retrieves the id of the actor represented
const std::string& getId() const;
const ESM::RefId& getId() const;
/// Checks if the actor is a creature
bool isCreature() const;
/// Checks if the actor is female
@ -97,35 +97,35 @@ namespace CSMWorld
/// Retrieves the associated actor part
std::string_view getPart(ESM::PartReferenceType index) const;
/// Checks if the actor has a data dependency
bool hasDependency(const std::string& id) const;
bool hasDependency(const ESM::RefId& id) const;
/// Sets the actor part used and marks a dependency
void setPart(ESM::PartReferenceType partIndex, const std::string& partId, int priority);
void setPart(ESM::PartReferenceType partIndex, const ESM::RefId& partId, int priority);
/// Marks an additional dependency for the actor
void addOtherDependency(const std::string& id);
void addOtherDependency(const ESM::RefId& id);
/// Clears race, parts, and dependencies
void reset_data(const std::string& actorId, const std::string& skeleton = "", bool isCreature = false,
void reset_data(const ESM::RefId& actorId, const std::string& skeleton = "", bool isCreature = false,
bool female = true, RaceDataPtr raceData = nullptr);
private:
std::string mId;
ESM::RefId mId;
bool mCreature;
bool mFemale;
std::string mSkeletonOverride;
RaceDataPtr mRaceData;
ActorPartList mParts;
StringSet mDependencies;
RefIdSet mDependencies;
};
using ActorDataPtr = std::shared_ptr<ActorData>;
ActorAdapter(Data& data);
/// Obtains the shared data for a given actor
ActorDataPtr getActorData(const std::string& refId);
ActorDataPtr getActorData(const ESM::RefId& refId);
signals:
void actorChanged(const std::string& refId);
void actorChanged(const ESM::RefId& refId);
public slots:
@ -151,28 +151,28 @@ namespace CSMWorld
QModelIndex getHighestIndex(QModelIndex) const;
bool is1stPersonPart(const std::string& id) const;
RaceDataPtr getRaceData(const std::string& raceId);
RaceDataPtr getRaceData(const ESM::RefId& raceId);
void setupActor(const std::string& id, ActorDataPtr data);
void setupRace(const std::string& id, RaceDataPtr data);
void setupActor(const ESM::RefId& id, ActorDataPtr data);
void setupRace(const ESM::RefId& id, RaceDataPtr data);
void setupNpc(const std::string& id, ActorDataPtr data);
void addNpcItem(const std::string& itemId, ActorDataPtr data);
void setupNpc(const ESM::RefId& id, ActorDataPtr data);
void addNpcItem(const ESM::RefId& itemId, ActorDataPtr data);
void setupCreature(const std::string& id, ActorDataPtr data);
void setupCreature(const ESM::RefId& id, ActorDataPtr data);
void markDirtyDependency(const std::string& dependency);
void markDirtyDependency(const ESM::RefId& dependency);
void updateDirty();
RefIdCollection& mReferenceables;
IdCollection<ESM::Race>& mRaces;
IdCollection<ESM::BodyPart>& mBodyParts;
Misc::WeakCache<std::string, ActorData> mCachedActors; // Key: referenceable id
Misc::WeakCache<std::string, RaceData> mCachedRaces; // Key: race id
Misc::WeakCache<ESM::RefId, ActorData> mCachedActors; // Key: referenceable id
Misc::WeakCache<ESM::RefId, RaceData> mCachedRaces; // Key: race id
StringSet mDirtyActors; // Actors that need updating
StringSet mDirtyRaces; // Races that need updating
RefIdSet mDirtyActors; // Actors that need updating
RefIdSet mDirtyRaces; // Races that need updating
};
}

@ -6,11 +6,11 @@ void CSMWorld::Cell::load(ESM::ESMReader& esm, bool& isDeleted)
{
ESM::Cell::load(esm, isDeleted, false);
mId = mName;
mId = ESM::RefId::stringRefId(mName);
if (isExterior())
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str();
mId = ESM::RefId::stringRefId(stream.str());
}
}

@ -18,7 +18,7 @@ namespace CSMWorld
/// Exterior cell coordinates are encoded in the cell ID.
struct Cell : public ESM::Cell
{
std::string mId;
ESM::RefId mId;
void load(ESM::ESMReader& esm, bool& isDeleted);
};

@ -28,53 +28,53 @@ namespace CSMWorld
template <typename ESXRecordT>
struct IdAccessor
{
void setId(ESXRecordT& record, const std::string& id) const;
const std::string getId(const ESXRecordT& record) const;
void setId(ESXRecordT& record, const ESM::RefId& id) const;
const ESM::RefId getId(const ESXRecordT& record) const;
};
template <typename ESXRecordT>
void IdAccessor<ESXRecordT>::setId(ESXRecordT& record, const std::string& id) const
void IdAccessor<ESXRecordT>::setId(ESXRecordT& record, const ESM::RefId& id) const
{
record.mId = id;
}
template <typename ESXRecordT>
const std::string IdAccessor<ESXRecordT>::getId(const ESXRecordT& record) const
const ESM::RefId IdAccessor<ESXRecordT>::getId(const ESXRecordT& record) const
{
return record.mId;
}
template <>
inline void IdAccessor<Land>::setId(Land& record, const std::string& id) const
inline void IdAccessor<Land>::setId(Land& record, const ESM::RefId& id) const
{
int x = 0, y = 0;
Land::parseUniqueRecordId(id, x, y);
Land::parseUniqueRecordId(id.getRefIdString(), x, y);
record.mX = x;
record.mY = y;
}
template <>
inline void IdAccessor<LandTexture>::setId(LandTexture& record, const std::string& id) const
inline void IdAccessor<LandTexture>::setId(LandTexture& record, const ESM::RefId& id) const
{
int plugin = 0;
int index = 0;
LandTexture::parseUniqueRecordId(id, plugin, index);
LandTexture::parseUniqueRecordId(id.getRefIdString(), plugin, index);
record.mPluginIndex = plugin;
record.mIndex = index;
}
template <>
inline const std::string IdAccessor<Land>::getId(const Land& record) const
inline const ESM::RefId IdAccessor<Land>::getId(const Land& record) const
{
return Land::createUniqueRecordId(record.mX, record.mY);
return ESM::RefId::stringRefId( Land::createUniqueRecordId(record.mX, record.mY));
}
template <>
inline const std::string IdAccessor<LandTexture>::getId(const LandTexture& record) const
inline const ESM::RefId IdAccessor<LandTexture>::getId(const LandTexture& record) const
{
return LandTexture::createUniqueRecordId(record.mPluginIndex, record.mIndex);
return ESM::RefId::stringRefId(LandTexture::createUniqueRecordId(record.mPluginIndex, record.mIndex));
}
/// \brief Single-type record collection
@ -118,9 +118,9 @@ namespace CSMWorld
int getSize() const override;
std::string getId(int index) const override;
ESM::RefId getId(int index) const override;
int getIndex(const std::string& id) const override;
int getIndex(const ESM::RefId& id) const override;
int getColumns() const override;
@ -138,13 +138,13 @@ namespace CSMWorld
void removeRows(int index, int count) override;
void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) override;
void appendBlankRecord(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None) override;
///< \param type Will be ignored, unless the collection supports multiple record types
void cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type) override;
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) override;
bool touchRecord(const std::string& id) override;
bool touchRecord(const ESM::RefId& id) override;
///< Change the state of a record from base to modified, if it is not already.
/// \return True if the record was changed.
@ -152,6 +152,10 @@ namespace CSMWorld
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
int searchId(const ESM::RefId& id) const override;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
void replace(int index, std::unique_ptr<RecordBase> record) override;
///< If the record type does not match, an exception is thrown.
///
@ -161,14 +165,14 @@ namespace CSMWorld
///< If the record type does not match, an exception is thrown.
///< \param type Will be ignored, unless the collection supports multiple record types
const Record<ESXRecordT>& getRecord(const std::string& id) const override;
const Record<ESXRecordT>& getRecord(const ESM::RefId& id) const override;
const Record<ESXRecordT>& getRecord(int index) const override;
int getAppendIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None) const override;
int getAppendIndex(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None) const override;
///< \param type Will be ignored, unless the collection supports multiple record types
std::vector<std::string> getIds(bool listDeleted = true) const override;
std::vector<ESM::RefId> getIds(bool listDeleted = true) const override;
///< Return a sorted collection of all IDs
///
/// \param listDeleted include deleted record in the list
@ -241,18 +245,18 @@ namespace CSMWorld
const std::string& origin, const std::string& destination, UniversalId::Type type)
{
auto copy = std::make_unique<Record<ESXRecordT>>();
copy->mModified = getRecord(origin).get();
copy->mModified = getRecord(ESM::RefId::stringRefId(origin)).get();
copy->mState = RecordBase::State_ModifiedOnly;
IdAccessorT().setId(copy->get(), destination);
IdAccessorT().setId(copy->get(), ESM::RefId::stringRefId(destination));
if (type == UniversalId::Type_Reference)
{
CSMWorld::CellRef* ptr = (CSMWorld::CellRef*)&copy->mModified;
ptr->mRefNum.mIndex = 0;
}
int index = getAppendIndex(destination, type);
insertRecord(std::move(copy), getAppendIndex(destination, type));
ESM::RefId destinationRefId = ESM::RefId::stringRefId(destination);
int index = getAppendIndex(destinationRefId, type);
insertRecord(std::move(copy), getAppendIndex(destinationRefId, type));
return index;
}
@ -260,7 +264,7 @@ namespace CSMWorld
template <typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::touchRecordImp(const std::string& id)
{
int index = getIndex(id);
int index = getIndex(ESM::RefId::stringRefId(id));
Record<ESXRecordT>& record = *mRecords.at(index);
if (record.isDeleted())
{
@ -278,29 +282,29 @@ namespace CSMWorld
template <typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type)
{
cloneRecordImp(origin, destination, type);
cloneRecordImp(origin.getRefIdString(), destination.getRefIdString(), type);
}
template <>
inline void Collection<Land, IdAccessor<Land>>::cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type)
{
int index = cloneRecordImp(origin, destination, type);
int index = cloneRecordImp(origin.getRefIdString(), destination.getRefIdString(), type);
mRecords.at(index)->get().setPlugin(0);
}
template <typename ESXRecordT, typename IdAccessorT>
bool Collection<ESXRecordT, IdAccessorT>::touchRecord(const std::string& id)
bool Collection<ESXRecordT, IdAccessorT>::touchRecord(const ESM::RefId& id)
{
return touchRecordImp(id) != -1;
return touchRecordImp(id.getRefIdString()) != -1;
}
template <>
inline bool Collection<Land, IdAccessor<Land>>::touchRecord(const std::string& id)
inline bool Collection<Land, IdAccessor<Land>>::touchRecord(const ESM::RefId& id)
{
int index = touchRecordImp(id);
int index = touchRecordImp(id.getRefIdString());
if (index >= 0)
{
mRecords.at(index)->get().setPlugin(0);
@ -325,9 +329,9 @@ namespace CSMWorld
template <typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::add(const ESXRecordT& record)
{
std::string id = Misc::StringUtils::lowerCase(IdAccessorT().getId(record));
auto id = IdAccessorT().getId(record);
std::map<std::string, int>::iterator iter = mIndex.find(id);
auto iter = mIndex.find(id.getRefIdString());
if (iter == mIndex.end())
{
@ -350,18 +354,18 @@ namespace CSMWorld
}
template <typename ESXRecordT, typename IdAccessorT>
std::string Collection<ESXRecordT, IdAccessorT>::getId(int index) const
ESM::RefId Collection<ESXRecordT, IdAccessorT>::getId(int index) const
{
return IdAccessorT().getId(mRecords.at(index)->get());
}
template <typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::getIndex(const std::string& id) const
int Collection<ESXRecordT, IdAccessorT>::getIndex(const ESM::RefId& id) const
{
int index = searchId(id);
if (index == -1)
throw std::runtime_error("invalid ID: " + id);
throw std::runtime_error("invalid ID: " + id.getRefIdString());
return index;
}
@ -456,7 +460,7 @@ namespace CSMWorld
}
template <typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::appendBlankRecord(const std::string& id, UniversalId::Type type)
void Collection<ESXRecordT, IdAccessorT>::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type)
{
ESXRecordT record;
IdAccessorT().setId(record, id);
@ -482,6 +486,18 @@ namespace CSMWorld
return iter->second;
}
template <typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::searchId(const ESM::RefId& id) const
{
std::map<std::string, int>::const_iterator iter = mIndex.find(id.getRefIdString());
if (iter == mIndex.end())
return -1;
return iter->second;
}
template <typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::replace(int index, std::unique_ptr<RecordBase> record)
{
@ -497,17 +513,17 @@ namespace CSMWorld
}
template <typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::getAppendIndex(const std::string& id, UniversalId::Type type) const
int Collection<ESXRecordT, IdAccessorT>::getAppendIndex(const ESM::RefId& id, UniversalId::Type type) const
{
return static_cast<int>(mRecords.size());
}
template <typename ESXRecordT, typename IdAccessorT>
std::vector<std::string> Collection<ESXRecordT, IdAccessorT>::getIds(bool listDeleted) const
std::vector<ESM::RefId> Collection<ESXRecordT, IdAccessorT>::getIds(bool listDeleted) const
{
std::vector<std::string> ids;
std::vector<ESM::RefId> ids;
for (typename std::map<std::string, int>::const_iterator iter = mIndex.begin(); iter != mIndex.end(); ++iter)
for (auto iter = mIndex.begin(); iter != mIndex.end(); ++iter)
{
if (listDeleted || !mRecords[iter->second]->isDeleted())
ids.push_back(IdAccessorT().getId(mRecords[iter->second]->get()));
@ -517,7 +533,7 @@ namespace CSMWorld
}
template <typename ESXRecordT, typename IdAccessorT>
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord(const std::string& id) const
const Record<ESXRecordT>& Collection<ESXRecordT, IdAccessorT>::getRecord(const ESM::RefId& id) const
{
int index = getIndex(id);
return *mRecords.at(index);
@ -538,7 +554,7 @@ namespace CSMWorld
throw std::runtime_error("index out of range");
std::unique_ptr<Record<ESXRecordT>> record2(static_cast<Record<ESXRecordT>*>(record.release()));
std::string lowerId = Misc::StringUtils::lowerCase(IdAccessorT().getId(record2->get()));
std::string id =IdAccessorT().getId(record2->get()).getRefIdString();
if (index == size)
mRecords.push_back(std::move(record2));
@ -554,14 +570,14 @@ namespace CSMWorld
}
}
mIndex.insert(std::make_pair(lowerId, index));
mIndex.insert(std::make_pair(id, index));
}
template <typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::setRecord(int index, std::unique_ptr<Record<ESXRecordT>> record)
{
if (Misc::StringUtils::lowerCase(IdAccessorT().getId(mRecords.at(index)->get()))
!= Misc::StringUtils::lowerCase(IdAccessorT().getId(record->get())))
if (IdAccessorT().getId(mRecords.at(index)->get())
!= IdAccessorT().getId(record->get()))
throw std::runtime_error("attempt to change the ID of a record");
mRecords.at(index) = std::move(record);

@ -13,7 +13,7 @@ CSMWorld::CollectionBase::~CollectionBase() {}
int CSMWorld::CollectionBase::getInsertIndex(const std::string& id, UniversalId::Type type, RecordBase* record) const
{
return getAppendIndex(id, type);
return getAppendIndex(ESM::RefId::stringRefId(id), type);
}
int CSMWorld::CollectionBase::searchColumnIndex(Columns::ColumnId id) const

@ -11,6 +11,11 @@
class QVariant;
namespace ESM
{
struct RefId;
}
namespace CSMWorld
{
struct ColumnBase;
@ -35,9 +40,9 @@ namespace CSMWorld
virtual int getSize() const = 0;
virtual std::string getId(int index) const = 0;
virtual ESM::RefId getId(int index) const = 0;
virtual int getIndex(const std::string& id) const = 0;
virtual int getIndex(const ESM::RefId& id) const = 0;
virtual int getColumns() const = 0;
@ -57,13 +62,17 @@ namespace CSMWorld
virtual void removeRows(int index, int count) = 0;
virtual void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) = 0;
virtual void appendBlankRecord(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None) = 0;
///< \param type Will be ignored, unless the collection supports multiple record types
virtual int searchId(std::string_view id) const = 0;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual int searchId(const ESM::RefId& id) const = 0;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace(int index, std::unique_ptr<RecordBase> record) = 0;
///< If the record type does not match, an exception is thrown.
///
@ -75,19 +84,19 @@ namespace CSMWorld
///< If the record type does not match, an exception is thrown.
virtual void cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type)
= 0;
virtual bool touchRecord(const std::string& id) = 0;
virtual bool touchRecord(const ESM::RefId& id) = 0;
virtual const RecordBase& getRecord(const std::string& id) const = 0;
virtual const RecordBase& getRecord(const ESM::RefId& id) const = 0;
virtual const RecordBase& getRecord(int index) const = 0;
virtual int getAppendIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None) const = 0;
virtual int getAppendIndex(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None) const = 0;
///< \param type Will be ignored, unless the collection supports multiple record types
virtual std::vector<std::string> getIds(bool listDeleted = true) const = 0;
virtual std::vector<ESM::RefId> getIds(bool listDeleted = true) const = 0;
///< Return a sorted collection of all IDs
///
/// \param listDeleted include deleted record in the list

@ -20,13 +20,13 @@ namespace CSMWorld
QVariant LandTextureNicknameColumn::get(const Record<LandTexture>& record) const
{
return QString::fromUtf8(record.get().mId.c_str());
return QString::fromUtf8(record.get().mId.getRefIdString().c_str());
}
void LandTextureNicknameColumn::set(Record<LandTexture>& record, const QVariant& data)
{
LandTexture copy = record.get();
copy.mId = data.toString().toUtf8().constData();
copy.mId = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(copy);
}
@ -281,7 +281,7 @@ namespace CSMWorld
{
if (mMeshType != nullptr && mMeshType->get(record) == ESM::BodyPart::MT_Skin)
{
return QString::fromUtf8(record.get().mRace.c_str());
return QString::fromUtf8(record.get().mRace.getRefIdString().c_str());
}
return QVariant(QVariant::UserType);
}
@ -290,7 +290,7 @@ namespace CSMWorld
{
ESM::BodyPart record2 = record.get();
record2.mRace = data.toString().toUtf8().constData();
record2.mRace = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}

@ -61,7 +61,7 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mId.c_str());
return QString::fromUtf8(record.get().mId.getRefIdString().c_str());
}
bool isEditable() const override { return false; }
@ -690,14 +690,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mSleepList.c_str());
return QString::fromUtf8(record.get().mSleepList.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mSleepList = data.toString().toUtf8().constData();
record2.mSleepList = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -816,14 +816,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mRegion.c_str());
return QString::fromUtf8(record.get().mRegion.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mRegion = data.toString().toUtf8().constData();
record2.mRegion = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -845,14 +845,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mCell.c_str());
return QString::fromUtf8(record.get().mCell.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mCell = data.toString().toUtf8().constData();
record2.mCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -872,14 +872,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mOriginalCell.c_str());
return QString::fromUtf8(record.get().mOriginalCell.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mOriginalCell = data.toString().toUtf8().constData();
record2.mOriginalCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -899,14 +899,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mRefID.c_str());
return QString::fromUtf8(record.get().mRefID.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mRefID = data.toString().toUtf8().constData();
record2.mRefID = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -944,14 +944,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mOwner.c_str());
return QString::fromUtf8(record.get().mOwner.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mOwner = data.toString().toUtf8().constData();
record2.mOwner = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -969,14 +969,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mSoul.c_str());
return QString::fromUtf8(record.get().mSoul.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mSoul = data.toString().toUtf8().constData();
record2.mSoul = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -994,14 +994,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mFaction.c_str());
return QString::fromUtf8(record.get().mFaction.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mFaction = data.toString().toUtf8().constData();
record2.mFaction = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1168,14 +1168,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mKey.c_str());
return QString::fromUtf8(record.get().mKey.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mKey = data.toString().toUtf8().constData();
record2.mKey = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1193,14 +1193,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mTrap.c_str());
return QString::fromUtf8(record.get().mTrap.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mTrap = data.toString().toUtf8().constData();
record2.mTrap = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1407,14 +1407,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mTopicId.c_str());
return QString::fromUtf8(record.get().mTopicId.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mTopicId = data.toString().toUtf8().constData();
record2.mTopicId = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1434,14 +1434,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mActor.c_str());
return QString::fromUtf8(record.get().mActor.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mActor = data.toString().toUtf8().constData();
record2.mActor = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1459,14 +1459,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mRace.c_str());
return QString::fromUtf8(record.get().mRace.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mRace = data.toString().toUtf8().constData();
record2.mRace = ESM::RefId::stringRefId( data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1484,14 +1484,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mClass.c_str());
return QString::fromUtf8(record.get().mClass.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mClass = data.toString().toUtf8().constData();
record2.mClass = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1509,14 +1509,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mPcFaction.c_str());
return QString::fromUtf8(record.get().mPcFaction.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mPcFaction = data.toString().toUtf8().constData();
record2.mPcFaction = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1926,14 +1926,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mSound.c_str());
return QString::fromUtf8(record.get().mSound.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mSound = data.toString().toUtf8().constData();
record2.mSound = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -1951,14 +1951,14 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
return QString::fromUtf8(record.get().mCreature.c_str());
return QString::fromUtf8(record.get().mCreature.getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mCreature = data.toString().toUtf8().constData();
record2.mCreature = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -2072,7 +2072,7 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
const std::string* string = nullptr;
const ESM::RefId* string = nullptr;
switch (this->mColumnId)
{
@ -2093,12 +2093,12 @@ namespace CSMWorld
if (!string)
throw std::logic_error("Unsupported column ID");
return QString::fromUtf8(string->c_str());
return QString::fromUtf8(string->getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
std::string* string = nullptr;
ESM::RefId* string = nullptr;
ESXRecordT record2 = record.get();
@ -2121,7 +2121,7 @@ namespace CSMWorld
if (!string)
throw std::logic_error("Unsupported column ID");
*string = data.toString().toUtf8().constData();
*string = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}
@ -2141,7 +2141,7 @@ namespace CSMWorld
QVariant get(const Record<ESXRecordT>& record) const override
{
const std::string* string = nullptr;
const ESM::RefId* string = nullptr;
switch (this->mColumnId)
{
@ -2162,12 +2162,12 @@ namespace CSMWorld
if (!string)
throw std::logic_error("Unsupported column ID");
return QString::fromUtf8(string->c_str());
return QString::fromUtf8(string->getRefIdString().c_str());
}
void set(Record<ESXRecordT>& record, const QVariant& data) override
{
std::string* string = nullptr;
ESM::RefId* string = nullptr;
ESXRecordT record2 = record.get();
@ -2190,7 +2190,7 @@ namespace CSMWorld
if (!string)
throw std::logic_error("Unsupported column ID");
*string = data.toString().toUtf8().constData();
*string = ESM::RefId::stringRefId(data.toString().toUtf8().constData());
record.setModified(record2);
}

@ -291,10 +291,10 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete()
continue;
if (!std::binary_search(
mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCase(record.get().mCell)))
mSelection.begin(), mSelection.end(), record.get().mCell.getRefIdString()))
continue;
macro.push(new CSMWorld::DeleteCommand(model, record.get().mId));
macro.push(new CSMWorld::DeleteCommand(model, record.get().mId.getRefIdString()));
}
}
}
@ -322,10 +322,10 @@ void CSMWorld::CommandDispatcher::executeExtendedRevert()
const Record<CellRef>& record = collection.getRecord(i);
if (!std::binary_search(
mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCase(record.get().mCell)))
mSelection.begin(), mSelection.end(), record.get().mCell.getRefIdString()))
continue;
macro.push(new CSMWorld::RevertCommand(model, record.get().mId));
macro.push(new CSMWorld::RevertCommand(model, record.get().mId.getRefIdString()));
}
}
}

@ -411,7 +411,7 @@ CSMWorld::CloneCommand::CloneCommand(CSMWorld::IdTable& model, const std::string
void CSMWorld::CloneCommand::redo()
{
mModel.cloneRecord(mIdOrigin, mId, mType);
mModel.cloneRecord(ESM::RefId::stringRefId(mIdOrigin), ESM::RefId::stringRefId(mId), mType);
applyModifications();
for (auto& value : mOverrideValues)
{
@ -442,7 +442,7 @@ void CSMWorld::CreatePathgridCommand::redo()
std::unique_ptr<Record<Pathgrid>> record
= std::make_unique<Record<Pathgrid>>(static_cast<const Record<Pathgrid>&>(mModel.getRecord(mId)));
record->get().blank();
record->get().mCell = mId;
record->get().mCell = ESM::RefId::stringRefId(mId);
std::pair<CellCoordinates, bool> coords = CellCoordinates::fromId(mId);
if (coords.second)

@ -73,9 +73,9 @@ void CSMWorld::Data::addModel(QAbstractItemModel* model, UniversalId::Type type,
}
}
void CSMWorld::Data::appendIds(std::vector<std::string>& ids, const CollectionBase& collection, bool listDeleted)
void CSMWorld::Data::appendIds(std::vector<ESM::RefId>& ids, const CollectionBase& collection, bool listDeleted)
{
std::vector<std::string> ids2 = collection.getIds(listDeleted);
std::vector<ESM::RefId> ids2 = collection.getIds(listDeleted);
ids.insert(ids.end(), ids2.begin(), ids2.end());
}
@ -578,7 +578,7 @@ CSMWorld::Data::Data(ToUTF8::FromType encoding, bool fsStrict, const Files::Path
mDebugProfiles.addColumn(new DescriptionColumn<ESM::DebugProfile>);
mDebugProfiles.addColumn(new ScriptColumn<ESM::DebugProfile>(ScriptColumn<ESM::DebugProfile>::Type_Lines));
mMetaData.appendBlankRecord("sys::meta");
mMetaData.appendBlankRecord(ESM::RefId::stringRefId("sys::meta"));
mMetaData.addColumn(new StringIdColumn<MetaData>(true));
mMetaData.addColumn(new RecordStateColumn<MetaData>);
@ -1018,7 +1018,7 @@ int CSMWorld::Data::startLoading(const std::filesystem::path& path, bool base, b
if (!mProject && !mBase)
{
MetaData metaData;
metaData.mId = "sys::meta";
metaData.mId = ESM::RefId::stringRefId("sys::meta");
metaData.load(*mReader);
mMetaData.setRecord(0,
@ -1042,7 +1042,7 @@ void CSMWorld::Data::loadFallbackEntries()
if (mReferenceables.searchId(marker.first) == -1)
{
ESM::Static newMarker;
newMarker.mId = marker.first;
newMarker.mId = ESM::RefId::stringRefId(marker.first);
newMarker.mModel = marker.second;
newMarker.mRecordFlags = 0;
auto record = std::make_unique<CSMWorld::Record<ESM::Static>>();
@ -1057,7 +1057,7 @@ void CSMWorld::Data::loadFallbackEntries()
if (mReferenceables.searchId(marker.first) == -1)
{
ESM::Door newMarker;
newMarker.mId = marker.first;
newMarker.mId = ESM::RefId::stringRefId(marker.first);
newMarker.mModel = marker.second;
newMarker.mRecordFlags = 0;
auto record = std::make_unique<CSMWorld::Record<ESM::Door>>();
@ -1172,7 +1172,7 @@ bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages)
messages.add(id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error);
index = mCells.getSize() - 1;
}
std::string cellId = Misc::StringUtils::lowerCase(mCells.getId(index));
std::string cellId = mCells.getId(index).getRefIdString();;
mRefs.load(*mReader, index, mBase, mRefLoadCache[cellId], messages);
break;
}
@ -1241,6 +1241,7 @@ bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages)
case ESM::REC_DIAL:
{
ESM::Dialogue record;
std::string recordIdString = record.mId.getRefIdString();
bool isDeleted = false;
record.load(*mReader, isDeleted);
@ -1250,18 +1251,18 @@ bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages)
// record vector can be shuffled around which would make pointer to record invalid
mDialogue = nullptr;
if (mJournals.tryDelete(record.mId))
if (mJournals.tryDelete(recordIdString))
{
mJournalInfos.removeDialogueInfos(record.mId);
mJournalInfos.removeDialogueInfos(recordIdString);
}
else if (mTopics.tryDelete(record.mId))
else if (mTopics.tryDelete(recordIdString))
{
mTopicInfos.removeDialogueInfos(record.mId);
mTopicInfos.removeDialogueInfos(recordIdString);
}
else
{
messages.add(UniversalId::Type_None,
"Trying to delete dialogue record " + record.mId + " which does not exist", "",
"Trying to delete dialogue record " + recordIdString + " which does not exist", "",
CSMDoc::Message::Severity_Warning);
}
}
@ -1360,9 +1361,9 @@ int CSMWorld::Data::count(RecordBase::State state) const
+ count(state, mPathgrids);
}
std::vector<std::string> CSMWorld::Data::getIds(bool listDeleted) const
std::vector<ESM::RefId> CSMWorld::Data::getIds(bool listDeleted) const
{
std::vector<std::string> ids;
std::vector<ESM::RefId> ids;
appendIds(ids, mGlobals, listDeleted);
appendIds(ids, mGmsts, listDeleted);

@ -140,7 +140,7 @@ namespace CSMWorld
void addModel(QAbstractItemModel* model, UniversalId::Type type, bool update = true);
static void appendIds(std::vector<std::string>& ids, const CollectionBase& collection, bool listDeleted);
static void appendIds(std::vector<ESM::RefId>& ids, const CollectionBase& collection, bool listDeleted);
///< Append all IDs from collection to \a ids.
static int count(RecordBase::State state, const CollectionBase& collection);
@ -305,7 +305,7 @@ namespace CSMWorld
bool hasId(const std::string& id) const;
std::vector<std::string> getIds(bool listDeleted = true) const;
std::vector<ESM::RefId> getIds(bool listDeleted = true) const;
///< Return a sorted collection of all IDs that are not internal to the editor.
///
/// \param listDeleted include deleted record in the list

@ -25,7 +25,7 @@ namespace CSMWorld
loadRecord(record, reader, isDeleted);
std::string id = IdAccessor<Pathgrid>().getId(record);
auto id = IdAccessor<Pathgrid>().getId(record);
int index = this->searchId(id);
if (record.mPoints.empty() || record.mEdges.empty())

@ -74,7 +74,7 @@ namespace CSMWorld
loadRecord(record, reader, isDeleted);
std::string id = IdAccessorT().getId(record);
ESM::RefId id = IdAccessorT().getId(record);
int index = this->searchId(id);
if (isDeleted)

@ -181,11 +181,12 @@ QModelIndex CSMWorld::IdTable::parent(const QModelIndex& index) const
void CSMWorld::IdTable::addRecord(const std::string& id, UniversalId::Type type)
{
int index = mIdCollection->getAppendIndex(id, type);
ESM::RefId refId = ESM::RefId::stringRefId(id);
int index = mIdCollection->getAppendIndex(refId, type);
beginInsertRows(QModelIndex(), index, index);
mIdCollection->appendBlankRecord(id, type);
mIdCollection->appendBlankRecord(refId, type);
endInsertRows();
}
@ -193,11 +194,12 @@ void CSMWorld::IdTable::addRecord(const std::string& id, UniversalId::Type type)
void CSMWorld::IdTable::addRecordWithData(
const std::string& id, const std::map<int, QVariant>& data, UniversalId::Type type)
{
int index = mIdCollection->getAppendIndex(id, type);
ESM::RefId refId = ESM::RefId::stringRefId(id);
int index = mIdCollection->getAppendIndex(refId, type);
beginInsertRows(QModelIndex(), index, index);
mIdCollection->appendBlankRecord(id, type);
mIdCollection->appendBlankRecord(refId, type);
for (std::map<int, QVariant>::const_iterator iter(data.begin()); iter != data.end(); ++iter)
{
@ -208,7 +210,7 @@ void CSMWorld::IdTable::addRecordWithData(
}
void CSMWorld::IdTable::cloneRecord(
const std::string& origin, const std::string& destination, CSMWorld::UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, CSMWorld::UniversalId::Type type)
{
int index = mIdCollection->getAppendIndex(destination, type);
@ -219,9 +221,10 @@ void CSMWorld::IdTable::cloneRecord(
bool CSMWorld::IdTable::touchRecord(const std::string& id)
{
bool changed = mIdCollection->touchRecord(id);
ESM::RefId refId = ESM::RefId::stringRefId(id);
bool changed = mIdCollection->touchRecord(refId);
int row = mIdCollection->getIndex(id);
int row = mIdCollection->getIndex(refId);
int column = mIdCollection->searchColumnIndex(Columns::ColumnId_RecordType);
if (changed && column != -1)
{
@ -234,7 +237,7 @@ bool CSMWorld::IdTable::touchRecord(const std::string& id)
std::string CSMWorld::IdTable::getId(int row) const
{
return mIdCollection->getId(row);
return mIdCollection->getId(row).getRefIdString();
}
/// This method can return only indexes to the top level table cells
@ -278,7 +281,7 @@ void CSMWorld::IdTable::setRecord(
const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord(const std::string& id) const
{
return mIdCollection->getRecord(id);
return mIdCollection->getRecord(ESM::RefId::stringRefId(id));
}
int CSMWorld::IdTable::searchColumnIndex(Columns::ColumnId id) const
@ -367,7 +370,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
{
auto& record = static_cast<const Record<LandTexture>&>(idCollection()->getRecord(i));
if (record.isModified())
reverseLookupMap.emplace(Misc::StringUtils::lowerCase(record.get().mTexture), idCollection()->getId(i));
reverseLookupMap.emplace(Misc::StringUtils::lowerCase(record.get().mTexture), idCollection()->getId(i).getRefIdString());
}
for (const std::string& id : ids)
@ -404,7 +407,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
if (newRow < 0)
{
// Id not taken, clone it
cloneRecord(id, newId, UniversalId::Type_LandTexture);
cloneRecord(ESM::RefId::stringRefId(id), ESM::RefId::stringRefId(newId), UniversalId::Type_LandTexture);
results.createdRecords.push_back(newId);
results.recordMapping.emplace_back(id, newId);
reverseLookupMap.emplace(texture, newId);

@ -64,7 +64,7 @@ namespace CSMWorld
///< \param type Will be ignored, unless the collection supports multiple record types
void cloneRecord(
const std::string& origin, const std::string& destination, UniversalId::Type type = UniversalId::Type_None);
const ESM::RefId& origin, const ESM::RefId& destination, UniversalId::Type type = UniversalId::Type_None);
bool touchRecord(const std::string& id);
///< Will change the record state to modified, if it is not already.

@ -194,7 +194,7 @@ QModelIndex CSMWorld::IdTree::index(int row, int column, const QModelIndex& pare
QModelIndex CSMWorld::IdTree::getNestedModelIndex(const std::string& id, int column) const
{
return CSMWorld::IdTable::index(idCollection()->getIndex(id), column);
return CSMWorld::IdTable::index(idCollection()->getIndex(ESM::RefId::stringRefId(id)), column);
}
QModelIndex CSMWorld::IdTree::parent(const QModelIndex& index) const

@ -7,7 +7,7 @@ namespace CSMWorld
{
struct Info : public ESM::DialInfo
{
std::string mTopicId;
ESM::RefId mTopicId;
};
}

@ -76,7 +76,7 @@ namespace CSMWorld
void CSMWorld::InfoCollection::load(const Info& record, bool base)
{
int index = searchId(record.mId);
int index = searchId(record.mId.getRefIdString());
if (index == -1)
{
@ -135,7 +135,7 @@ int CSMWorld::InfoCollection::getInsertIndex(const std::string& id, UniversalId:
std::pair<RecordConstIterator, RecordConstIterator> range = getTopicRange(id.substr(0, separator));
if (range.first == range.second)
return Collection<Info, IdAccessor<Info>>::getAppendIndex(id, type);
return Collection<Info, IdAccessor<Info>>::getAppendIndex(ESM::RefId::stringRefId(id), type);
return std::distance(getRecords().begin(), range.second);
}
@ -143,12 +143,12 @@ int CSMWorld::InfoCollection::getInsertIndex(const std::string& id, UniversalId:
int index = -1;
const Info& info = static_cast<Record<Info>*>(record)->get();
std::string topic = info.mTopicId;
auto topic = info.mTopicId;
// if the record has a prev, find its index value
if (!info.mPrev.empty())
{
index = getInfoIndex(info.mPrev, topic);
index = getInfoIndex(info.mPrev.getRefIdString(), topic.getRefIdString());
if (index != -1)
++index; // if prev exists, set current index to one above prev
@ -158,13 +158,13 @@ int CSMWorld::InfoCollection::getInsertIndex(const std::string& id, UniversalId:
if (index == -1 && !info.mNext.empty())
{
// if next exists, use its index as the current index
index = getInfoIndex(info.mNext, topic);
index = getInfoIndex(info.mNext.getRefIdString(), topic.getRefIdString());
}
// if next doesn't exist or not found (i.e. neither exist yet) then start a new one
if (index == -1)
{
Range range = getTopicRange(topic); // getTopicRange converts topic to lower case first
Range range = getTopicRange(topic.getRefIdString()); // getTopicRange converts topic to lower case first
index = std::distance(getRecords().begin(), range.second);
}
@ -181,7 +181,7 @@ bool CSMWorld::InfoCollection::reorderRows(int baseIndex, const std::vector<int>
return false;
// Check that topics match
if (!Misc::StringUtils::ciEqual(getRecord(baseIndex).get().mTopicId, getRecord(lastIndex).get().mTopicId))
if (!(getRecord(baseIndex).get().mTopicId == getRecord(lastIndex).get().mTopicId))
return false;
// reorder
@ -204,7 +204,7 @@ void CSMWorld::InfoCollection::load(ESM::ESMReader& reader, bool base, const ESM
bool isDeleted = false;
info.load(reader, isDeleted);
std::string id = Misc::StringUtils::lowerCase(dialogue.mId) + "#" + info.mId;
std::string id = dialogue.mId.getRefIdString() + "#" + info.mId.getRefIdString();
if (isDeleted)
{
@ -230,7 +230,7 @@ void CSMWorld::InfoCollection::load(ESM::ESMReader& reader, bool base, const ESM
else
{
info.mTopicId = dialogue.mId;
info.mId = id;
info.mId = ESM::RefId::stringRefId(id);
load(info, base);
}
}
@ -274,7 +274,7 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId
{
const Record<Info>& record = **range.first;
if (Misc::StringUtils::ciEqual(dialogueId, record.get().mTopicId))
if ((ESM::RefId::stringRefId(dialogueId) == record.get().mTopicId))
{
if (record.mState == RecordBase::State_ModifiedOnly)
{
@ -333,7 +333,7 @@ void CSMWorld::InfoCollection::removeRows(int index, int count)
}
}
void CSMWorld::InfoCollection::appendBlankRecord(const std::string& id, UniversalId::Type type)
void CSMWorld::InfoCollection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type)
{
auto record2 = std::make_unique<Record<Info>>();
@ -342,7 +342,7 @@ void CSMWorld::InfoCollection::appendBlankRecord(const std::string& id, Universa
record2->get().mId = id;
insertRecord(std::move(record2), getInsertIndex(id, type, nullptr), type); // call InfoCollection::insertRecord()
insertRecord(std::move(record2), getInsertIndex(id.getRefIdString(), type, nullptr), type); // call InfoCollection::insertRecord()
}
int CSMWorld::InfoCollection::searchId(std::string_view id) const
@ -357,7 +357,7 @@ int CSMWorld::InfoCollection::searchId(std::string_view id) const
void CSMWorld::InfoCollection::appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type)
{
int index = getInsertIndex(static_cast<Record<Info>*>(record.get())->get().mId, type, record.get());
int index = getInsertIndex(static_cast<Record<Info>*>(record.get())->get().mId.getRefIdString(), type, record.get());
insertRecord(std::move(record), index, type);
}
@ -366,7 +366,7 @@ void CSMWorld::InfoCollection::insertRecord(std::unique_ptr<RecordBase> record,
{
int size = static_cast<int>(getRecords().size());
std::string id = static_cast<Record<Info>*>(record.get())->get().mId;
std::string id = static_cast<Record<Info>*>(record.get())->get().mId.getRefIdString();
std::string::size_type separator = id.find_last_of('#');
if (separator == std::string::npos)

@ -86,7 +86,7 @@ namespace CSMWorld
void removeRows(int index, int count) override;
void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) override;
void appendBlankRecord(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None) override;
int searchId(std::string_view id) const override;

@ -2,6 +2,7 @@
#define CSM_WOLRD_METADATA_H
#include <string>
#include <components/esm/refid.hpp>
namespace ESM
{
@ -13,7 +14,7 @@ namespace CSMWorld
{
struct MetaData
{
std::string mId;
ESM::RefId mId;
int mFormat;
std::string mAuthor;

@ -252,10 +252,10 @@ namespace CSMWorld
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
std::map<ESM::RefId, int>& reactions = faction.mReactions;
// blank row
reactions.insert(std::make_pair("", 0));
reactions.insert(std::make_pair(ESM::RefId::sEmpty, 0));
record.setModified(faction);
}
@ -264,14 +264,14 @@ namespace CSMWorld
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
std::map<ESM::RefId, int>& reactions = faction.mReactions;
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(reactions.size()))
throw std::runtime_error("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
auto iter = reactions.begin();
for (int i = 0; i < rowToRemove; ++i)
++iter;
reactions.erase(iter);
@ -285,7 +285,7 @@ namespace CSMWorld
ESM::Faction faction = record.get();
faction.mReactions
= static_cast<const NestedTableWrapper<std::map<std::string, int>>&>(nestedTable).mNestedTable;
= static_cast<const NestedTableWrapper<std::map<ESM::RefId, int>>&>(nestedTable).mNestedTable;
record.setModified(faction);
}
@ -293,7 +293,7 @@ namespace CSMWorld
NestedTableWrapperBase* FactionReactionsAdapter::table(const Record<ESM::Faction>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::map<std::string, int>>(record.get().mReactions);
return new NestedTableWrapper<std::map<ESM::RefId, int>>(record.get().mReactions);
}
QVariant FactionReactionsAdapter::getData(
@ -301,20 +301,20 @@ namespace CSMWorld
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
std::map<ESM::RefId, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(reactions.size()))
throw std::runtime_error("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::const_iterator iter = reactions.begin();
auto iter = reactions.begin();
for (int i = 0; i < subRowIndex; ++i)
++iter;
switch (subColIndex)
{
case 0:
return QString((*iter).first.c_str());
return QString((*iter).first.getRefIdString().c_str());
case 1:
return (*iter).second;
default:
@ -327,18 +327,18 @@ namespace CSMWorld
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
std::map<ESM::RefId, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(reactions.size()))
throw std::runtime_error("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
auto iter = reactions.begin();
for (int i = 0; i < subRowIndex; ++i)
++iter;
std::string factionId = (*iter).first;
ESM::RefId factionId = (*iter).first;
int reaction = (*iter).second;
switch (subColIndex)
@ -346,7 +346,7 @@ namespace CSMWorld
case 0:
{
reactions.erase(iter);
reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction));
reactions.insert(std::make_pair(ESM::RefId::stringRefId(value.toString().toUtf8().constData()), reaction));
break;
}
case 1:
@ -381,7 +381,7 @@ namespace CSMWorld
// blank row
ESM::Region::SoundRef soundRef;
soundRef.mSound.assign("");
soundRef.mSound = ESM::RefId::sEmpty;
soundRef.mChance = 0;
soundList.insert(soundList.begin() + position, soundRef);
@ -432,7 +432,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
return QString(soundRef.mSound.c_str());
return QString(soundRef.mSound.getRefIdString().c_str());
case 1:
return soundRef.mChance;
default:
@ -454,7 +454,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
soundRef.mSound.assign(value.toString().toUtf8().constData());
soundRef.mSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break;
case 1:
soundRef.mChance = static_cast<unsigned char>(value.toInt());

@ -154,10 +154,10 @@ namespace CSMWorld
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<std::string>& spells = raceOrBthSgn.mPowers.mList;
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
// blank row
std::string spell;
ESM::RefId spell;
spells.insert(spells.begin() + position, spell);
@ -168,7 +168,7 @@ namespace CSMWorld
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<std::string>& spells = raceOrBthSgn.mPowers.mList;
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
@ -183,7 +183,7 @@ namespace CSMWorld
ESXRecordT raceOrBthSgn = record.get();
raceOrBthSgn.mPowers.mList
= static_cast<const NestedTableWrapper<std::vector<std::string>>&>(nestedTable).mNestedTable;
= static_cast<const NestedTableWrapper<std::vector<ESM::RefId>>&>(nestedTable).mNestedTable;
record.setModified(raceOrBthSgn);
}
@ -191,23 +191,23 @@ namespace CSMWorld
NestedTableWrapperBase* table(const Record<ESXRecordT>& record) const override
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<std::string>>(record.get().mPowers.mList);
return new NestedTableWrapper<std::vector<ESM::RefId>>(record.get().mPowers.mList);
}
QVariant getData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const override
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<std::string>& spells = raceOrBthSgn.mPowers.mList;
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
std::string spell = spells[subRowIndex];
ESM::RefId spell = spells[subRowIndex];
switch (subColIndex)
{
case 0:
return QString(spell.c_str());
return QString(spell.getRefIdString().c_str());
default:
throw std::runtime_error("Spells subcolumn index out of range");
}
@ -217,16 +217,16 @@ namespace CSMWorld
{
ESXRecordT raceOrBthSgn = record.get();
std::vector<std::string>& spells = raceOrBthSgn.mPowers.mList;
std::vector<ESM::RefId>& spells = raceOrBthSgn.mPowers.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(spells.size()))
throw std::runtime_error("index out of range");
std::string spell = spells[subRowIndex];
ESM::RefId spell = spells[subRowIndex];
switch (subColIndex)
{
case 0:
spell = value.toString().toUtf8().constData();
spell = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break;
default:
throw std::runtime_error("Spells subcolumn index out of range");

@ -9,11 +9,11 @@ void CSMWorld::Pathgrid::load(ESM::ESMReader& esm, bool& isDeleted, const IdColl
load(esm, isDeleted);
// correct ID
if (!mId.empty() && mId[0] != '#' && cells.searchId(mId) == -1)
if (!mId.empty() && mId.getRefIdString()[0] != '#' && cells.searchId(mId) == -1)
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str();
mId = ESM::RefId::stringRefId(stream.str());
}
}
@ -26,6 +26,6 @@ void CSMWorld::Pathgrid::load(ESM::ESMReader& esm, bool& isDeleted)
{
std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str();
mId = ESM::RefId::stringRefId(stream.str());
}
}

@ -4,6 +4,7 @@
#include <string>
#include <components/esm3/loadpgrd.hpp>
#include <components/esm/refid.hpp>
namespace ESM
{
@ -25,7 +26,7 @@ namespace CSMWorld
/// Exterior cell coordinates are encoded in the pathgrid ID.
struct Pathgrid : public ESM::Pathgrid
{
std::string mId;
ESM::RefId mId;
void load(ESM::ESMReader& esm, bool& isDeleted, const IdCollection<Cell, IdAccessor<Cell>>& cells);
void load(ESM::ESMReader& esm, bool& isDeleted);

@ -11,9 +11,9 @@ namespace CSMWorld
/// \brief Wrapper for CellRef sub record
struct CellRef : public ESM::CellRef
{
std::string mId;
std::string mCell;
std::string mOriginalCell;
ESM::RefId mId;
ESM::RefId mCell;
ESM::RefId mOriginalCell;
bool mNew; // new reference, not counted yet, ref num not assigned yet
unsigned int mIdNum;

@ -64,14 +64,14 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
{
// Keep mOriginalCell empty when in modified (as an indicator that the
// original cell will always be equal the current cell).
ref.mOriginalCell = base ? cell2.mId : "";
ref.mOriginalCell = base ? cell2.mId : ESM::RefId::sEmpty;
if (cell.get().isExterior())
{
// Autocalculate the cell index from coordinates first
std::pair<int, int> index = ref.getCellIndex();
ref.mCell = "#" + std::to_string(index.first) + " " + std::to_string(index.second);
ref.mCell = ESM::RefId::stringRefId("#" + std::to_string(index.first) + " " + std::to_string(index.second));
// Handle non-base moved references
if (!base && isMoved)
@ -86,12 +86,12 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
// Log a warning if the record target cell is different
if (index.first != mref.mTarget[0] || index.second != mref.mTarget[1])
{
std::string indexCell = ref.mCell;
ref.mCell = "#" + std::to_string(mref.mTarget[0]) + " " + std::to_string(mref.mTarget[1]);
ESM::RefId indexCell = ref.mCell;
ref.mCell = ESM::RefId::stringRefId("#" + std::to_string(mref.mTarget[0]) + " " + std::to_string(mref.mTarget[1]));
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, mCells.getId(cellIndex));
messages.add(id, "The position of the moved reference " + ref.mRefID + " (cell " + indexCell + ")"
" does not match the target cell (" + ref.mCell + ")",
messages.add(id, "The position of the moved reference " + ref.mRefID.getRefIdString() + " (cell " + indexCell.getRefIdString() + ")"
" does not match the target cell (" + ref.mCell.getRefIdString() + ")",
std::string(), CSMDoc::Message::Severity_Warning);
}
}
@ -118,7 +118,7 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
messages.add(id,
"Attempt to move a non-existent reference - RefNum index " + std::to_string(ref.mRefNum.mIndex)
+ ", refID " + ref.mRefID + ", content file index " + std::to_string(ref.mRefNum.mContentFile),
+ ", refID " + ref.mRefID.getRefIdString() + ", content file index " + std::to_string(ref.mRefNum.mContentFile),
/*hint*/ "", CSMDoc::Message::Severity_Warning);
continue;
}
@ -127,7 +127,7 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
// ensure we have the same record id for setRecord()
ref.mId = getRecord(index).get().mId;
ref.mIdNum = extractIdNum(ref.mId);
ref.mIdNum = extractIdNum(ref.mId.getRefIdString());
auto record = std::make_unique<Record<CellRef>>();
// TODO: check whether a base record be moved
@ -148,7 +148,7 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
messages.add(id,
"Attempt to delete a non-existent reference - RefNum index " + std::to_string(ref.mRefNum.mIndex)
+ ", refID " + ref.mRefID + ", content file index " + std::to_string(ref.mRefNum.mContentFile),
+ ", refID " + ref.mRefID.getRefIdString() + ", content file index " + std::to_string(ref.mRefNum.mContentFile),
/*hint*/ "", CSMDoc::Message::Severity_Warning);
continue;
}
@ -174,7 +174,7 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
{
// new reference
ref.mIdNum = mNextId; // FIXME: fragile
ref.mId = getNewId();
ref.mId = ESM::RefId::stringRefId(getNewId());
cache.emplace(refNum, ref.mIdNum);
@ -207,7 +207,7 @@ void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool b
}
#endif
ref.mId = getRecord(index).get().mId;
ref.mIdNum = extractIdNum(ref.mId);
ref.mIdNum = extractIdNum(ref.mId.getRefIdString());
auto record = std::make_unique<Record<CellRef>>(getRecord(index));
record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_Modified;
@ -282,14 +282,27 @@ void CSMWorld::RefCollection::appendBlankRecord(const std::string& id, Universal
record->mState = Record<CellRef>::State_ModifiedOnly;
record->mModified.blank();
record->get().mId = id;
record->get().mId = ESM::RefId::stringRefId(id);
record->get().mIdNum = extractIdNum(id);
Collection<CellRef, IdAccessor<CellRef>>::appendRecord(std::move(record));
}
void CSMWorld::RefCollection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type)
{
auto record = std::make_unique<Record<CellRef>>();
record->mState = Record<CellRef>::State_ModifiedOnly;
record->mModified.blank();
record->get().mId = id;
record->get().mIdNum = extractIdNum(id.getRefIdString());
Collection<CellRef, IdAccessor<CellRef>>::appendRecord(std::move(record));
}
void CSMWorld::RefCollection::cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type)
{
auto copy = std::make_unique<Record<CellRef>>();
@ -297,7 +310,7 @@ void CSMWorld::RefCollection::cloneRecord(
copy->mState = RecordBase::State_ModifiedOnly;
copy->get().mId = destination;
copy->get().mIdNum = extractIdNum(destination);
copy->get().mIdNum = extractIdNum(destination.getRefIdString());
insertRecord(std::move(copy), getAppendIndex(destination, type)); // call RefCollection::insertRecord()
}
@ -307,9 +320,14 @@ int CSMWorld::RefCollection::searchId(std::string_view id) const
return searchId(extractIdNum(id));
}
int CSMWorld::RefCollection::searchId(const ESM::RefId& id) const
{
return searchId(extractIdNum(id.getRefIdString()));
}
void CSMWorld::RefCollection::appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type)
{
int index = getAppendIndex(/*id*/ "", type); // for CellRef records id is ignored
int index = getAppendIndex(/*id*/ ESM::RefId::sEmpty, type); // for CellRef records id is ignored
mRefIndex.insert(std::make_pair(static_cast<Record<CellRef>*>(record.get())->get().mIdNum, index));
@ -318,7 +336,7 @@ void CSMWorld::RefCollection::appendRecord(std::unique_ptr<RecordBase> record, U
void CSMWorld::RefCollection::insertRecord(std::unique_ptr<RecordBase> record, int index, UniversalId::Type type)
{
int size = getAppendIndex(/*id*/ "", type); // for CellRef records id is ignored
int size = getAppendIndex(/*id*/ ESM::RefId::sEmpty, type); // for CellRef records id is ignored
unsigned int idNum = static_cast<Record<CellRef>*>(record.get())->get().mIdNum;
Collection<CellRef, IdAccessor<CellRef>>::insertRecord(std::move(record), index, type); // add records only

@ -65,11 +65,13 @@ namespace CSMWorld
virtual void removeRows(int index, int count);
virtual void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None);
virtual void appendBlankRecord(const ESM::RefId& id, UniversalId::Type type = UniversalId::Type_None);
virtual void cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type);
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type);
virtual int searchId(std::string_view id) const;
virtual int searchId(const ESM::RefId& id) const;
virtual void appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type = UniversalId::Type_None);

@ -2,6 +2,7 @@
#define CSM_WOLRD_REFIDADAPTER_H
#include <string>
#include <components/esm/refid.hpp>
/*! \brief
* Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels
@ -38,7 +39,7 @@ namespace CSMWorld
virtual void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const = 0;
///< If the data type does not match an exception is thrown.
virtual std::string getId(const RecordBase& record) const = 0;
virtual ESM::RefId getId(const RecordBase& record) const = 0;
virtual void setId(RecordBase& record, const std::string& id) = 0; // used by RefIdCollection::cloneRecord()
};

@ -503,7 +503,7 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData(const RefIdColumn* column, cons
return record.get().mScale;
if (column == mColumns.mOriginal)
return QString::fromUtf8(record.get().mOriginal.c_str());
return QString::fromUtf8(record.get().mOriginal.getRefIdString().c_str());
if (column == mColumns.mAttributes)
return QVariant::fromValue(ColumnBase::TableEdit_FixedRows);
@ -538,7 +538,7 @@ void CSMWorld::CreatureRefIdAdapter::setData(
else if (column == mColumns.mScale)
creature.mScale = value.toFloat();
else if (column == mColumns.mOriginal)
creature.mOriginal = value.toString().toUtf8().constData();
creature.mOriginal = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mBloodType)
creature.mBloodType = value.toInt();
else
@ -577,10 +577,10 @@ QVariant CSMWorld::DoorRefIdAdapter::getData(const RefIdColumn* column, const Re
= static_cast<const Record<ESM::Door>&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Door)));
if (column == mOpenSound)
return QString::fromUtf8(record.get().mOpenSound.c_str());
return QString::fromUtf8(record.get().mOpenSound.getRefIdString().c_str());
if (column == mCloseSound)
return QString::fromUtf8(record.get().mCloseSound.c_str());
return QString::fromUtf8(record.get().mCloseSound.getRefIdString().c_str());
return NameRefIdAdapter<ESM::Door>::getData(column, data, index);
}
@ -594,9 +594,9 @@ void CSMWorld::DoorRefIdAdapter::setData(
ESM::Door door = record.get();
if (column == mOpenSound)
door.mOpenSound = value.toString().toUtf8().constData();
door.mOpenSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mCloseSound)
door.mCloseSound = value.toString().toUtf8().constData();
door.mCloseSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else
{
NameRefIdAdapter<ESM::Door>::setData(column, data, index, value);
@ -638,7 +638,7 @@ QVariant CSMWorld::LightRefIdAdapter::getData(const RefIdColumn* column, const R
return record.get().mData.mColor;
if (column == mColumns.mSound)
return QString::fromUtf8(record.get().mSound.c_str());
return QString::fromUtf8(record.get().mSound.getRefIdString().c_str());
if (column == mColumns.mEmitterType)
{
@ -682,7 +682,7 @@ void CSMWorld::LightRefIdAdapter::setData(
else if (column == mColumns.mColor)
light.mData.mColor = value.toInt();
else if (column == mColumns.mSound)
light.mSound = value.toString().toUtf8().constData();
light.mSound = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mEmitterType)
{
int mask = ~(ESM::Light::Flicker | ESM::Light::FlickerSlow | ESM::Light::Pulse | ESM::Light::PulseSlow);
@ -784,19 +784,19 @@ QVariant CSMWorld::NpcRefIdAdapter::getData(const RefIdColumn* column, const Ref
= static_cast<const Record<ESM::NPC>&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc)));
if (column == mColumns.mRace)
return QString::fromUtf8(record.get().mRace.c_str());
return QString::fromUtf8(record.get().mRace.getRefIdString().c_str());
if (column == mColumns.mClass)
return QString::fromUtf8(record.get().mClass.c_str());
return QString::fromUtf8(record.get().mClass.getRefIdString().c_str());
if (column == mColumns.mFaction)
return QString::fromUtf8(record.get().mFaction.c_str());
return QString::fromUtf8(record.get().mFaction.getRefIdString().c_str());
if (column == mColumns.mHair)
return QString::fromUtf8(record.get().mHair.c_str());
return QString::fromUtf8(record.get().mHair.getRefIdString().c_str());
if (column == mColumns.mHead)
return QString::fromUtf8(record.get().mHead.c_str());
return QString::fromUtf8(record.get().mHead.getRefIdString().c_str());
if (column == mColumns.mAttributes || column == mColumns.mSkills)
{
@ -838,15 +838,15 @@ void CSMWorld::NpcRefIdAdapter::setData(
ESM::NPC npc = record.get();
if (column == mColumns.mRace)
npc.mRace = value.toString().toUtf8().constData();
npc.mRace = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mClass)
npc.mClass = value.toString().toUtf8().constData();
npc.mClass = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mFaction)
npc.mFaction = value.toString().toUtf8().constData();
npc.mFaction = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mHair)
npc.mHair = value.toString().toUtf8().constData();
npc.mHair = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mHead)
npc.mHead = value.toString().toUtf8().constData();
npc.mHead = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mColumns.mBloodType)
npc.mBloodType = value.toInt();
else if (column == mColumns.mGender)

@ -68,7 +68,7 @@ namespace CSMWorld
public:
BaseRefIdAdapter(UniversalId::Type type, const BaseColumns& base);
std::string getId(const RecordBase& record) const override;
ESM::RefId getId(const RecordBase& record) const override;
void setId(RecordBase& record, const std::string& id) override;
@ -90,11 +90,11 @@ namespace CSMWorld
template <typename RecordT>
void BaseRefIdAdapter<RecordT>::setId(RecordBase& record, const std::string& id)
{
(dynamic_cast<Record<RecordT>&>(record).get().mId) = id;
(dynamic_cast<Record<RecordT>&>(record).get().mId) = ESM::RefId::stringRefId(id);
}
template <typename RecordT>
std::string BaseRefIdAdapter<RecordT>::getId(const RecordBase& record) const
ESM::RefId BaseRefIdAdapter<RecordT>::getId(const RecordBase& record) const
{
return dynamic_cast<const Record<RecordT>&>(record).get().mId;
}
@ -106,7 +106,7 @@ namespace CSMWorld
= static_cast<const Record<RecordT>&>(data.getRecord(RefIdData::LocalIndex(index, mType)));
if (column == mBase.mId)
return QString::fromUtf8(record.get().mId.c_str());
return QString::fromUtf8(record.get().mId.getRefIdString().c_str());
if (column == mBase.mModified)
{
@ -282,7 +282,7 @@ namespace CSMWorld
return QString::fromUtf8(record.get().mName.c_str());
if (column == mName.mScript)
return QString::fromUtf8(record.get().mScript.c_str());
return QString::fromUtf8(record.get().mScript.getRefIdString().c_str());
return ModelRefIdAdapter<RecordT>::getData(column, data, index);
}
@ -298,7 +298,7 @@ namespace CSMWorld
if (column == mName.mName)
record2.mName = value.toString().toUtf8().constData();
else if (column == mName.mScript)
record2.mScript = value.toString().toUtf8().constData();
record2.mScript = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else
{
ModelRefIdAdapter<RecordT>::setData(column, data, index, value);
@ -503,7 +503,7 @@ namespace CSMWorld
data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter<RecordT>::getType())));
if (column == mEnchantable.mEnchantment)
return QString::fromUtf8(record.get().mEnchant.c_str());
return QString::fromUtf8(record.get().mEnchant.getRefIdString().c_str());
if (column == mEnchantable.mEnchantmentPoints)
return static_cast<int>(record.get().mData.mEnchant);
@ -520,7 +520,7 @@ namespace CSMWorld
RecordT record2 = record.get();
if (column == mEnchantable.mEnchantment)
record2.mEnchant = value.toString().toUtf8().constData();
record2.mEnchant = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else if (column == mEnchantable.mEnchantmentPoints)
record2.mData.mEnchant = value.toInt();
else
@ -1265,7 +1265,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mItem.c_str());
return QString::fromUtf8(content.mItem.getRefIdString().c_str());
case 1:
return content.mCount;
default:
@ -1287,7 +1287,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
list.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData()));
list.at(subRowIndex).mItem = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break;
case 1:
@ -1335,9 +1335,9 @@ namespace CSMWorld
= static_cast<Record<ESXRecordT>&>(data.getRecord(RefIdData::LocalIndex(index, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
std::vector<ESM::RefId>& list = caster.mSpells.mList;
std::string newString;
ESM::RefId newString;
if (position >= (int)list.size())
list.push_back(newString);
@ -1353,7 +1353,7 @@ namespace CSMWorld
= static_cast<Record<ESXRecordT>&>(data.getRecord(RefIdData::LocalIndex(index, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
std::vector<ESM::RefId>& list = caster.mSpells.mList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int>(list.size()))
throw std::runtime_error("index out of range");
@ -1371,7 +1371,7 @@ namespace CSMWorld
ESXRecordT caster = record.get();
caster.mSpells.mList
= static_cast<const NestedTableWrapper<std::vector<typename std::string>>&>(nestedTable).mNestedTable;
= static_cast<const NestedTableWrapper<std::vector<typename ESM::RefId>>&>(nestedTable).mNestedTable;
record.setModified(caster);
}
@ -1382,7 +1382,7 @@ namespace CSMWorld
= static_cast<const Record<ESXRecordT>&>(data.getRecord(RefIdData::LocalIndex(index, mType)));
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename std::string>>(record.get().mSpells.mList);
return new NestedTableWrapper<std::vector<typename ESM::RefId>>(record.get().mSpells.mList);
}
QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex,
@ -1391,15 +1391,15 @@ namespace CSMWorld
const Record<ESXRecordT>& record
= static_cast<const Record<ESXRecordT>&>(data.getRecord(RefIdData::LocalIndex(index, mType)));
const std::vector<std::string>& list = record.get().mSpells.mList;
const std::vector<ESM::RefId>& list = record.get().mSpells.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(list.size()))
throw std::runtime_error("index out of range");
const std::string& content = list.at(subRowIndex);
const ESM::RefId& content = list.at(subRowIndex);
if (subColIndex == 0)
return QString::fromUtf8(content.c_str());
return QString::fromUtf8(content.getRefIdString().c_str());
else
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
@ -1410,13 +1410,13 @@ namespace CSMWorld
Record<ESXRecordT>& record
= static_cast<Record<ESXRecordT>&>(data.getRecord(RefIdData::LocalIndex(row, mType)));
ESXRecordT caster = record.get();
std::vector<std::string>& list = caster.mSpells.mList;
std::vector<ESM::RefId>& list = caster.mSpells.mList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int>(list.size()))
throw std::runtime_error("index out of range");
if (subColIndex == 0)
list.at(subRowIndex) = std::string(value.toString().toUtf8());
list.at(subRowIndex) = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
else
throw std::runtime_error("Trying to access non-existing column in the nested table!");
@ -1468,7 +1468,7 @@ namespace CSMWorld
ESM::Transport::Dest newRow;
newRow.mPos = newPos;
newRow.mCellName.clear();
newRow.mCellName = ESM::RefId::sEmpty;
if (position >= (int)list.size())
list.push_back(newRow);
@ -1533,7 +1533,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mCellName.c_str());
return QString::fromUtf8(content.mCellName.getRefIdString().c_str());
case 1:
return content.mPos.pos[0];
case 2:
@ -1565,7 +1565,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData());
list.at(subRowIndex).mCellName = ESM::RefId::stringRefId(value.toString().toUtf8().constData());
break;
case 1:
list.at(subRowIndex).mPos.pos[0] = value.toFloat();
@ -1986,8 +1986,8 @@ namespace CSMWorld
ESM::PartReference newPart;
newPart.mPart = 0; // 0 == head
newPart.mMale.clear();
newPart.mFemale.clear();
newPart.mMale = ESM::RefId::sEmpty;
newPart.mFemale = ESM::RefId::sEmpty;
if (position >= (int)list.size())
list.push_back(newPart);
@ -2059,9 +2059,9 @@ namespace CSMWorld
throw std::runtime_error("Part Reference Type unexpected value");
}
case 1:
return QString(content.mMale.c_str());
return QString(content.mMale.getRefIdString().c_str());
case 2:
return QString(content.mFemale.c_str());
return QString(content.mFemale.getRefIdString().c_str());
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
}
@ -2084,10 +2084,10 @@ namespace CSMWorld
list.at(subRowIndex).mPart = static_cast<unsigned char>(value.toInt());
break;
case 1:
list.at(subRowIndex).mMale = value.toString().toStdString();
list.at(subRowIndex).mMale = ESM::RefId::stringRefId(value.toString().toStdString());
break;
case 2:
list.at(subRowIndex).mFemale = value.toString().toStdString();
list.at(subRowIndex).mFemale = ESM::RefId::stringRefId(value.toString().toStdString());
break;
default:
throw std::runtime_error("Trying to access non-existing column in the nested table!");
@ -2343,7 +2343,7 @@ namespace CSMWorld
std::vector<ESM::LevelledListBase::LevelItem>& list = leveled.mList;
ESM::LevelledListBase::LevelItem newItem;
newItem.mId.clear();
newItem.mId = ESM::RefId::sEmpty;
newItem.mLevel = 0;
if (position >= (int)list.size())
@ -2410,7 +2410,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
return QString(content.mId.c_str());
return QString(content.mId.getRefIdString().c_str());
case 1:
return content.mLevel;
default:
@ -2432,7 +2432,7 @@ namespace CSMWorld
switch (subColIndex)
{
case 0:
list.at(subRowIndex).mId = value.toString().toStdString();
list.at(subRowIndex).mId = ESM::RefId::stringRefId(value.toString().toStdString());
break;
case 1:
list.at(subRowIndex).mLevel = static_cast<short>(value.toInt());

@ -648,17 +648,17 @@ int CSMWorld::RefIdCollection::getSize() const
return mData.getSize();
}
std::string CSMWorld::RefIdCollection::getId(int index) const
ESM::RefId CSMWorld::RefIdCollection::getId(int index) const
{
return getData(index, 0).toString().toUtf8().constData();
return ESM::RefId::stringRefId(getData(index, 0).toString().toUtf8().constData());
}
int CSMWorld::RefIdCollection::getIndex(const std::string& id) const
int CSMWorld::RefIdCollection::getIndex(const ESM::RefId& id) const
{
int index = searchId(id);
if (index == -1)
throw std::runtime_error("invalid ID: " + id);
throw std::runtime_error("invalid ID: " + id.getRefIdString());
return index;
}
@ -720,14 +720,14 @@ void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow
nestedAdapter.removeNestedRow(&mColumns.at(column), mData, localIndex.first, subRow);
}
void CSMWorld::RefIdCollection::appendBlankRecord(const std::string& id, UniversalId::Type type)
void CSMWorld::RefIdCollection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type)
{
mData.appendRecord(type, id, false);
}
int CSMWorld::RefIdCollection::searchId(std::string_view id) const
{
RefIdData::LocalIndex localIndex = mData.searchId(id);
RefIdData::LocalIndex localIndex = mData.searchId(ESM::RefId::stringRefId(id));
if (localIndex.first == -1)
return -1;
@ -735,20 +735,25 @@ int CSMWorld::RefIdCollection::searchId(std::string_view id) const
return mData.localToGlobalIndex(localIndex);
}
int CSMWorld::RefIdCollection::searchId(const ESM::RefId& id) const
{
return searchId(id.getRefIdString());
}
void CSMWorld::RefIdCollection::replace(int index, std::unique_ptr<RecordBase> record)
{
mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release());
}
void CSMWorld::RefIdCollection::cloneRecord(
const std::string& origin, const std::string& destination, const CSMWorld::UniversalId::Type type)
const ESM::RefId& origin, const ESM::RefId& destination, const CSMWorld::UniversalId::Type type)
{
std::unique_ptr<RecordBase> newRecord = mData.getRecord(mData.searchId(origin)).modifiedCopy();
mAdapters.find(type)->second->setId(*newRecord, destination);
mAdapters.find(type)->second->setId(*newRecord, destination.getRefIdString());
mData.insertRecord(std::move(newRecord), type, destination);
}
bool CSMWorld::RefIdCollection::touchRecord(const std::string& id)
bool CSMWorld::RefIdCollection::touchRecord(const ESM::RefId& id)
{
throw std::runtime_error("RefIdCollection::touchRecord is unimplemented");
return false;
@ -756,7 +761,7 @@ bool CSMWorld::RefIdCollection::touchRecord(const std::string& id)
void CSMWorld::RefIdCollection::appendRecord(std::unique_ptr<RecordBase> record, UniversalId::Type type)
{
std::string id = findAdapter(type).getId(*record.get());
auto id = findAdapter(type).getId(*record.get());
int index = mData.getAppendIndex(type);
@ -765,7 +770,7 @@ void CSMWorld::RefIdCollection::appendRecord(std::unique_ptr<RecordBase> record,
mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release());
}
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(const std::string& id) const
const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(const ESM::RefId& id) const
{
return mData.getRecord(mData.searchId(id));
}
@ -780,12 +785,12 @@ void CSMWorld::RefIdCollection::load(ESM::ESMReader& reader, bool base, Universa
mData.load(reader, base, type);
}
int CSMWorld::RefIdCollection::getAppendIndex(const std::string& id, UniversalId::Type type) const
int CSMWorld::RefIdCollection::getAppendIndex(const ESM::RefId& id, UniversalId::Type type) const
{
return mData.getAppendIndex(type);
}
std::vector<std::string> CSMWorld::RefIdCollection::getIds(bool listDeleted) const
std::vector<ESM::RefId> CSMWorld::RefIdCollection::getIds(bool listDeleted) const
{
return mData.getIds(listDeleted);
}

@ -67,9 +67,9 @@ namespace CSMWorld
int getSize() const override;
std::string getId(int index) const override;
ESM::RefId getId(int index) const override;
int getIndex(const std::string& id) const override;
int getIndex(const ESM::RefId& id) const override;
int getColumns() const override;
@ -82,17 +82,21 @@ namespace CSMWorld
void removeRows(int index, int count) override;
void cloneRecord(
const std::string& origin, const std::string& destination, const UniversalId::Type type) override;
const ESM::RefId& origin, const ESM::RefId& destination, const UniversalId::Type type) override;
bool touchRecord(const std::string& id) override;
bool touchRecord(const ESM::RefId& id) override;
void appendBlankRecord(const std::string& id, UniversalId::Type type) override;
void appendBlankRecord(const ESM::RefId& id, UniversalId::Type type) override;
///< \param type Will be ignored, unless the collection supports multiple record types
int searchId(std::string_view id) const override;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
int searchId(const ESM::RefId& id) const override;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
void replace(int index, std::unique_ptr<RecordBase> record) override;
///< If the record type does not match, an exception is thrown.
///
@ -103,16 +107,16 @@ namespace CSMWorld
///
///< \param type Will be ignored, unless the collection supports multiple record types
const RecordBase& getRecord(const std::string& id) const override;
const RecordBase& getRecord(const ESM::RefId& id) const override;
const RecordBase& getRecord(int index) const override;
void load(ESM::ESMReader& reader, bool base, UniversalId::Type type);
int getAppendIndex(const std::string& id, UniversalId::Type type) const override;
int getAppendIndex(const ESM::RefId& id, UniversalId::Type type) const override;
///< \param type Will be ignored, unless the collection supports multiple record types
std::vector<std::string> getIds(bool listDeleted) const override;
std::vector<ESM::RefId> getIds(bool listDeleted) const override;
///< Return a sorted collection of all IDs
///
/// \param listDeleted include deleted record in the list

@ -16,7 +16,7 @@ namespace ESM
CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {}
std::string CSMWorld::RefIdData::getRecordId(const CSMWorld::RefIdData::LocalIndex& index) const
ESM::RefId CSMWorld::RefIdData::getRecordId(const CSMWorld::RefIdData::LocalIndex& index) const
{
std::map<UniversalId::Type, RefIdDataContainerBase*>::const_iterator found = mRecordContainers.find(index.second);
@ -80,11 +80,9 @@ int CSMWorld::RefIdData::localToGlobalIndex(const LocalIndex& index) const
return globalIndex;
}
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId(std::string_view id) const
CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId(const ESM::RefId& id) const
{
std::string id2 = Misc::StringUtils::lowerCase(id);
std::map<std::string, std::pair<int, UniversalId::Type>>::const_iterator iter = mIndex.find(id2);
auto iter = mIndex.find(id);
if (iter == mIndex.end())
return std::make_pair(-1, CSMWorld::UniversalId::Type_None);
@ -92,7 +90,7 @@ CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId(std::string_view i
return iter->second;
}
unsigned int CSMWorld::RefIdData::getRecordFlags(const std::string& id) const
unsigned int CSMWorld::RefIdData::getRecordFlags(const ESM::RefId& id) const
{
LocalIndex localIndex = searchId(id);
@ -197,7 +195,7 @@ CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index)
return iter->second->getRecord(index.first);
}
void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const std::string& id, bool base)
void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const ESM::RefId& id, bool base)
{
std::map<UniversalId::Type, RefIdDataContainerBase*>::iterator iter = mRecordContainers.find(type);
@ -206,7 +204,7 @@ void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const std::string
iter->second->appendRecord(id, base);
mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), LocalIndex(iter->second->getSize() - 1, type)));
mIndex.insert(std::make_pair(id, LocalIndex(iter->second->getSize() - 1, type)));
}
int CSMWorld::RefIdData::getAppendIndex(UniversalId::Type type) const
@ -242,7 +240,7 @@ void CSMWorld::RefIdData::load(ESM::ESMReader& reader, bool base, CSMWorld::Univ
}
else
{
mIndex[Misc::StringUtils::lowerCase(getRecordId(localIndex))] = localIndex;
mIndex[getRecordId(localIndex)] = localIndex;
}
}
}
@ -255,8 +253,8 @@ void CSMWorld::RefIdData::erase(const LocalIndex& index, int count)
for (int i = index.first; i < index.first + count; ++i)
{
std::map<std::string, LocalIndex>::iterator result
= mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(i)));
auto result
= mIndex.find(iter->second->getId(i));
if (result != mIndex.end())
mIndex.erase(result);
@ -267,8 +265,8 @@ void CSMWorld::RefIdData::erase(const LocalIndex& index, int count)
int recordCount = iter->second->getSize();
while (recordIndex < recordCount)
{
std::map<std::string, LocalIndex>::iterator recordIndexFound
= mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(recordIndex)));
auto recordIndexFound
= mIndex.find(iter->second->getId(recordIndex));
if (recordIndexFound != mIndex.end())
{
recordIndexFound->second.first -= count;
@ -284,11 +282,11 @@ int CSMWorld::RefIdData::getSize() const
return mIndex.size();
}
std::vector<std::string> CSMWorld::RefIdData::getIds(bool listDeleted) const
std::vector<ESM::RefId> CSMWorld::RefIdData::getIds(bool listDeleted) const
{
std::vector<std::string> ids;
std::vector<ESM::RefId> ids;
for (std::map<std::string, LocalIndex>::const_iterator iter(mIndex.begin()); iter != mIndex.end(); ++iter)
for (auto iter(mIndex.begin()); iter != mIndex.end(); ++iter)
{
if (listDeleted || !getRecord(iter->second).isDeleted())
{
@ -419,7 +417,7 @@ const CSMWorld::RefIdDataContainer<ESM::Static>& CSMWorld::RefIdData::getStatics
}
void CSMWorld::RefIdData::insertRecord(
std::unique_ptr<CSMWorld::RecordBase> record, CSMWorld::UniversalId::Type type, const std::string& id)
std::unique_ptr<CSMWorld::RecordBase> record, CSMWorld::UniversalId::Type type, const ESM::RefId& id)
{
std::map<UniversalId::Type, RefIdDataContainerBase*>::iterator iter = mRecordContainers.find(type);
@ -428,7 +426,7 @@ void CSMWorld::RefIdData::insertRecord(
iter->second->insertRecord(std::move(record));
mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), LocalIndex(iter->second->getSize() - 1, type)));
mIndex.insert(std::make_pair(id, LocalIndex(iter->second->getSize() - 1, type)));
}
void CSMWorld::RefIdData::copyTo(int index, RefIdData& target) const

@ -56,7 +56,7 @@ namespace CSMWorld
virtual unsigned int getRecordFlags(int index) const = 0;
virtual void appendRecord(const std::string& id, bool base) = 0;
virtual void appendRecord(const ESM::RefId& id, bool base) = 0;
virtual void insertRecord(std::unique_ptr<RecordBase> record) = 0;
@ -65,7 +65,7 @@ namespace CSMWorld
virtual void erase(int index, int count) = 0;
virtual std::string getId(int index) const = 0;
virtual ESM::RefId getId(int index) const = 0;
virtual void save(int index, ESM::ESMWriter& writer) const = 0;
};
@ -83,7 +83,7 @@ namespace CSMWorld
unsigned int getRecordFlags(int index) const override;
void appendRecord(const std::string& id, bool base) override;
void appendRecord(const ESM::RefId& id, bool base) override;
void insertRecord(std::unique_ptr<RecordBase> record) override;
@ -92,7 +92,7 @@ namespace CSMWorld
void erase(int index, int count) override;
std::string getId(int index) const override;
ESM::RefId getId(int index) const override;
void save(int index, ESM::ESMWriter& writer) const override;
};
@ -132,7 +132,7 @@ namespace CSMWorld
}
template <typename RecordT>
void RefIdDataContainer<RecordT>::appendRecord(const std::string& id, bool base)
void RefIdDataContainer<RecordT>::appendRecord(const ESM::RefId& id, bool base)
{
auto record = std::make_unique<Record<RecordT>>();
@ -157,7 +157,7 @@ namespace CSMWorld
int numRecords = static_cast<int>(mContainer.size());
for (; index < numRecords; ++index)
{
if (Misc::StringUtils::ciEqual(mContainer[index]->get().mId, record.mId))
if ((mContainer[index]->get().mId == record.mId))
{
break;
}
@ -216,7 +216,7 @@ namespace CSMWorld
}
template <typename RecordT>
std::string RefIdDataContainer<RecordT>::getId(int index) const
ESM::RefId RefIdDataContainer<RecordT>::getId(int index) const
{
return mContainer.at(index)->get().mId;
}
@ -262,14 +262,14 @@ namespace CSMWorld
RefIdDataContainer<ESM::Static> mStatics;
RefIdDataContainer<ESM::Weapon> mWeapons;
std::map<std::string, LocalIndex> mIndex;
std::map<ESM::RefId, LocalIndex> mIndex;
std::map<UniversalId::Type, RefIdDataContainerBase*> mRecordContainers;
void erase(const LocalIndex& index, int count);
///< Must not spill over into another type.
std::string getRecordId(const LocalIndex& index) const;
ESM::RefId getRecordId(const LocalIndex& index) const;
public:
RefIdData();
@ -278,19 +278,19 @@ namespace CSMWorld
int localToGlobalIndex(const LocalIndex& index) const;
LocalIndex searchId(std::string_view id) const;
LocalIndex searchId(const ESM::RefId& id) const;
void erase(int index, int count);
void insertRecord(std::unique_ptr<RecordBase> record, CSMWorld::UniversalId::Type type, const std::string& id);
void insertRecord(std::unique_ptr<RecordBase> record, CSMWorld::UniversalId::Type type, const ESM::RefId& id);
const RecordBase& getRecord(const LocalIndex& index) const;
RecordBase& getRecord(const LocalIndex& index);
unsigned int getRecordFlags(const std::string& id) const;
unsigned int getRecordFlags(const ESM::RefId& id) const;
void appendRecord(UniversalId::Type type, const std::string& id, bool base);
void appendRecord(UniversalId::Type type, const ESM::RefId& id, bool base);
int getAppendIndex(UniversalId::Type type) const;
@ -298,7 +298,7 @@ namespace CSMWorld
int getSize() const;
std::vector<std::string> getIds(bool listDeleted = true) const;
std::vector<ESM::RefId> getIds(bool listDeleted = true) const;
///< Return a sorted collection of all IDs
///
/// \param listDeleted include deleted record in the list

@ -53,7 +53,7 @@ QModelIndex CSMWorld::RegionMap::getIndex(const CellCoordinates& index) const
CSMWorld::CellCoordinates CSMWorld::RegionMap::getIndex(const Cell& cell) const
{
std::istringstream stream(cell.mId);
std::istringstream stream(cell.mId.getRefIdString());
char ignore;
int x = 0;
@ -74,7 +74,7 @@ void CSMWorld::RegionMap::buildRegions()
const Record<ESM::Region>& region = regions.getRecord(i);
if (!region.isDeleted())
mColours.insert(std::make_pair(Misc::StringUtils::lowerCase(region.get().mId), region.get().mMapColor));
mColours.insert(std::make_pair(region.get().mId, region.get().mMapColor));
}
}
@ -163,33 +163,29 @@ void CSMWorld::RegionMap::removeCell(const CellCoordinates& index)
}
}
void CSMWorld::RegionMap::addRegion(const std::string& region, unsigned int colour)
void CSMWorld::RegionMap::addRegion(const ESM::RefId& region, unsigned int colour)
{
mColours[Misc::StringUtils::lowerCase(region)] = colour;
mColours[region] = colour;
}
void CSMWorld::RegionMap::removeRegion(const std::string& region)
void CSMWorld::RegionMap::removeRegion(const ESM::RefId& region)
{
std::map<std::string, unsigned int>::iterator iter(mColours.find(Misc::StringUtils::lowerCase(region)));
auto iter(mColours.find(region));
if (iter != mColours.end())
mColours.erase(iter);
}
void CSMWorld::RegionMap::updateRegions(const std::vector<std::string>& regions)
void CSMWorld::RegionMap::updateRegions(const std::vector<ESM::RefId>& regions)
{
std::vector<std::string> regions2(regions);
std::vector<ESM::RefId> regions2(regions);
for (auto& region2 : regions2)
{
Misc::StringUtils::lowerCaseInPlace(region2);
}
std::sort(regions2.begin(), regions2.end());
for (std::map<CellCoordinates, CellDescription>::const_iterator iter(mMap.begin()); iter != mMap.end(); ++iter)
{
if (!iter->second.mRegion.empty()
&& std::find(regions2.begin(), regions2.end(), Misc::StringUtils::lowerCase(iter->second.mRegion))
&& std::find(regions2.begin(), regions2.end(),iter->second.mRegion)
!= regions2.end())
{
QModelIndex index = getIndex(iter->first);
@ -337,8 +333,8 @@ QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const
if (cell->second.mDeleted)
return QBrush(Qt::red, Qt::DiagCrossPattern);
std::map<std::string, unsigned int>::const_iterator iter
= mColours.find(Misc::StringUtils::lowerCase(cell->second.mRegion));
auto iter
= mColours.find(cell->second.mRegion);
if (iter != mColours.end())
return QBrush(QColor(iter->second & 0xff, (iter->second >> 8) & 0xff, (iter->second >> 16) & 0xff));
@ -374,8 +370,8 @@ QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const
{
stream << "<br>";
std::map<std::string, unsigned int>::const_iterator iter
= mColours.find(Misc::StringUtils::lowerCase(cell->second.mRegion));
auto iter
= mColours.find(cell->second.mRegion);
if (iter != mColours.end())
stream << cell->second.mRegion;
@ -396,7 +392,7 @@ QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const
std::map<CellCoordinates, CellDescription>::const_iterator cell = mMap.find(cellIndex);
if (cell != mMap.end() && !cell->second.mRegion.empty())
return QString::fromUtf8(Misc::StringUtils::lowerCase(cell->second.mRegion).c_str());
return QString::fromUtf8(cell->second.mRegion.getRefIdString().c_str());
}
if (role == Role_CellId)
@ -419,7 +415,7 @@ Qt::ItemFlags CSMWorld::RegionMap::flags(const QModelIndex& index) const
void CSMWorld::RegionMap::regionsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
std::vector<std::string> update;
std::vector<ESM::RefId> update;
const IdCollection<ESM::Region>& regions = mData.getRegions();
@ -437,7 +433,7 @@ void CSMWorld::RegionMap::regionsAboutToBeRemoved(const QModelIndex& parent, int
void CSMWorld::RegionMap::regionsInserted(const QModelIndex& parent, int start, int end)
{
std::vector<std::string> update;
std::vector<ESM::RefId> update;
const IdCollection<ESM::Region>& regions = mData.getRegions();
@ -461,7 +457,7 @@ void CSMWorld::RegionMap::regionsChanged(const QModelIndex& topLeft, const QMode
// Note: At this point an additional check could be inserted to see if there is any change to the
// columns we are interested in. If not we can exit the function here and avoid all updating.
std::vector<std::string> update;
std::vector<ESM::RefId> update;
const IdCollection<ESM::Region>& regions = mData.getRegions();

@ -40,7 +40,7 @@ namespace CSMWorld
struct CellDescription
{
bool mDeleted;
std::string mRegion;
ESM::RefId mRegion;
std::string mName;
CellDescription();
@ -52,7 +52,7 @@ namespace CSMWorld
std::map<CellCoordinates, CellDescription> mMap;
CellCoordinates mMin; ///< inclusive
CellCoordinates mMax; ///< exclusive
std::map<std::string, unsigned int> mColours; ///< region ID, colour (RGBA)
std::map<ESM::RefId, unsigned int> mColours; ///< region ID, colour (RGBA)
CellCoordinates getIndex(const QModelIndex& index) const;
///< Translates a Qt model index into a cell index (which can contain negative components)
@ -74,18 +74,18 @@ namespace CSMWorld
void removeCell(const CellCoordinates& index);
///< May be called on a cell that is not in the map (in which case the call is ignored)
void addRegion(const std::string& region, unsigned int colour);
void addRegion(const ESM::RefId& region, unsigned int colour);
///< May be called on a region that is already listed (in which case an update is
/// performed)
///
/// \note This function does not update the region map.
void removeRegion(const std::string& region);
void removeRegion(const ESM::RefId& region);
///< May be called on a region that is not listed (in which case the call is ignored)
///
/// \note This function does not update the region map.
void updateRegions(const std::vector<std::string>& regions);
void updateRegions(const std::vector<ESM::RefId>& regions);
///< Update cells affected by the listed regions
void updateSize();

@ -53,9 +53,9 @@ char CSMWorld::ScriptContext::getGlobalType(const std::string& name) const
return ' ';
}
std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string& name, const std::string& id) const
std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string& name, const ESM::RefId& id) const
{
std::string id2 = Misc::StringUtils::lowerCase(id);
ESM::RefId id2 = id;
int index = mData.getScripts().searchId(id2);
bool reference = false;
@ -70,7 +70,7 @@ std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string&
// Referenceable found.
int columnIndex = mData.getReferenceables().findColumnIndex(Columns::ColumnId_Script);
id2 = Misc::StringUtils::lowerCase(
id2 = ESM::RefId::stringRefId(
mData.getReferenceables().getData(index, columnIndex).toString().toUtf8().constData());
if (!id2.empty())
@ -85,7 +85,7 @@ std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string&
if (index == -1)
return std::make_pair(' ', false);
std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(id2);
std::map<std::string, Compiler::Locals>::iterator iter = mLocals.find(id2.getRefIdString());
if (iter == mLocals.end())
{
@ -97,28 +97,24 @@ std::pair<char, bool> CSMWorld::ScriptContext::getMemberType(const std::string&
Compiler::Scanner scanner(errorHandler, stream, getExtensions());
scanner.scan(parser);
iter = mLocals.insert(std::make_pair(id2, locals)).first;
iter = mLocals.insert(std::make_pair(id2.getRefIdString(), locals)).first;
}
return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference);
}
bool CSMWorld::ScriptContext::isId(const std::string& name) const
bool CSMWorld::ScriptContext::isId(const ESM::RefId& name) const
{
if (!mIdsUpdated)
{
mIds = mData.getIds();
for (auto& id : mIds)
{
Misc::StringUtils::lowerCaseInPlace(id);
}
std::sort(mIds.begin(), mIds.end());
mIdsUpdated = true;
}
return std::binary_search(mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase(name));
return std::binary_search(mIds.begin(), mIds.end(), name);
}
void CSMWorld::ScriptContext::invalidateIds()

@ -16,7 +16,7 @@ namespace CSMWorld
class ScriptContext : public Compiler::Context
{
const Data& mData;
mutable std::vector<std::string> mIds;
mutable std::vector<ESM::RefId> mIds;
mutable bool mIdsUpdated;
mutable std::map<std::string, Compiler::Locals> mLocals;
@ -29,13 +29,13 @@ namespace CSMWorld
char getGlobalType(const std::string& name) const override;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
std::pair<char, bool> getMemberType(const std::string& name, const std::string& id) const override;
std::pair<char, bool> getMemberType(const std::string& name, const ESM::RefId& id) const override;
///< Return type of member variable \a name in script \a id or in script of reference of
/// \a id
/// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist.
/// second: true: script of reference
bool isId(const std::string& name) const override;
bool isId(const ESM::RefId& name) const override;
///< Does \a name match an ID, that can be referenced?
void invalidateIds();

@ -275,6 +275,11 @@ CSMWorld::UniversalId::UniversalId(Type type, const std::string& id)
throw std::logic_error("invalid ID argument UniversalId type");
}
CSMWorld::UniversalId::UniversalId(Type type, const ESM::RefId& id)
{
UniversalId(type, id.getRefIdString());
}
CSMWorld::UniversalId::UniversalId(Type type, int index)
: mArgumentType(ArgumentType_Index)
, mType(type)

@ -5,6 +5,7 @@
#include <vector>
#include <QMetaType>
#include <components/esm/refid.hpp>
namespace CSMWorld
{
@ -158,6 +159,9 @@ namespace CSMWorld
UniversalId(Type type, const std::string& id);
///< Using a type for a non-ID-argument UniversalId will throw an exception.
UniversalId(Type type, const ESM::RefId& id);
UniversalId(Type type, int index);
///< Using a type for a non-index-argument UniversalId will throw an exception.

@ -26,7 +26,7 @@ namespace CSVRender
{
const std::string Actor::MeshPrefix = "meshes\\";
Actor::Actor(const std::string& id, CSMWorld::Data& data)
Actor::Actor(const ESM::RefId& id, CSMWorld::Data& data)
: mId(id)
, mData(data)
, mBaseNode(new osg::Group())
@ -73,7 +73,7 @@ namespace CSVRender
mSkeleton->setActive(SceneUtil::Skeleton::Active);
}
void Actor::handleActorChanged(const std::string& refId)
void Actor::handleActorChanged(const ESM::RefId& refId)
{
if (mId == refId)
{

@ -35,7 +35,7 @@ namespace CSVRender
/// \param id The referenceable id
/// \param type The record type
/// \param data The data store
Actor(const std::string& id, CSMWorld::Data& data);
Actor(const ESM::RefId& id, CSMWorld::Data& data);
/// Retrieves the base node that meshes are attached to
osg::Group* getBaseNode();
@ -44,7 +44,7 @@ namespace CSVRender
void update();
private slots:
void handleActorChanged(const std::string& refId);
void handleActorChanged(const ESM::RefId& refId);
private:
void loadSkeleton(const std::string& model);
@ -55,7 +55,7 @@ namespace CSVRender
static const std::string MeshPrefix;
std::string mId;
ESM::RefId mId;
CSMWorld::Data& mData;
CSMWorld::ActorAdapter::ActorDataPtr mActorData;

@ -95,13 +95,14 @@ bool CSVRender::Cell::addObjects(int start, int end)
for (int i = start; i <= end; ++i)
{
std::string cell = Misc::StringUtils::lowerCase(collection.getRecord(i).get().mCell);
auto cellId = collection.getRecord(i).get().mCell;
std::string cell = cellId.getRefIdString();
CSMWorld::RecordBase::State state = collection.getRecord(i).mState;
if (cell == mId && state != CSMWorld::RecordBase::State_Deleted)
if (cellId == mId && state != CSMWorld::RecordBase::State_Deleted)
{
std::string id = Misc::StringUtils::lowerCase(collection.getRecord(i).get().mId);
std::string id =collection.getRecord(i).get().mId.getRefIdString();
auto object = std::make_unique<Object>(mData, mCellNode, id, false);
@ -176,7 +177,7 @@ void CSVRender::Cell::unloadLand()
CSVRender::Cell::Cell(CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, bool deleted)
: mData(data)
, mId(Misc::StringUtils::lowerCase(id))
, mId(ESM::RefId::stringRefId(id))
, mDeleted(deleted)
, mSubMode(0)
, mSubModeElementMask(0)
@ -208,8 +209,8 @@ CSVRender::Cell::Cell(CSMWorld::Data& data, osg::Group* rootNode, const std::str
updateLand();
mPathgrid = std::make_unique<Pathgrid>(mData, mCellNode, mId, mCoordinates);
mCellWater = std::make_unique<CellWater>(mData, mCellNode, mId, mCoordinates);
mPathgrid = std::make_unique<Pathgrid>(mData, mCellNode, mId.getRefIdString(), mCoordinates);
mCellWater = std::make_unique<CellWater>(mData, mCellNode, mId.getRefIdString(), mCoordinates);
}
}
@ -268,7 +269,7 @@ bool CSVRender::Cell::referenceDataChanged(const QModelIndex& topLeft, const QMo
for (int i = topLeft.row(); i <= bottomRight.row(); ++i)
{
std::string cell = Misc::StringUtils::lowerCase(
auto cell =ESM::RefId::stringRefId(
references.data(references.index(i, cellColumn)).toString().toUtf8().constData());
if (cell == mId)

@ -44,7 +44,7 @@ namespace CSVRender
class Cell
{
CSMWorld::Data& mData;
std::string mId;
ESM::RefId mId;
osg::ref_ptr<osg::Group> mCellNode;
std::map<std::string, Object*> mObjects;
std::unique_ptr<Terrain::TerrainGrid> mTerrain;

@ -131,7 +131,7 @@ namespace CSVRender
{
const CSMWorld::Record<CSMWorld::Cell>& cellRecord = cells.getRecord(row);
if (Misc::StringUtils::lowerCase(cellRecord.get().mId) == mId)
if (cellRecord.get().mId == ESM::RefId::stringRefId(mId))
updateCellData(cellRecord);
}
}

@ -155,7 +155,7 @@ void CSVRender::Object::update()
}
else
{
throw std::runtime_error(mReferenceableId + " has no model");
throw std::runtime_error(mReferenceableId.getRefIdString() + " has no model");
}
}
catch (std::exception& e)
@ -460,14 +460,14 @@ CSVRender::Object::Object(
parentNode->addChild(mRootNode);
mRootNode->setNodeMask(Mask_Reference);
ESM::RefId refId = ESM::RefId::stringRefId(id);
if (referenceable)
{
mReferenceableId = id;
mReferenceableId = refId;
}
else
{
mReferenceId = id;
mReferenceId = refId;
mReferenceableId = getReference().mRefID;
}
@ -597,7 +597,7 @@ bool CSVRender::Object::referenceDataChanged(const QModelIndex& topLeft, const Q
const CSMWorld::RefCollection& references = mData.getReferences();
int index = references.searchId(mReferenceId);
int index = references.searchId(mReferenceId.getRefIdString());
if (index != -1 && index >= topLeft.row() && index <= bottomRight.row())
{
@ -607,7 +607,7 @@ bool CSVRender::Object::referenceDataChanged(const QModelIndex& topLeft, const Q
if (columnIndex >= topLeft.column() && columnIndex <= bottomRight.row())
{
mReferenceableId = references.getData(index, columnIndex).toString().toUtf8().constData();
mReferenceableId = ESM::RefId::stringRefId(references.getData(index, columnIndex).toString().toUtf8().constData());
update();
updateMarker();
@ -627,12 +627,12 @@ void CSVRender::Object::reloadAssets()
std::string CSVRender::Object::getReferenceId() const
{
return mReferenceId;
return mReferenceId.getRefIdString();
}
std::string CSVRender::Object::getReferenceableId() const
{
return mReferenceableId;
return mReferenceableId.getRefIdString();
}
osg::ref_ptr<CSVRender::TagBase> CSVRender::Object::getTag() const
@ -734,7 +734,7 @@ void CSVRender::Object::apply(CSMWorld::CommandMacro& commands)
// Do cell check first so positions can be compared
const CSMWorld::CellRef& ref = collection.getRecord(recordIndex).get();
if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell))
if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell.getRefIdString()))
{
// Find cell index at new position
std::pair<int, int> cellIndex

@ -8,6 +8,7 @@
#include <osg/ref_ptr>
#include <components/esm/defs.hpp>
#include <components/esm/refid.hpp>
#include "tagbase.hpp"
@ -81,8 +82,8 @@ namespace CSVRender
static const float MarkerHeadLength;
CSMWorld::Data& mData;
std::string mReferenceId;
std::string mReferenceableId;
ESM::RefId mReferenceId;
ESM::RefId mReferenceableId;
osg::ref_ptr<osg::PositionAttitudeTransform> mRootNode;
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
osg::ref_ptr<osgFX::Scribe> mOutline;

@ -23,6 +23,7 @@
#include <components/esm3/loadpgrd.hpp>
#include <components/misc/constants.hpp>
#include <components/esm/refid.hpp>
#include <osg/Camera>
#include <osg/Vec3f>
@ -380,9 +381,9 @@ void CSVRender::PagedWorldspaceWidget::landDataChanged(const QModelIndex& topLef
{
for (int r = topLeft.row(); r <= bottomRight.row(); ++r)
{
std::string id = mDocument.getData().getLand().getId(r);
auto id = mDocument.getData().getLand().getId(r);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id).first);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id.getRefIdString()).first);
if (cellIt != mCells.end())
{
cellIt->second->landDataChanged(topLeft, bottomRight);
@ -395,9 +396,9 @@ void CSVRender::PagedWorldspaceWidget::landAboutToBeRemoved(const QModelIndex& p
{
for (int r = start; r <= end; ++r)
{
std::string id = mDocument.getData().getLand().getId(r);
auto id = mDocument.getData().getLand().getId(r);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id).first);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id.getRefIdString()).first);
if (cellIt != mCells.end())
{
cellIt->second->landAboutToBeRemoved(parent, start, end);
@ -410,9 +411,9 @@ void CSVRender::PagedWorldspaceWidget::landAdded(const QModelIndex& parent, int
{
for (int r = start; r <= end; ++r)
{
std::string id = mDocument.getData().getLand().getId(r);
auto id = mDocument.getData().getLand().getId(r);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id).first);
auto cellIt = mCells.find(CSMWorld::CellCoordinates::fromId(id.getRefIdString()).first);
if (cellIt != mCells.end())
{
cellIt->second->landAdded(parent, start, end);

@ -85,7 +85,7 @@ namespace CSVRender
const CSMWorld::CellCoordinates& coordinates)
: mData(data)
, mPathgridCollection(mData.getPathgrids())
, mId(pathgridId)
, mId(ESM::RefId::stringRefId(pathgridId))
, mCoords(coordinates)
, mInterior(false)
, mDragOrigin(0)
@ -131,7 +131,7 @@ namespace CSVRender
const std::string& Pathgrid::getId() const
{
return mId;
return mId.getRefIdString();
}
bool Pathgrid::isSelected() const
@ -259,7 +259,7 @@ namespace CSVRender
{
CSMWorld::IdTree* model
= &dynamic_cast<CSMWorld::IdTree&>(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids));
std::string idString = mId.getRefIdString();
const CSMWorld::Pathgrid* source = getPathgridSource();
if (source)
{
@ -285,7 +285,7 @@ namespace CSVRender
int row = static_cast<int>(source->mPoints.size());
// Add node to end of list
commands.push(new CSMWorld::AddNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::AddNestedCommand(*model, idString, row, parentColumn));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posXColumn, parent), posX));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posYColumn, parent), posY));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posZColumn, parent), posZ));
@ -296,25 +296,25 @@ namespace CSVRender
if (index == -1)
{
// Does not exist
commands.push(new CSMWorld::CreatePathgridCommand(*model, mId));
commands.push(new CSMWorld::CreatePathgridCommand(*model, idString));
}
else
{
source = &mPathgridCollection.getRecord(index).get();
// Deleted, so revert and remove all data
commands.push(new CSMWorld::RevertCommand(*model, mId));
commands.push(new CSMWorld::RevertCommand(*model, idString));
int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
for (int row = source->mPoints.size() - 1; row >= 0; --row)
{
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::DeleteNestedCommand(*model, idString, row, parentColumn));
}
parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges);
for (int row = source->mEdges.size() - 1; row >= 0; --row)
{
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::DeleteNestedCommand(*model, idString, row, parentColumn));
}
}
}
@ -401,7 +401,7 @@ namespace CSVRender
for (std::vector<unsigned short>::iterator row = mSelected.begin(); row != mSelected.end(); ++row)
{
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, static_cast<int>(*row), parentColumn));
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId.getRefIdString(), static_cast<int>(*row), parentColumn));
}
// Fix/remove edges
@ -459,7 +459,7 @@ namespace CSVRender
std::set<int, std::greater<int>>::iterator row;
for (row = edgeRowsToRemove.begin(); row != edgeRowsToRemove.end(); ++row)
{
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, *row, parentColumn));
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId.getRefIdString(), *row, parentColumn));
}
}
@ -498,7 +498,7 @@ namespace CSVRender
std::set<int, std::greater<int>>::iterator row;
for (row = rowsToRemove.begin(); row != rowsToRemove.end(); ++row)
{
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, *row, parentColumn));
commands.push(new CSMWorld::DeleteNestedCommand(*model, mId.getRefIdString(), *row, parentColumn));
}
}
}
@ -682,7 +682,7 @@ namespace CSVRender
if (edgeExists(source, node1, node2) == -1)
{
commands.push(new CSMWorld::AddNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::AddNestedCommand(*model, mId.getRefIdString(), row, parentColumn));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, edge0Column, parent), node1));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, edge1Column, parent), node2));
++row;
@ -690,7 +690,7 @@ namespace CSVRender
if (edgeExists(source, node2, node1) == -1)
{
commands.push(new CSMWorld::AddNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::AddNestedCommand(*model, mId.getRefIdString(), row, parentColumn));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, edge0Column, parent), node2));
commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, edge1Column, parent), node1));
}

@ -11,7 +11,7 @@
#include "../../model/world/cellcoordinates.hpp"
#include "../../model/world/subcellcollection.hpp"
#include <components/esm/refid.hpp>
#include "tagbase.hpp"
namespace osg
@ -92,7 +92,7 @@ namespace CSVRender
private:
CSMWorld::Data& mData;
CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& mPathgridCollection;
std::string mId;
ESM::RefId mId;
CSMWorld::CellCoordinates mCoords;
bool mInterior;

@ -310,7 +310,7 @@ bool CSVRender::TerrainSelection::noLandLoaded(const std::string& cellId)
{
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
const CSMWorld::IdCollection<CSMWorld::Land>& landCollection = document.getData().getLand();
return !landCollection.getRecord(cellId).get().isDataLoaded(ESM::Land::DATA_VNML);
return !landCollection.getRecord(ESM::RefId::stringRefId(cellId)).get().isDataLoaded(ESM::Land::DATA_VNML);
}
bool CSVRender::TerrainSelection::isLandLoaded(const std::string& cellId)
@ -339,7 +339,7 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver
CSMDoc::Document& document = mWorldspaceWidget->getDocument();
std::string cellId = CSMWorld::CellCoordinates::generateId(cellX, cellY);
const ESM::Land::LandData* landData
= document.getData().getLand().getRecord(cellId).get().getLandData(ESM::Land::DATA_VHGT);
= document.getData().getLand().getRecord(ESM::RefId::stringRefId(cellId)).get().getLandData(ESM::Land::DATA_VHGT);
return landData->mHeights[localY * ESM::Land::LAND_SIZE + localX];
}

@ -1340,7 +1340,7 @@ bool CSVRender::TerrainShapeMode::noLandLoaded(const std::string& cellId)
{
CSMDoc::Document& document = getWorldspaceWidget().getDocument();
const CSMWorld::IdCollection<CSMWorld::Land>& landCollection = document.getData().getLand();
return !landCollection.getRecord(cellId).get().isDataLoaded(ESM::Land::DATA_VNML);
return !landCollection.getRecord(ESM::RefId::stringRefId(cellId)).get().isDataLoaded(ESM::Land::DATA_VNML);
}
bool CSVRender::TerrainShapeMode::isLandLoaded(const std::string& cellId)

@ -286,7 +286,7 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged(const QModelIndex&
for (int row = rowStart; row <= rowEnd; ++row)
{
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (mCellId == pathgrid.mId)
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
{
mCell->pathgridModified();
flagAsModified();
@ -305,7 +305,7 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved(const QModelIn
for (int row = start; row <= end; ++row)
{
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (mCellId == pathgrid.mId)
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
{
mCell->pathgridRemoved();
flagAsModified();
@ -324,7 +324,7 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent
for (int row = start; row <= end; ++row)
{
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (mCellId == pathgrid.mId)
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
{
mCell->pathgridModified();
flagAsModified();

@ -182,9 +182,9 @@ void CSVWidget::TextureBrushWindow::setBrushTexture(std::string brushTexture)
{
newBrushTextureId = CSMWorld::LandTexture::createUniqueRecordId(0, counter);
if (landtexturesCollection.searchId(brushTexture) != -1
&& landtexturesCollection.getRecord(brushTexture).isDeleted() == 0
&& landtexturesCollection.getRecord(ESM::RefId::stringRefId(brushTexture)).isDeleted() == 0
&& landtexturesCollection.searchId(newBrushTextureId) != -1
&& landtexturesCollection.getRecord(newBrushTextureId).isDeleted() == 0)
&& landtexturesCollection.getRecord(ESM::RefId::stringRefId(newBrushTextureId)).isDeleted() == 0)
counter = (counter + 1) % maxCounter;
else
freeIndexFound = true;

@ -24,7 +24,7 @@ CSVWorld::PreviewSubView::PreviewSubView(const CSMWorld::UniversalId& id, CSMDoc
if (document.getData().getReferenceables().searchId(id.getId()) == -1)
{
std::string referenceableId = document.getData().getReferences().getRecord(id.getId()).get().mRefID;
std::string referenceableId = document.getData().getReferences().getRecord(ESM::RefId::stringRefId(id.getId())).get().mRefID.getRefIdString();
referenceableIdChanged(referenceableId);

@ -7,7 +7,7 @@
#include <components/compiler/extensions0.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/tokenloc.hpp>
#include <components/esm/refid.hpp>
#include "../../model/prefs/category.hpp"
#include "../../model/prefs/setting.hpp"
@ -33,7 +33,7 @@ bool CSVWorld::ScriptHighlighter::parseFloat(float value, const Compiler::TokenL
bool CSVWorld::ScriptHighlighter::parseName(
const std::string& name, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner)
{
highlight(loc, mContext.isId(name) ? Type_Id : Type_Name);
highlight(loc, mContext.isId(ESM::RefId::stringRefId(name)) ? Type_Id : Type_Name);
return true;
}

@ -1319,11 +1319,11 @@ namespace MWClass
switch (boots->getClass().getEquipmentSkill(*boots))
{
case ESM::Skill::LightArmor:
sound = (name == "left") ? "FootLightLeft" : "FootLightRight";
sound = (name == "left") ? "FootLightLeft" : "FootLightRight"; break;
case ESM::Skill::MediumArmor:
sound = (name == "left") ? "FootMedLeft" : "FootMedRight";
sound = (name == "left") ? "FootMedLeft" : "FootMedRight"; break;
case ESM::Skill::HeavyArmor:
sound = (name == "left") ? "FootHeavyLeft" : "FootHeavyRight";
sound = (name == "left") ? "FootHeavyLeft" : "FootHeavyRight"; break;
}
}
return ESM::RefId::sEmpty;

@ -668,7 +668,7 @@ namespace MWDialogue
if (winMgr->getSubtitlesEnabled())
winMgr->messageBox(info->mResponse);
if (!info->mSound.empty())
sndMgr->say(actor, info->mSound.getRefIdString());
sndMgr->say(actor, info->mSound);
if (!info->mResultScript.empty())
executeScript(info->mResultScript, actor);
}

@ -36,7 +36,7 @@ namespace
{
EsmData data;
GetParam().mPushBack(data);
EXPECT_EQ(EsmLoader::getModel(data, GetParam().mRefId, GetParam().mType), GetParam().mResult);
EXPECT_EQ(EsmLoader::getModel(data, ESM::RefId::stringRefId(GetParam().mRefId), GetParam().mType), GetParam().mResult);
}
void pushBack(ESM::Activator&& value, EsmData& esmData)
@ -68,7 +68,7 @@ namespace
void operator()(EsmData& esmData) const
{
T value;
value.mId = mId;
value.mId = ESM::RefId::stringRefId(mId);
value.mModel = mModel;
pushBack(std::move(value), esmData);
}
@ -98,15 +98,15 @@ namespace
{
std::vector<ESM::GameSetting> settings;
ESM::GameSetting setting;
setting.mId = "setting";
setting.mId = ESM::RefId::stringRefId("setting");
setting.mValue = ESM::Variant(42);
settings.push_back(setting);
EXPECT_EQ(EsmLoader::getGameSetting(settings, "setting"), ESM::Variant(42));
EXPECT_EQ(EsmLoader::getGameSetting(settings, ESM::RefId::stringRefId("setting")), ESM::Variant(42));
}
TEST(EsmLoaderGetGameSettingTest, shouldThrowExceptionWhenNotFound)
{
const std::vector<ESM::GameSetting> settings;
EXPECT_THROW(EsmLoader::getGameSetting(settings, "setting"), std::runtime_error);
EXPECT_THROW(EsmLoader::getGameSetting(settings, ESM::RefId::stringRefId("setting")), std::runtime_error);
}
}

@ -58,9 +58,11 @@ namespace
EXPECT_THAT(asVector(conf.getGlobalConf()), ElementsAre(Pair(0, "")));
EXPECT_THAT(asVector(conf.getPlayerConf()), ElementsAre(Pair(1, "")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, "something", ESM::RefNum())), ElementsAre());
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, "something", ESM::RefNum())), ElementsAre(Pair(1, "")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, "something", ESM::RefNum())),
const ESM::RefId something = ESM::RefId::stringRefId("something");
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, something, ESM::RefNum())), ElementsAre());
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, something, ESM::RefNum())), ElementsAre(Pair(1, "")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, something, ESM::RefNum())),
ElementsAre(Pair(1, ""), Pair(3, "")));
// Check that initialization cleans old data
@ -90,7 +92,7 @@ namespace
script1.mInitializationData = "data1";
script1.mFlags = ESM::LuaScriptCfg::sPlayer;
script1.mTypes.push_back(ESM::REC_CREA);
script1.mRecords.push_back({ true, "record1", "dataRecord1" });
script1.mRecords.push_back({ true, ESM::RefId::stringRefId("record1"), "dataRecord1" });
script1.mRefs.push_back({ true, 2, 3, "" });
script1.mRefs.push_back({ true, 2, 4, "" });
@ -103,8 +105,8 @@ namespace
script1Extra.mScriptPath = "script1.LUA";
script1Extra.mFlags = ESM::LuaScriptCfg::sCustom | ESM::LuaScriptCfg::sMerge;
script1Extra.mTypes.push_back(ESM::REC_NPC_);
script1Extra.mRecords.push_back({ false, "rat", "" });
script1Extra.mRecords.push_back({ true, "record2", "" });
script1Extra.mRecords.push_back({ false, ESM::RefId::stringRefId("rat"), "" });
script1Extra.mRecords.push_back({ true, ESM::RefId::stringRefId("record2"), "" });
script1Extra.mRefs.push_back({ true, 3, 5, "dataRef35" });
script1Extra.mRefs.push_back({ false, 2, 3, "" });
@ -116,17 +118,17 @@ namespace
EXPECT_EQ(LuaUtil::scriptCfgToString(conf[1]), "CUSTOM CONTAINER : Script2.lua");
EXPECT_THAT(asVector(conf.getPlayerConf()), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, "something", ESM::RefNum())), ElementsAre(Pair(1, "")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, "guar", ESM::RefNum())), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, "rat", ESM::RefNum())), ElementsAre());
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, ESM::RefId::stringRefId("something"), ESM::RefNum())), ElementsAre(Pair(1, "")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, ESM::RefId::stringRefId("guar"), ESM::RefNum())), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CREA, ESM::RefId::stringRefId("rat"), ESM::RefNum())), ElementsAre());
EXPECT_THAT(
asVector(conf.getLocalConf(ESM::REC_DOOR, "record1", ESM::RefNum())), ElementsAre(Pair(0, "dataRecord1")));
asVector(conf.getLocalConf(ESM::REC_DOOR, ESM::RefId::stringRefId("record1"), ESM::RefNum())), ElementsAre(Pair(0, "dataRecord1")));
EXPECT_THAT(
asVector(conf.getLocalConf(ESM::REC_DOOR, "record2", ESM::RefNum())), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, "record3", { 1, 1 })), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, "record3", { 2, 3 })), ElementsAre());
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, "record3", { 3, 5 })), ElementsAre(Pair(0, "dataRef35")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, "record4", { 2, 4 })),
asVector(conf.getLocalConf(ESM::REC_DOOR, ESM::RefId::stringRefId("record2"), ESM::RefNum())), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, ESM::RefId::stringRefId("record3"), { 1, 1 })), ElementsAre(Pair(0, "data1")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, ESM::RefId::stringRefId("record3"), { 2, 3 })), ElementsAre());
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_NPC_, ESM::RefId::stringRefId("record3"), { 3, 5 })), ElementsAre(Pair(0, "dataRef35")));
EXPECT_THAT(asVector(conf.getLocalConf(ESM::REC_CONT, ESM::RefId::stringRefId("record4"), { 2, 4 })),
ElementsAre(Pair(0, "data1"), Pair(1, "")));
ESM::LuaScriptCfg& script3 = cfg.mScripts.emplace_back();
@ -169,8 +171,8 @@ namespace
script.mFlags = ESM::LuaScriptCfg::sMerge;
script.mTypes.push_back(ESM::REC_DOOR);
script.mTypes.push_back(ESM::REC_MISC);
script.mRecords.push_back({ true, "rat", luaData });
script.mRecords.push_back({ false, "chargendoorjournal", "" });
script.mRecords.push_back({ true, ESM::RefId::stringRefId("rat"), luaData });
script.mRecords.push_back({ false, ESM::RefId::stringRefId("chargendoorjournal"), "" });
script.mRefs.push_back({ true, 128964, 1, "" });
script.mRefs.push_back({ true, 128962, 1, luaData });
}

@ -297,7 +297,7 @@ CUSTOM, PLAYER: useInterface.lua
TEST_F(LuaScriptsContainerTest, Interface)
{
LuaUtil::ScriptsContainer scripts(&mLua, "Test");
scripts.setAutoStartConf(mCfg.getLocalConf(ESM::REC_CREA, "", ESM::RefNum()));
scripts.setAutoStartConf(mCfg.getLocalConf(ESM::REC_CREA, ESM::RefId::sEmpty, ESM::RefNum()));
int addIfaceId = *mCfg.findId("testInterface.lua");
int overrideIfaceId = *mCfg.findId("overrideInterface.lua");
int useIfaceId = *mCfg.findId("useInterface.lua");
@ -327,8 +327,8 @@ CUSTOM, PLAYER: useInterface.lua
LuaUtil::ScriptsContainer scripts1(&mLua, "Test");
LuaUtil::ScriptsContainer scripts2(&mLua, "Test");
LuaUtil::ScriptsContainer scripts3(&mLua, "Test");
scripts1.setAutoStartConf(mCfg.getLocalConf(ESM::REC_NPC_, "", ESM::RefNum()));
scripts2.setAutoStartConf(mCfg.getLocalConf(ESM::REC_NPC_, "", ESM::RefNum()));
scripts1.setAutoStartConf(mCfg.getLocalConf(ESM::REC_NPC_, ESM::RefId::sEmpty, ESM::RefNum()));
scripts2.setAutoStartConf(mCfg.getLocalConf(ESM::REC_NPC_, ESM::RefId::sEmpty, ESM::RefNum()));
scripts3.setAutoStartConf(mCfg.getPlayerConf());
scripts1.addAutoStartedScripts();

@ -29,11 +29,11 @@ namespace
public:
bool canDeclareLocals() const override { return true; }
char getGlobalType(const std::string& name) const override { return ' '; }
std::pair<char, bool> getMemberType(const std::string& name, const std::string& id) const override
std::pair<char, bool> getMemberType(const std::string& name, const ESM::RefId& id) const override
{
return { ' ', false };
}
bool isId(const std::string& name) const override { return Misc::StringUtils::ciEqual(name, "player"); }
bool isId(const ESM::RefId& name) const override { return name == ESM::RefId::stringRefId("player"); }
};
class TestErrorHandler : public Compiler::ErrorHandler
@ -147,7 +147,7 @@ namespace
std::map<std::string, GlobalVariables, std::less<>> mMembers;
public:
std::string_view getTarget() const override { return {}; }
const ESM::RefId& getTarget() const override { return ESM::RefId::sEmpty; };
int getLocalShort(int index) const override { return mLocals.getShort(index); }
@ -207,44 +207,44 @@ namespace
std::string_view getCurrentCellName() const override { return {}; }
int getMemberShort(std::string_view id, std::string_view name, bool global) const override
int getMemberShort(const ESM::RefId id, std::string_view name, bool global) const override
{
auto it = mMembers.find(id);
auto it = mMembers.find(id.getRefIdString());
if (it != mMembers.end())
return it->second.getShort(name);
return {};
}
int getMemberLong(std::string_view id, std::string_view name, bool global) const override
int getMemberLong(const ESM::RefId id, std::string_view name, bool global) const override
{
auto it = mMembers.find(id);
auto it = mMembers.find(id.getRefIdString());
if (it != mMembers.end())
return it->second.getLong(name);
return {};
}
float getMemberFloat(std::string_view id, std::string_view name, bool global) const override
float getMemberFloat(const ESM::RefId id, std::string_view name, bool global) const override
{
auto it = mMembers.find(id);
auto it = mMembers.find(id.getRefIdString());
if (it != mMembers.end())
return it->second.getFloat(name);
return {};
}
void setMemberShort(std::string_view id, std::string_view name, int value, bool global) override
void setMemberShort(const ESM::RefId id, std::string_view name, int value, bool global) override
{
mMembers[std::string(id)].setShort(name, value);
}
mMembers[id.getRefIdString()].setShort(name, value);
};
void setMemberLong(std::string_view id, std::string_view name, int value, bool global) override
void setMemberLong(const ESM::RefId id, std::string_view name, int value, bool global) override
{
mMembers[std::string(id)].setLong(name, value);
}
mMembers[id.getRefIdString()].setLong(name, value);
};
void setMemberFloat(std::string_view id, std::string_view name, float value, bool global) override
void setMemberFloat(const ESM::RefId id, std::string_view name, float value, bool global) override
{
mMembers[std::string(id)].setFloat(name, value);
}
mMembers[id.getRefIdString()].setFloat(name, value);
};
};
struct CompiledScript
@ -260,4 +260,4 @@ namespace
};
}
#endif
#endif

@ -20,7 +20,7 @@
namespace MWMechanics
{
SpellList::SpellList(const std::string& id, int type)
SpellList::SpellList(const ESM::RefId& id, int type)
: mId(id)
, mType(type)
{
@ -255,7 +255,7 @@ std::unique_ptr<std::istream> getEsmFile(T record, bool deleted)
/// Tests deletion of records.
TEST_F(StoreTest, delete_test)
{
const std::string recordId = "foobar";
const ESM::RefId recordId = ESM::RefId::stringRefId("foobar");
typedef ESM::Apparatus RecordType;
@ -292,8 +292,8 @@ TEST_F(StoreTest, delete_test)
/// Tests overwriting of records.
TEST_F(StoreTest, overwrite_test)
{
const std::string recordId = "foobar";
const std::string recordIdUpper = "Foobar";
const ESM::RefId recordId = ESM::RefId::stringRefId("foobar");
const ESM::RefId recordIdUpper = ESM::RefId::stringRefId("Foobar");
typedef ESM::Apparatus RecordType;

@ -50,7 +50,7 @@ namespace ESM
mPcFaction = esm.getRefId();
break;
case fourCC("SNAM"):
mSound = esm.getRefId();
mSound = esm.getHString();
break;
case SREC_NAME:
mResponse = esm.getHString();
@ -108,7 +108,7 @@ namespace ESM
esm.writeHNOCString("FNAM", mFaction.getRefIdString());
esm.writeHNOCString("ANAM", mCell.getRefIdString());
esm.writeHNOCString("DNAM", mPcFaction.getRefIdString());
esm.writeHNOCString("SNAM", mSound.getRefIdString());
esm.writeHNOCString("SNAM", mSound);
esm.writeHNOString("NAME", mResponse);
for (std::vector<SelectStruct>::const_iterator it = mSelects.begin(); it != mSelects.end(); ++it)
@ -148,7 +148,7 @@ namespace ESM
mFaction = ESM::RefId::sEmpty;
mPcFaction = ESM::RefId::sEmpty;
mCell = ESM::RefId::sEmpty;
mSound = ESM::RefId::sEmpty;
mSound.clear();
mResponse.clear();
mResultScript.clear();
mFactionLess = false;

@ -75,7 +75,7 @@ namespace ESM
RefId mActor, mRace, mClass, mFaction, mPcFaction, mCell;
// Sound and text associated with this item
RefId mSound;
std::string mSound;
std::string mResponse;
// Result script (uncompiled) to run whenever this dialog item is
// selected

Loading…
Cancel
Save