diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index 1d58993588..9cc8fb1ea4 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -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; diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index 46987c44b2..1f178c0016 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -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; } diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index 8911858215..7520de15f8 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -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; diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 82cb10e53a..7606484e0a 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -45,6 +45,7 @@ #include "convertnpcc.hpp" #include "convertplayer.hpp" #include "convertscpt.hpp" +#include namespace ESSImport { @@ -89,7 +90,7 @@ namespace ESSImport void write(ESM::ESMWriter& esm) override { - for (typename std::map::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 mRecords; + std::map 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, int> owners; + std::map, 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::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); } diff --git a/apps/essimporter/convertinventory.cpp b/apps/essimporter/convertinventory.cpp index 484b9d1130..2f03cfaf41 100644 --- a/apps/essimporter/convertinventory.cpp +++ b/apps/essimporter/convertinventory.cpp @@ -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); diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 3cb12c2f3a..5bb9897487 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -8,13 +8,13 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& 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; diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index 864a7d8540..ccc0f7d64d 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -9,7 +9,7 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls); } diff --git a/apps/essimporter/convertscpt.cpp b/apps/essimporter/convertscpt.cpp index 9d03ae3d3c..af456515a1 100644 --- a/apps/essimporter/convertscpt.cpp +++ b/apps/essimporter/convertscpt.cpp @@ -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); diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 179e31adbd..7ac0b1e1a7 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -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_); diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index baad8a366f..e1ecc4074e 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -40,15 +40,15 @@ namespace ESSImport float mHour; // key - std::map, CREC> mCreatureChanges; - std::map, NPCC> mNpcChanges; - std::map, CNTC> mContainerChanges; + std::map, CREC> mCreatureChanges; + std::map, NPCC> mNpcChanges; + std::map, CNTC> mContainerChanges; - std::map, int> mActorIdMap; + std::map, int> mActorIdMap; int mNextActorId; - std::map mCreatures; - std::map mNpcs; + std::map mCreatures; + std::map mNpcs; std::vector 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; diff --git a/apps/navmeshtool/main.cpp b/apps/navmeshtool/main.cpp index 6b60e5f2f9..8eb4b3e92f 100644 --- a/apps/navmeshtool/main.cpp +++ b/apps/navmeshtool/main.cpp @@ -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); diff --git a/apps/navmeshtool/worldspacedata.cpp b/apps/navmeshtool/worldspacedata.cpp index f66b54dd9b..8ac6090cac 100644 --- a/apps/navmeshtool/worldspacedata.cpp +++ b/apps/navmeshtool/worldspacedata.cpp @@ -36,7 +36,7 @@ #include #include #include - +#include 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; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 698ff60c43..eab9dce8cd 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -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(""); @@ -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(); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index c03eb5762c..2d2f066906 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -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& indices = mState.getSubRecords()[Misc::StringUtils::lowerCase(cellId)]; + std::deque& 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 persistentRefs; std::map>::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; } diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index b641f9bf7b..6fb938768f 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -97,7 +97,7 @@ namespace CSMDoc template void WriteCollectionStage::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(); diff --git a/apps/opencs/model/tools/bodypartcheck.cpp b/apps/opencs/model/tools/bodypartcheck.cpp index e53cd9e40a..a301aff248 100644 --- a/apps/opencs/model/tools/bodypartcheck.cpp +++ b/apps/opencs/model/tools/bodypartcheck.cpp @@ -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); } } diff --git a/apps/opencs/model/tools/gmstcheck.cpp b/apps/opencs/model/tools/gmstcheck.cpp index c32c3e948c..3433bbbbf3 100644 --- a/apps/opencs/model/tools/gmstcheck.cpp +++ b/apps/opencs/model/tools/gmstcheck.cpp @@ -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); diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp index 00bf6605d7..84973c5a9c 100644 --- a/apps/opencs/model/tools/journalcheck.cpp +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -50,7 +50,7 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) int totalInfoCount = 0; std::set 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) { diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index f2d19187f5..1770cb694e 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -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); } diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index 5950ee20d8..3ebb2621f8 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -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& effects, diff --git a/apps/opencs/model/tools/mandatoryid.cpp b/apps/opencs/model/tools/mandatoryid.cpp index fd02d8b450..b4642365de 100644 --- a/apps/opencs/model/tools/mandatoryid.cpp +++ b/apps/opencs/model/tools/mandatoryid.cpp @@ -10,7 +10,7 @@ #include CSMTools::MandatoryIdStage::MandatoryIdStage(const CSMWorld::CollectionBase& idCollection, - const CSMWorld::UniversalId& collectionId, const std::vector& ids) + const CSMWorld::UniversalId& collectionId, const std::vector& 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()); } diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp index f0ca04671d..3c62b8a2c2 100644 --- a/apps/opencs/model/tools/mandatoryid.hpp +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -5,7 +5,7 @@ #include #include "../world/universalid.hpp" - +#include #include "../doc/stage.hpp" namespace CSMDoc @@ -25,11 +25,11 @@ namespace CSMTools { const CSMWorld::CollectionBase& mIdCollection; CSMWorld::UniversalId mCollectionId; - std::vector mIds; + std::vector mIds; public: MandatoryIdStage(const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, - const std::vector& ids); + const std::vector& ids); int setup() override; ///< \return number of steps diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index 501dcf8848..5f8ef6788c 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -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( *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(); diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index b2b5535c0c..5aa3bbe439 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -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&>(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(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); } } diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index 5497067280..c6924cfc73 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -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); } diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 25c5a09986..4affc1bd44 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -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); } diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index 5244c34640..644bb3c08c 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -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()); diff --git a/apps/opencs/model/tools/scriptcheck.hpp b/apps/opencs/model/tools/scriptcheck.hpp index e83ff4acd1..31b3f32915 100644 --- a/apps/opencs/model/tools/scriptcheck.hpp +++ b/apps/opencs/model/tools/scriptcheck.hpp @@ -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; diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index 63b9d9fc91..64c1bacc32 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -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); } } diff --git a/apps/opencs/model/tools/startscriptcheck.cpp b/apps/opencs/model/tools/startscriptcheck.cpp index 2a730cb259..ba468ddb51 100644 --- a/apps/opencs/model/tools/startscriptcheck.cpp +++ b/apps/opencs/model/tools/startscriptcheck.cpp @@ -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() diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index a2b95f1a30..4a58a4fdf9 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -79,8 +79,12 @@ CSMDoc::OperationHolder* CSMTools::Tools::getVerifier() std::vector mandatoryIds{ "Day", "DaysPassed", "GameHour", "Month", "PCRace" }; + std::vector 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())); diff --git a/apps/opencs/model/tools/topicinfocheck.cpp b/apps/opencs/model/tools/topicinfocheck.cpp index 0c1b8b4f4f..eb1fe2be5b 100644 --- a/apps/opencs/model/tools/topicinfocheck.cpp +++ b/apps/opencs/model/tools/topicinfocheck.cpp @@ -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 -bool CSMTools::TopicInfoCheckStage::verifyId(const std::string& name, const CSMWorld::IdCollection& collection, +bool CSMTools::TopicInfoCheckStage::verifyId(const ESM::RefId& name, const CSMWorld::IdCollection& 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; } diff --git a/apps/opencs/model/tools/topicinfocheck.hpp b/apps/opencs/model/tools/topicinfocheck.hpp index 139e676928..c58df98ba9 100644 --- a/apps/opencs/model/tools/topicinfocheck.hpp +++ b/apps/opencs/model/tools/topicinfocheck.hpp @@ -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 - bool verifyId(const std::string& name, const CSMWorld::IdCollection& collection, + bool verifyId(const ESM::RefId& name, const CSMWorld::IdCollection& collection, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); }; } diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index d5bcf54270..9374e16414 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -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& 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) { diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index 363f01c952..81bef223e3 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -37,9 +37,9 @@ namespace CSMWorld /// A list indexed by ESM::PartReferenceType using ActorPartList = std::map>; /// A list indexed by ESM::BodyPart::MeshPart - using RacePartList = std::array; + using RacePartList = std::array; /// Tracks unique strings - using StringSet = std::unordered_set; + using RefIdSet = std::unordered_set; /// 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; @@ -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; 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& mRaces; IdCollection& mBodyParts; - Misc::WeakCache mCachedActors; // Key: referenceable id - Misc::WeakCache mCachedRaces; // Key: race id + Misc::WeakCache mCachedActors; // Key: referenceable id + Misc::WeakCache 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 }; } diff --git a/apps/opencs/model/world/cell.cpp b/apps/opencs/model/world/cell.cpp index dff09aac61..f4b0084ef4 100644 --- a/apps/opencs/model/world/cell.cpp +++ b/apps/opencs/model/world/cell.cpp @@ -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()); } } diff --git a/apps/opencs/model/world/cell.hpp b/apps/opencs/model/world/cell.hpp index 3d057c39c9..5d4aefbda2 100644 --- a/apps/opencs/model/world/cell.hpp +++ b/apps/opencs/model/world/cell.hpp @@ -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); }; diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 2c33cb18d0..d04c983eab 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -28,53 +28,53 @@ namespace CSMWorld template 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 - void IdAccessor::setId(ESXRecordT& record, const std::string& id) const + void IdAccessor::setId(ESXRecordT& record, const ESM::RefId& id) const { record.mId = id; } template - const std::string IdAccessor::getId(const ESXRecordT& record) const + const ESM::RefId IdAccessor::getId(const ESXRecordT& record) const { return record.mId; } template <> - inline void IdAccessor::setId(Land& record, const std::string& id) const + inline void IdAccessor::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::setId(LandTexture& record, const std::string& id) const + inline void IdAccessor::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::getId(const Land& record) const + inline const ESM::RefId IdAccessor::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::getId(const LandTexture& record) const + inline const ESM::RefId IdAccessor::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 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& getRecord(const std::string& id) const override; + const Record& getRecord(const ESM::RefId& id) const override; const Record& 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 getIds(bool listDeleted = true) const override; + std::vector 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>(); - 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*)©->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 int Collection::touchRecordImp(const std::string& id) { - int index = getIndex(id); + int index = getIndex(ESM::RefId::stringRefId(id)); Record& record = *mRecords.at(index); if (record.isDeleted()) { @@ -278,29 +282,29 @@ namespace CSMWorld template void Collection::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>::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 - bool Collection::touchRecord(const std::string& id) + bool Collection::touchRecord(const ESM::RefId& id) { - return touchRecordImp(id) != -1; + return touchRecordImp(id.getRefIdString()) != -1; } template <> - inline bool Collection>::touchRecord(const std::string& id) + inline bool Collection>::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 void Collection::add(const ESXRecordT& record) { - std::string id = Misc::StringUtils::lowerCase(IdAccessorT().getId(record)); + auto id = IdAccessorT().getId(record); - std::map::iterator iter = mIndex.find(id); + auto iter = mIndex.find(id.getRefIdString()); if (iter == mIndex.end()) { @@ -350,18 +354,18 @@ namespace CSMWorld } template - std::string Collection::getId(int index) const + ESM::RefId Collection::getId(int index) const { return IdAccessorT().getId(mRecords.at(index)->get()); } template - int Collection::getIndex(const std::string& id) const + int Collection::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 - void Collection::appendBlankRecord(const std::string& id, UniversalId::Type type) + void Collection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type) { ESXRecordT record; IdAccessorT().setId(record, id); @@ -482,6 +486,18 @@ namespace CSMWorld return iter->second; } + template + int Collection::searchId(const ESM::RefId& id) const + { + + std::map::const_iterator iter = mIndex.find(id.getRefIdString()); + + if (iter == mIndex.end()) + return -1; + + return iter->second; + } + template void Collection::replace(int index, std::unique_ptr record) { @@ -497,17 +513,17 @@ namespace CSMWorld } template - int Collection::getAppendIndex(const std::string& id, UniversalId::Type type) const + int Collection::getAppendIndex(const ESM::RefId& id, UniversalId::Type type) const { return static_cast(mRecords.size()); } template - std::vector Collection::getIds(bool listDeleted) const + std::vector Collection::getIds(bool listDeleted) const { - std::vector ids; + std::vector ids; - for (typename std::map::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 - const Record& Collection::getRecord(const std::string& id) const + const Record& Collection::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> record2(static_cast*>(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 void Collection::setRecord(int index, std::unique_ptr> 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); diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 7795f9cea4..42c0718609 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -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 diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 8ac918612e..a22e9ce7a6 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -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 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 getIds(bool listDeleted = true) const = 0; + virtual std::vector getIds(bool listDeleted = true) const = 0; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list diff --git a/apps/opencs/model/world/columnimp.cpp b/apps/opencs/model/world/columnimp.cpp index 20246d644c..d9d5971aa6 100644 --- a/apps/opencs/model/world/columnimp.cpp +++ b/apps/opencs/model/world/columnimp.cpp @@ -20,13 +20,13 @@ namespace CSMWorld QVariant LandTextureNicknameColumn::get(const Record& record) const { - return QString::fromUtf8(record.get().mId.c_str()); + return QString::fromUtf8(record.get().mId.getRefIdString().c_str()); } void LandTextureNicknameColumn::set(Record& 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); } diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 20042d526d..264e81fe03 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -61,7 +61,7 @@ namespace CSMWorld QVariant get(const Record& 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& record) const override { - return QString::fromUtf8(record.get().mSleepList.c_str()); + return QString::fromUtf8(record.get().mSleepList.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mRegion.c_str()); + return QString::fromUtf8(record.get().mRegion.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mCell.c_str()); + return QString::fromUtf8(record.get().mCell.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mOriginalCell.c_str()); + return QString::fromUtf8(record.get().mOriginalCell.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mRefID.c_str()); + return QString::fromUtf8(record.get().mRefID.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mOwner.c_str()); + return QString::fromUtf8(record.get().mOwner.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mSoul.c_str()); + return QString::fromUtf8(record.get().mSoul.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mFaction.c_str()); + return QString::fromUtf8(record.get().mFaction.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mKey.c_str()); + return QString::fromUtf8(record.get().mKey.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mTrap.c_str()); + return QString::fromUtf8(record.get().mTrap.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mTopicId.c_str()); + return QString::fromUtf8(record.get().mTopicId.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mActor.c_str()); + return QString::fromUtf8(record.get().mActor.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mRace.c_str()); + return QString::fromUtf8(record.get().mRace.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mClass.c_str()); + return QString::fromUtf8(record.get().mClass.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mPcFaction.c_str()); + return QString::fromUtf8(record.get().mPcFaction.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mSound.c_str()); + return QString::fromUtf8(record.get().mSound.getRefIdString().c_str()); } void set(Record& 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& record) const override { - return QString::fromUtf8(record.get().mCreature.c_str()); + return QString::fromUtf8(record.get().mCreature.getRefIdString().c_str()); } void set(Record& 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& 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& 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& 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& 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); } diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index b292f3b7e8..7b6929b88a 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -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& 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())); } } } diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 6929ded052..b34fc4e14b 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -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 = std::make_unique>(static_cast&>(mModel.getRecord(mId))); record->get().blank(); - record->get().mCell = mId; + record->get().mCell = ESM::RefId::stringRefId(mId); std::pair coords = CellCoordinates::fromId(mId); if (coords.second) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index f24d51352c..36804d8cb0 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -73,9 +73,9 @@ void CSMWorld::Data::addModel(QAbstractItemModel* model, UniversalId::Type type, } } -void CSMWorld::Data::appendIds(std::vector& ids, const CollectionBase& collection, bool listDeleted) +void CSMWorld::Data::appendIds(std::vector& ids, const CollectionBase& collection, bool listDeleted) { - std::vector ids2 = collection.getIds(listDeleted); + std::vector 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); mDebugProfiles.addColumn(new ScriptColumn(ScriptColumn::Type_Lines)); - mMetaData.appendBlankRecord("sys::meta"); + mMetaData.appendBlankRecord(ESM::RefId::stringRefId("sys::meta")); mMetaData.addColumn(new StringIdColumn(true)); mMetaData.addColumn(new RecordStateColumn); @@ -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>(); @@ -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>(); @@ -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 CSMWorld::Data::getIds(bool listDeleted) const +std::vector CSMWorld::Data::getIds(bool listDeleted) const { - std::vector ids; + std::vector ids; appendIds(ids, mGlobals, listDeleted); appendIds(ids, mGmsts, listDeleted); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index f55046084f..e0f5139e6d 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -140,7 +140,7 @@ namespace CSMWorld void addModel(QAbstractItemModel* model, UniversalId::Type type, bool update = true); - static void appendIds(std::vector& ids, const CollectionBase& collection, bool listDeleted); + static void appendIds(std::vector& 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 getIds(bool listDeleted = true) const; + std::vector 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 diff --git a/apps/opencs/model/world/idcollection.cpp b/apps/opencs/model/world/idcollection.cpp index fb00f766f0..7459b016d3 100644 --- a/apps/opencs/model/world/idcollection.cpp +++ b/apps/opencs/model/world/idcollection.cpp @@ -25,7 +25,7 @@ namespace CSMWorld loadRecord(record, reader, isDeleted); - std::string id = IdAccessor().getId(record); + auto id = IdAccessor().getId(record); int index = this->searchId(id); if (record.mPoints.empty() || record.mEdges.empty()) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index a716bc88cc..95165b021c 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -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) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 708740f9ed..4820f4e2a8 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -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& 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::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&>(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); diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 0a6a6e4caf..f79e94ad68 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -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. diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 10c103ed12..a88234d63d 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -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 diff --git a/apps/opencs/model/world/info.hpp b/apps/opencs/model/world/info.hpp index 9405c002c7..f1743b5760 100644 --- a/apps/opencs/model/world/info.hpp +++ b/apps/opencs/model/world/info.hpp @@ -7,7 +7,7 @@ namespace CSMWorld { struct Info : public ESM::DialInfo { - std::string mTopicId; + ESM::RefId mTopicId; }; } diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index b90ce2a711..d812ba4275 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -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 range = getTopicRange(id.substr(0, separator)); if (range.first == range.second) - return Collection>::getAppendIndex(id, type); + return Collection>::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)->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 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& 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>(); @@ -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 record, UniversalId::Type type) { - int index = getInsertIndex(static_cast*>(record.get())->get().mId, type, record.get()); + int index = getInsertIndex(static_cast*>(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 record, { int size = static_cast(getRecords().size()); - std::string id = static_cast*>(record.get())->get().mId; + std::string id = static_cast*>(record.get())->get().mId.getRefIdString(); std::string::size_type separator = id.find_last_of('#'); if (separator == std::string::npos) diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp index 14f92262fc..b83cb3f52e 100644 --- a/apps/opencs/model/world/infocollection.hpp +++ b/apps/opencs/model/world/infocollection.hpp @@ -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; diff --git a/apps/opencs/model/world/metadata.hpp b/apps/opencs/model/world/metadata.hpp index 330551b1e2..edc1785eaa 100644 --- a/apps/opencs/model/world/metadata.hpp +++ b/apps/opencs/model/world/metadata.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_METADATA_H #include +#include namespace ESM { @@ -13,7 +14,7 @@ namespace CSMWorld { struct MetaData { - std::string mId; + ESM::RefId mId; int mFormat; std::string mAuthor; diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 8ba70e80e3..4a12ee0268 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -252,10 +252,10 @@ namespace CSMWorld { ESM::Faction faction = record.get(); - std::map& reactions = faction.mReactions; + std::map& 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& reactions = faction.mReactions; + std::map& reactions = faction.mReactions; if (rowToRemove < 0 || rowToRemove >= static_cast(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::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>&>(nestedTable).mNestedTable; + = static_cast>&>(nestedTable).mNestedTable; record.setModified(faction); } @@ -293,7 +293,7 @@ namespace CSMWorld NestedTableWrapperBase* FactionReactionsAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper>(record.get().mReactions); + return new NestedTableWrapper>(record.get().mReactions); } QVariant FactionReactionsAdapter::getData( @@ -301,20 +301,20 @@ namespace CSMWorld { ESM::Faction faction = record.get(); - std::map& reactions = faction.mReactions; + std::map& reactions = faction.mReactions; if (subRowIndex < 0 || subRowIndex >= static_cast(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::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& reactions = faction.mReactions; + std::map& reactions = faction.mReactions; if (subRowIndex < 0 || subRowIndex >= static_cast(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::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(value.toInt()); diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index cfeac2500d..a7dfedc1fd 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -154,10 +154,10 @@ namespace CSMWorld { ESXRecordT raceOrBthSgn = record.get(); - std::vector& spells = raceOrBthSgn.mPowers.mList; + std::vector& 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& spells = raceOrBthSgn.mPowers.mList; + std::vector& spells = raceOrBthSgn.mPowers.mList; if (rowToRemove < 0 || rowToRemove >= static_cast(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>&>(nestedTable).mNestedTable; + = static_cast>&>(nestedTable).mNestedTable; record.setModified(raceOrBthSgn); } @@ -191,23 +191,23 @@ namespace CSMWorld NestedTableWrapperBase* table(const Record& record) const override { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper>(record.get().mPowers.mList); + return new NestedTableWrapper>(record.get().mPowers.mList); } QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override { ESXRecordT raceOrBthSgn = record.get(); - std::vector& spells = raceOrBthSgn.mPowers.mList; + std::vector& spells = raceOrBthSgn.mPowers.mList; if (subRowIndex < 0 || subRowIndex >= static_cast(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& spells = raceOrBthSgn.mPowers.mList; + std::vector& spells = raceOrBthSgn.mPowers.mList; if (subRowIndex < 0 || subRowIndex >= static_cast(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"); diff --git a/apps/opencs/model/world/pathgrid.cpp b/apps/opencs/model/world/pathgrid.cpp index 0852ad46fa..78191d9b58 100644 --- a/apps/opencs/model/world/pathgrid.cpp +++ b/apps/opencs/model/world/pathgrid.cpp @@ -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()); } } diff --git a/apps/opencs/model/world/pathgrid.hpp b/apps/opencs/model/world/pathgrid.hpp index 86f19c816c..853a4c0997 100644 --- a/apps/opencs/model/world/pathgrid.hpp +++ b/apps/opencs/model/world/pathgrid.hpp @@ -4,6 +4,7 @@ #include #include +#include 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>& cells); void load(ESM::ESMReader& esm, bool& isDeleted); diff --git a/apps/opencs/model/world/ref.hpp b/apps/opencs/model/world/ref.hpp index b572c4f01e..8e634d8106 100644 --- a/apps/opencs/model/world/ref.hpp +++ b/apps/opencs/model/world/ref.hpp @@ -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; diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 580fe166b6..37428a147a 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -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 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>(); // 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>(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::State_ModifiedOnly; record->mModified.blank(); - record->get().mId = id; + record->get().mId = ESM::RefId::stringRefId(id); record->get().mIdNum = extractIdNum(id); Collection>::appendRecord(std::move(record)); } +void CSMWorld::RefCollection::appendBlankRecord(const ESM::RefId& id, UniversalId::Type type) +{ + auto record = std::make_unique>(); + + record->mState = Record::State_ModifiedOnly; + record->mModified.blank(); + + record->get().mId = id; + record->get().mIdNum = extractIdNum(id.getRefIdString()); + + Collection>::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>(); @@ -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 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.get())->get().mIdNum, index)); @@ -318,7 +336,7 @@ void CSMWorld::RefCollection::appendRecord(std::unique_ptr record, U void CSMWorld::RefCollection::insertRecord(std::unique_ptr 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.get())->get().mIdNum; Collection>::insertRecord(std::move(record), index, type); // add records only diff --git a/apps/opencs/model/world/refcollection.hpp b/apps/opencs/model/world/refcollection.hpp index b31abf33e4..fe844cb0ed 100644 --- a/apps/opencs/model/world/refcollection.hpp +++ b/apps/opencs/model/world/refcollection.hpp @@ -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 record, UniversalId::Type type = UniversalId::Type_None); diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 83f495a41f..d18b790a70 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_REFIDADAPTER_H #include +#include /*! \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() }; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 82d92b9ab3..e387f52d12 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -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&>(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::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::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&>(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) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 75552ae7be..8854dfbf05 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -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 void BaseRefIdAdapter::setId(RecordBase& record, const std::string& id) { - (dynamic_cast&>(record).get().mId) = id; + (dynamic_cast&>(record).get().mId) = ESM::RefId::stringRefId(id); } template - std::string BaseRefIdAdapter::getId(const RecordBase& record) const + ESM::RefId BaseRefIdAdapter::getId(const RecordBase& record) const { return dynamic_cast&>(record).get().mId; } @@ -106,7 +106,7 @@ namespace CSMWorld = static_cast&>(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::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::setData(column, data, index, value); @@ -503,7 +503,7 @@ namespace CSMWorld data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::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(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&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT caster = record.get(); - std::vector& list = caster.mSpells.mList; + std::vector& 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&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT caster = record.get(); - std::vector& list = caster.mSpells.mList; + std::vector& list = caster.mSpells.mList; if (rowToRemove < 0 || rowToRemove >= static_cast(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>&>(nestedTable).mNestedTable; + = static_cast>&>(nestedTable).mNestedTable; record.setModified(caster); } @@ -1382,7 +1382,7 @@ namespace CSMWorld = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper>(record.get().mSpells.mList); + return new NestedTableWrapper>(record.get().mSpells.mList); } QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, @@ -1391,15 +1391,15 @@ namespace CSMWorld const Record& record = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); - const std::vector& list = record.get().mSpells.mList; + const std::vector& list = record.get().mSpells.mList; if (subRowIndex < 0 || subRowIndex >= static_cast(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& record = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT caster = record.get(); - std::vector& list = caster.mSpells.mList; + std::vector& list = caster.mSpells.mList; if (subRowIndex < 0 || subRowIndex >= static_cast(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(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& 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(value.toInt()); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 7c68d7619e..d3e16188e7 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -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 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 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 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 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 CSMWorld::RefIdCollection::getIds(bool listDeleted) const +std::vector CSMWorld::RefIdCollection::getIds(bool listDeleted) const { return mData.getIds(listDeleted); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 4f4849b9e5..45e3a65223 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -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 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 getIds(bool listDeleted) const override; + std::vector getIds(bool listDeleted) const override; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index d633744f2b..1d13e42866 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -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::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>::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::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::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::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 CSMWorld::RefIdData::getIds(bool listDeleted) const +std::vector CSMWorld::RefIdData::getIds(bool listDeleted) const { - std::vector ids; + std::vector ids; - for (std::map::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& CSMWorld::RefIdData::getStatics } void CSMWorld::RefIdData::insertRecord( - std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id) + std::unique_ptr record, CSMWorld::UniversalId::Type type, const ESM::RefId& id) { std::map::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 diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 513b3bdac9..2425cc89c0 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -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 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 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 - void RefIdDataContainer::appendRecord(const std::string& id, bool base) + void RefIdDataContainer::appendRecord(const ESM::RefId& id, bool base) { auto record = std::make_unique>(); @@ -157,7 +157,7 @@ namespace CSMWorld int numRecords = static_cast(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 - std::string RefIdDataContainer::getId(int index) const + ESM::RefId RefIdDataContainer::getId(int index) const { return mContainer.at(index)->get().mId; } @@ -262,14 +262,14 @@ namespace CSMWorld RefIdDataContainer mStatics; RefIdDataContainer mWeapons; - std::map mIndex; + std::map mIndex; std::map 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 record, CSMWorld::UniversalId::Type type, const std::string& id); + void insertRecord(std::unique_ptr 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 getIds(bool listDeleted = true) const; + std::vector getIds(bool listDeleted = true) const; ///< Return a sorted collection of all IDs /// /// \param listDeleted include deleted record in the list diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index c65ba7b510..ed233946a7 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -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& 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::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& regions) +void CSMWorld::RegionMap::updateRegions(const std::vector& regions) { - std::vector regions2(regions); + std::vector regions2(regions); - for (auto& region2 : regions2) - { - Misc::StringUtils::lowerCaseInPlace(region2); - } std::sort(regions2.begin(), regions2.end()); for (std::map::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::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 << "
"; - std::map::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::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 update; + std::vector update; const IdCollection& 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 update; + std::vector update; const IdCollection& 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 update; + std::vector update; const IdCollection& regions = mData.getRegions(); diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 9a7821e4b4..f93c45274f 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -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 mMap; CellCoordinates mMin; ///< inclusive CellCoordinates mMax; ///< exclusive - std::map mColours; ///< region ID, colour (RGBA) + std::map 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& regions); + void updateRegions(const std::vector& regions); ///< Update cells affected by the listed regions void updateSize(); diff --git a/apps/opencs/model/world/scriptcontext.cpp b/apps/opencs/model/world/scriptcontext.cpp index e7473d25be..e002baea47 100644 --- a/apps/opencs/model/world/scriptcontext.cpp +++ b/apps/opencs/model/world/scriptcontext.cpp @@ -53,9 +53,9 @@ char CSMWorld::ScriptContext::getGlobalType(const std::string& name) const return ' '; } -std::pair CSMWorld::ScriptContext::getMemberType(const std::string& name, const std::string& id) const +std::pair 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 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 CSMWorld::ScriptContext::getMemberType(const std::string& if (index == -1) return std::make_pair(' ', false); - std::map::iterator iter = mLocals.find(id2); + std::map::iterator iter = mLocals.find(id2.getRefIdString()); if (iter == mLocals.end()) { @@ -97,28 +97,24 @@ std::pair 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() diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index 1e1f411639..b25d232d7c 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -16,7 +16,7 @@ namespace CSMWorld class ScriptContext : public Compiler::Context { const Data& mData; - mutable std::vector mIds; + mutable std::vector mIds; mutable bool mIdsUpdated; mutable std::map 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 getMemberType(const std::string& name, const std::string& id) const override; + std::pair 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(); diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 4dc38c7aba..a4afa56706 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -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) diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 5db1f02f1e..dedf732478 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -5,6 +5,7 @@ #include #include +#include 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. diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index b5a7fd3e5f..c85a484e67 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -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) { diff --git a/apps/opencs/view/render/actor.hpp b/apps/opencs/view/render/actor.hpp index 9ebd9bf157..7fe14e4a20 100644 --- a/apps/opencs/view/render/actor.hpp +++ b/apps/opencs/view/render/actor.hpp @@ -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; diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index d1ce08d579..83c6a7c9ae 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -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(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(mData, mCellNode, mId, mCoordinates); - mCellWater = std::make_unique(mData, mCellNode, mId, mCoordinates); + mPathgrid = std::make_unique(mData, mCellNode, mId.getRefIdString(), mCoordinates); + mCellWater = std::make_unique(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) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 6cc9caf989..706d434fdb 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -44,7 +44,7 @@ namespace CSVRender class Cell { CSMWorld::Data& mData; - std::string mId; + ESM::RefId mId; osg::ref_ptr mCellNode; std::map mObjects; std::unique_ptr mTerrain; diff --git a/apps/opencs/view/render/cellwater.cpp b/apps/opencs/view/render/cellwater.cpp index e56ddd7238..7fe72f282c 100644 --- a/apps/opencs/view/render/cellwater.cpp +++ b/apps/opencs/view/render/cellwater.cpp @@ -131,7 +131,7 @@ namespace CSVRender { const CSMWorld::Record& cellRecord = cells.getRecord(row); - if (Misc::StringUtils::lowerCase(cellRecord.get().mId) == mId) + if (cellRecord.get().mId == ESM::RefId::stringRefId(mId)) updateCellData(cellRecord); } } diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index b980a96af7..f41bcb2a20 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -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::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 cellIndex diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 209916772c..436c410c84 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -8,6 +8,7 @@ #include #include +#include #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 mRootNode; osg::ref_ptr mBaseNode; osg::ref_ptr mOutline; diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index facd8a061d..8b96a9b376 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -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); diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp index f8d5eec346..c2321d10f7 100644 --- a/apps/opencs/view/render/pathgrid.cpp +++ b/apps/opencs/view/render/pathgrid.cpp @@ -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(*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(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::iterator row = mSelected.begin(); row != mSelected.end(); ++row) { - commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, static_cast(*row), parentColumn)); + commands.push(new CSMWorld::DeleteNestedCommand(*model, mId.getRefIdString(), static_cast(*row), parentColumn)); } // Fix/remove edges @@ -459,7 +459,7 @@ namespace CSVRender std::set>::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>::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)); } diff --git a/apps/opencs/view/render/pathgrid.hpp b/apps/opencs/view/render/pathgrid.hpp index e25f18ec0c..bcf1faef8e 100644 --- a/apps/opencs/view/render/pathgrid.hpp +++ b/apps/opencs/view/render/pathgrid.hpp @@ -11,7 +11,7 @@ #include "../../model/world/cellcoordinates.hpp" #include "../../model/world/subcellcollection.hpp" - +#include #include "tagbase.hpp" namespace osg @@ -92,7 +92,7 @@ namespace CSVRender private: CSMWorld::Data& mData; CSMWorld::SubCellCollection& mPathgridCollection; - std::string mId; + ESM::RefId mId; CSMWorld::CellCoordinates mCoords; bool mInterior; diff --git a/apps/opencs/view/render/terrainselection.cpp b/apps/opencs/view/render/terrainselection.cpp index 3e4813f7b4..b37ecd3ac3 100644 --- a/apps/opencs/view/render/terrainselection.cpp +++ b/apps/opencs/view/render/terrainselection.cpp @@ -310,7 +310,7 @@ bool CSVRender::TerrainSelection::noLandLoaded(const std::string& cellId) { CSMDoc::Document& document = mWorldspaceWidget->getDocument(); const CSMWorld::IdCollection& 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]; } diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index cf14bee901..36da957270 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -1340,7 +1340,7 @@ bool CSVRender::TerrainShapeMode::noLandLoaded(const std::string& cellId) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); const CSMWorld::IdCollection& 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) diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 71878ab533..c9ac27b177 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -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(); diff --git a/apps/opencs/view/widget/scenetooltexturebrush.cpp b/apps/opencs/view/widget/scenetooltexturebrush.cpp index 6b97f25772..51149b36ad 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.cpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.cpp @@ -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; diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 9a9c7ea9cf..38d071d06a 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -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); diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index 6e98fa695e..5f92eee82e 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -7,7 +7,7 @@ #include #include #include - +#include #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; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 02e1ba7bc4..b4457530e3 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -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; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 2b2afcbcf2..ad11a6c861 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -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); } diff --git a/apps/openmw_test_suite/esmloader/esmdata.cpp b/apps/openmw_test_suite/esmloader/esmdata.cpp index cfe4092970..5f91b5f195 100644 --- a/apps/openmw_test_suite/esmloader/esmdata.cpp +++ b/apps/openmw_test_suite/esmloader/esmdata.cpp @@ -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 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 settings; - EXPECT_THROW(EsmLoader::getGameSetting(settings, "setting"), std::runtime_error); + EXPECT_THROW(EsmLoader::getGameSetting(settings, ESM::RefId::stringRefId("setting")), std::runtime_error); } } diff --git a/apps/openmw_test_suite/lua/test_configuration.cpp b/apps/openmw_test_suite/lua/test_configuration.cpp index 61c96703dd..f213e31a1e 100644 --- a/apps/openmw_test_suite/lua/test_configuration.cpp +++ b/apps/openmw_test_suite/lua/test_configuration.cpp @@ -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 }); } diff --git a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp index 3a43db9a67..ae615fd4e5 100644 --- a/apps/openmw_test_suite/lua/test_scriptscontainer.cpp +++ b/apps/openmw_test_suite/lua/test_scriptscontainer.cpp @@ -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(); diff --git a/apps/openmw_test_suite/mwscript/test_utils.hpp b/apps/openmw_test_suite/mwscript/test_utils.hpp index 029d201a96..aa4cc046e6 100644 --- a/apps/openmw_test_suite/mwscript/test_utils.hpp +++ b/apps/openmw_test_suite/mwscript/test_utils.hpp @@ -29,11 +29,11 @@ namespace public: bool canDeclareLocals() const override { return true; } char getGlobalType(const std::string& name) const override { return ' '; } - std::pair getMemberType(const std::string& name, const std::string& id) const override + std::pair 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> 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 \ No newline at end of file +#endif diff --git a/apps/openmw_test_suite/mwworld/test_store.cpp b/apps/openmw_test_suite/mwworld/test_store.cpp index c3aa7ecf23..f869f0e448 100644 --- a/apps/openmw_test_suite/mwworld/test_store.cpp +++ b/apps/openmw_test_suite/mwworld/test_store.cpp @@ -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 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; diff --git a/components/esm3/loadinfo.cpp b/components/esm3/loadinfo.cpp index b6ef11d9f8..5ab955230e 100644 --- a/components/esm3/loadinfo.cpp +++ b/components/esm3/loadinfo.cpp @@ -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::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; diff --git a/components/esm3/loadinfo.hpp b/components/esm3/loadinfo.hpp index c50a327145..84db0d4f85 100644 --- a/components/esm3/loadinfo.hpp +++ b/components/esm3/loadinfo.hpp @@ -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