diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index a972d2a320..e3a1a0c725 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -214,7 +214,7 @@ namespace MWBase /// update activated quick key state (if action executing was delayed for some reason) virtual void updateActivatedQuickKey () = 0; - virtual std::string getSelectedSpell() = 0; + virtual const std::string& getSelectedSpell() = 0; virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0; virtual void setSelectedEnchantItem(const MWWorld::Ptr& item) = 0; virtual const MWWorld::Ptr& getSelectedEnchantItem() const = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index d570ffe515..54f5c16e65 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -224,7 +224,7 @@ namespace MWBase virtual void advanceTime (double hours, bool incremental = false) = 0; ///< Advance in-game time. - virtual std::string getMonthName (int month = -1) const = 0; + virtual std::string_view getMonthName(int month = -1) const = 0; ///< Return name of month (-1: current month) virtual MWWorld::TimeStamp getTimeStamp() const = 0; @@ -514,7 +514,7 @@ namespace MWBase /// Find default position inside exterior cell specified by name /// \return false if exterior with given name not exists, true otherwise - virtual bool findExteriorPosition(const std::string &name, ESM::Position &pos) = 0; + virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0; /// Find default position inside interior cell specified by name /// \return false if interior with given name not exists, true otherwise @@ -566,8 +566,7 @@ namespace MWBase /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) /// @note id must be lower case - virtual void teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id) = 0; + virtual void teleportToClosestMarker(const MWWorld::Ptr& ptr, std::string_view id) = 0; enum DetectionType { diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index fcdc5775d1..1104653c62 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -126,7 +126,7 @@ namespace MWGui std::string cellname = transport[i].mCellName; bool interior = true; const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); - if (cellname == "") + if (cellname.empty()) { MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); cellname = MWBase::Environment::get().getWorld()->getCellName(cell); @@ -170,7 +170,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); ESM::Position pos = *_sender->getUserData(); - std::string cellname = _sender->getUserString("Destination"); + const std::string& cellname = _sender->getUserString("Destination"); bool interior = _sender->getUserString("interior") == "y"; if (mPtr.getCell()->isExterior()) { @@ -187,7 +187,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); // Teleports any followers, too. - MWWorld::ActionTeleport action(interior ? cellname : "", pos, true); + MWWorld::ActionTeleport action(interior ? cellname : std::string_view{}, pos, true); action.execute(player); MWBase::Environment::get().getWindowManager()->fadeScreenOut(0); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 2fe3cefb45..f6671915f3 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -153,7 +153,7 @@ namespace MWGui onHourSliderChangedPosition(mHourSlider, 0); mHourSlider->setScrollPosition (0); - std::string month = MWBase::Environment::get().getWorld ()->getMonthName(); + std::string_view month = MWBase::Environment::get().getWorld ()->getMonthName(); int hour = static_cast(MWBase::Environment::get().getWorld()->getTimeStamp().getHour()); bool pm = hour >= 12; if (hour >= 13) hour -= 12; @@ -161,7 +161,7 @@ namespace MWGui ESM::EpochTimeStamp currentDate = MWBase::Environment::get().getWorld()->getEpochTimeStamp(); std::string daysPassed = Misc::StringUtils::format("(#{sDay} %i)", MWBase::Environment::get().getWorld()->getTimeStamp().getDay()); - std::string formattedHour(pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); + std::string_view formattedHour(pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); std::string dateTimeText = Misc::StringUtils::format("%i %s %s %i %s", currentDate.mDay, month, daysPassed, hour, formattedHour); mDateTimeText->setCaptionWithReplacing (dateTimeText); } @@ -195,7 +195,7 @@ namespace MWGui MWWorld::Ptr player = world->getPlayerPtr(); if (mSleeping && player.getCell()->isExterior()) { - std::string regionstr = player.getCell()->getCell()->mRegion; + const std::string& regionstr = player.getCell()->getCell()->mRegion; if (!regionstr.empty()) { const ESM::Region *region = world->getStore().get().find (regionstr); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index ad15831098..14a7f89115 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -242,7 +242,7 @@ namespace MWGui /// update activated quick key state (if action executing was delayed for some reason) void updateActivatedQuickKey () override; - std::string getSelectedSpell() override { return mSelectedSpell; } + const std::string& getSelectedSpell() override { return mSelectedSpell; } void setSelectedSpell(const std::string& spellId, int successChancePercent) override; void setSelectedEnchantItem(const MWWorld::Ptr& item) override; const MWWorld::Ptr& getSelectedEnchantItem() const override; diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 3092363537..2def2696bb 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -299,7 +299,7 @@ namespace MWMechanics const CreatureStats& stats = actor.getClass().getCreatureStats(actor); const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - std::string selectedSpellId = stats.getSpells().getSelectedSpell(); + const std::string& selectedSpellId = stats.getSpells().getSelectedSpell(); MWWorld::Ptr selectedEnchItem; MWWorld::Ptr activeWeapon, activeAmmo; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 597a0c143c..9ee7d5097e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -56,7 +56,7 @@ namespace { -std::string getBestAttack (const ESM::Weapon* weapon) +std::string_view getBestAttack(const ESM::Weapon* weapon) { int slash = weapon->mData.mSlash[0] + weapon->mData.mSlash[1]; int chop = weapon->mData.mChop[0] + weapon->mData.mChop[1]; @@ -104,7 +104,7 @@ MWMechanics::CharacterState hitStateToDeathState (MWMechanics::CharacterState st } // Converts a movement state to its equivalent base animation group as long as it is a movement state. -std::string movementStateToAnimGroup(MWMechanics::CharacterState state) +std::string_view movementStateToAnimGroup(MWMechanics::CharacterState state) { using namespace MWMechanics; switch (state) @@ -143,7 +143,7 @@ std::string movementStateToAnimGroup(MWMechanics::CharacterState state) } // Converts a death state to its equivalent animation group as long as it is a death state. -std::string deathStateToAnimGroup(MWMechanics::CharacterState state) +std::string_view deathStateToAnimGroup(MWMechanics::CharacterState state) { using namespace MWMechanics; switch (state) @@ -350,8 +350,8 @@ void CharacterController::refreshHitRecoilAnims() return; MWRender::Animation::AnimPriority priority(Priority_Knockdown); - std::string startKey = "start"; - std::string stopKey = "stop"; + std::string_view startKey = "start"; + std::string_view stopKey = "stop"; if (knockout) { mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut; @@ -563,15 +563,16 @@ void CharacterController::refreshMovementAnims(CharacterState movement, bool for if (movement == mMovementState && !force) return; - std::string movementAnimName = movementStateToAnimGroup(movement); + std::string_view movementAnimGroup = movementStateToAnimGroup(movement); - if (movementAnimName.empty()) + if (movementAnimGroup.empty()) { if (!mCurrentMovement.empty()) resetCurrentIdleState(); resetCurrentMovementState(); return; } + std::string movementAnimName{movementAnimGroup}; mMovementState = movement; std::string::size_type swimpos = movementAnimName.find("swim"); @@ -644,7 +645,7 @@ void CharacterController::refreshMovementAnims(CharacterState movement, bool for if (mPtr.getClass().getType() == ESM::Creature::sRecordId && !(mPtr.get()->mBase->mFlags & ESM::Creature::Flies)) { CharacterState walkState = runStateToWalkState(mMovementState); - std::string anim = movementStateToAnimGroup(walkState); + std::string_view anim = movementStateToAnimGroup(walkState); mMovementAnimSpeed = mAnimation->getVelocity(anim); if (mMovementAnimSpeed <= 1.0f) @@ -1009,19 +1010,21 @@ void CharacterController::handleTextKey(std::string_view groupname, SceneUtil::T { std::multimap::const_iterator hitKey = key; - std::string hitKeyName = std::string(groupname) + ": hit"; - std::string stopKeyName = std::string(groupname) + ": stop"; // Not all animations have a hit key defined. If there is none, the hit happens with the start key. bool hasHitKey = false; while (hitKey != map.end()) { - if (hitKey->second == hitKeyName) + if (hitKey->second.starts_with(groupname)) { - hasHitKey = true; - break; + std::string_view suffix = std::string_view(hitKey->second).substr(groupname.size()); + if (suffix == ": hit") + { + hasHitKey = true; + break; + } + if (suffix == ": stop") + break; } - if (hitKey->second == stopKeyName) - break; ++hitKey; } if (!hasHitKey) @@ -1383,10 +1386,10 @@ bool CharacterController::updateWeaponState() // For the player, set the spell we want to cast // This has to be done at the start of the casting animation, // *not* when selecting a spell in the GUI (otherwise you could change the spell mid-animation) - std::string selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); + const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); stats.getSpells().setSelectedSpell(selectedSpell); } - std::string spellid = stats.getSpells().getSelectedSpell(); + std::string_view spellid = stats.getSpells().getSelectedSpell(); bool isMagicItem = false; // Play hand VFX and allow castSpell use (assuming an animation is going to be played) if spellcasting is successful. @@ -1565,7 +1568,7 @@ bool CharacterController::updateWeaponState() if (!target.isEmpty()) { - std::string resultMessage, resultSound; + std::string_view resultMessage, resultSound; if (mWeapon.getType() == ESM::Lockpick::sRecordId) Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound); else if (mWeapon.getType() == ESM::Probe::sRecordId) @@ -2082,7 +2085,7 @@ void CharacterController::update(float duration) if (playLandingSound) { - std::string sound; + std::string_view sound; osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr)) sound = "DefaultLandWater"; @@ -2425,7 +2428,7 @@ bool CharacterController::isPersistentAnimPlaying() const return false; } -bool CharacterController::isAnimPlaying(const std::string &groupName) const +bool CharacterController::isAnimPlaying(std::string_view groupName) const { if(mAnimation == nullptr) return false; @@ -2714,7 +2717,7 @@ void CharacterController::setHeadTrackTarget(const MWWorld::ConstPtr &target) void CharacterController::playSwishSound() const { - std::string soundId = "Weapon Swish"; + std::string_view soundId = "Weapon Swish"; float volume = 0.98f + mAttackStrength * 0.02f; float pitch = 0.75f + mAttackStrength * 0.4f; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 441815e834..3f7dcd1114 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -262,7 +262,7 @@ public: bool playGroup(std::string_view groupname, int mode, int count, bool persist=false); void skipAnim(); - bool isAnimPlaying(const std::string &groupName) const; + bool isAnimPlaying(std::string_view groupName) const; enum KillResult { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 732e0fccff..bde5ad0225 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -533,7 +533,7 @@ namespace MWMechanics std::map::const_iterator playerFactionIt = playerStats.getFactionRanks().begin(); for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt) { - std::string itFaction = playerFactionIt->first; + const std::string& itFaction = playerFactionIt->first; // Ignore the faction, if a player was expelled from it. if (playerStats.getExpelled(itFaction)) @@ -839,12 +839,8 @@ namespace MWMechanics for (const ESM::GameSetting ¤tSetting : gameSettings) { - std::string currentGMSTID = currentSetting.mId; - Misc::StringUtils::lowerCaseInPlace(currentGMSTID); - // Don't bother checking this GMST if it's not a sMagicBound* one. - const std::string& toFind = "smagicbound"; - if (currentGMSTID.compare(0, toFind.length(), toFind) != 0) + if (!Misc::StringUtils::ciStartsWith(currentSetting.mId, "smagicbound")) continue; // All sMagicBound* GMST's should be of type string @@ -970,7 +966,7 @@ namespace MWMechanics return false; const OwnerMap& owners = it->second; - const std::string ownerid = ptr.getCellRef().getRefId(); + const std::string& ownerid = ptr.getCellRef().getRefId(); OwnerMap::const_iterator ownerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); if (ownerFound != owners.end()) return true; diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index bfb48dd754..d41bf817a3 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -26,7 +26,7 @@ namespace MWMechanics } void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, - std::string& resultMessage, std::string& resultSound) + std::string_view& resultMessage, std::string_view& resultSound) { if (lock.getCellRef().getLockLevel() <= 0 || lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || @@ -72,7 +72,7 @@ namespace MWMechanics } void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, - std::string& resultMessage, std::string& resultSound) + std::string_view& resultMessage, std::string_view& resultSound) { if (trap.getCellRef().getTrap().empty()) return; diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index f3efb04ed8..b555dcc299 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -13,9 +13,9 @@ namespace MWMechanics Security (const MWWorld::Ptr& actor); void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, - std::string& resultMessage, std::string& resultSound); + std::string_view& resultMessage, std::string_view& resultSound); void probeTrap (const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, - std::string& resultMessage, std::string& resultSound); + std::string_view& resultMessage, std::string_view& resultSound); private: float mAgility, mLuck, mSecuritySkill, mFatigueTerm; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 58bd76ca49..97530ce293 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -435,7 +435,7 @@ namespace MWMechanics return true; } - void CastSpell::playSpellCastingEffects(const std::string &spellid, bool enchantment) + void CastSpell::playSpellCastingEffects(std::string_view spellid, bool enchantment) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (enchantment) diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 8dfd2b3f0c..835c3b6633 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -54,7 +54,7 @@ namespace MWMechanics /// @note Auto detects if spell, ingredient or potion bool cast (const std::string& id); - void playSpellCastingEffects(const std::string &spellid, bool enchantment); + void playSpellCastingEffects(std::string_view spellid, bool enchantment); /// Launch a bolt with the given effects. void launchMagicBolt (); diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index 509695c4e7..b1178fa5b2 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -428,7 +428,7 @@ void applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, co invalid = true; else if (world->isTeleportingEnabled()) { - auto marker = (effect.mEffectId == ESM::MagicEffect::DivineIntervention) ? "divinemarker" : "templemarker"; + std::string_view marker = (effect.mEffectId == ESM::MagicEffect::DivineIntervention) ? "divinemarker" : "templemarker"; world->teleportToClosestMarker(target, marker); if(!caster.isEmpty()) { @@ -464,7 +464,10 @@ void applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, co world->getPlayer().getMarkedPosition(markedCell, markedPosition); if (markedCell) { - MWWorld::ActionTeleport action(markedCell->isExterior() ? "" : markedCell->getCell()->mName, markedPosition, false); + std::string_view dest; + if (!markedCell->isExterior()) + dest = markedCell->getCell()->mName; + MWWorld::ActionTeleport action(dest, markedPosition, false); action.execute(target); if(!caster.isEmpty()) { diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index b6ca74ef6b..2f81be6d36 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -106,7 +106,7 @@ namespace MWMechanics mSelectedSpell = spellId; } - const std::string Spells::getSelectedSpell() const + const std::string& Spells::getSelectedSpell() const { return mSelectedSpell; } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index ff803a9ec2..2dd8706b1c 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -87,7 +87,7 @@ namespace MWMechanics void setSelectedSpell (const std::string& spellId); ///< This function does not verify, if the spell is available. - const std::string getSelectedSpell() const; + const std::string& getSelectedSpell() const; ///< May return an empty string. bool hasCommonDisease() const; diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index 0cf2e26f47..f17b6773e8 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -27,9 +27,9 @@ namespace MWMechanics || (effectId >= ESM::MagicEffect::SummonFabricant && effectId <= ESM::MagicEffect::SummonCreature05)); } - std::string getSummonedCreature(int effectId) + std::string_view getSummonedCreature(int effectId) { - static const std::map summonMap + static const std::map summonMap { {ESM::MagicEffect::SummonAncestralGhost, "sMagicAncestralGhostID"}, {ESM::MagicEffect::SummonBonelord, "sMagicBonelordID"}, @@ -58,12 +58,12 @@ namespace MWMechanics auto it = summonMap.find(effectId); if (it != summonMap.end()) return MWBase::Environment::get().getWorld()->getStore().get().find(it->second)->mValue.getString(); - return std::string(); + return {}; } int summonCreature(int effectId, const MWWorld::Ptr& summoner) { - std::string creatureID = getSummonedCreature(effectId); + std::string_view creatureID = getSummonedCreature(effectId); int creatureActorId = -1; if (!creatureID.empty()) { diff --git a/apps/openmw/mwmechanics/summoning.hpp b/apps/openmw/mwmechanics/summoning.hpp index aff88bec13..62a5c725a3 100644 --- a/apps/openmw/mwmechanics/summoning.hpp +++ b/apps/openmw/mwmechanics/summoning.hpp @@ -1,7 +1,7 @@ #ifndef OPENMW_MECHANICS_SUMMONING_H #define OPENMW_MECHANICS_SUMMONING_H -#include +#include #include #include @@ -15,7 +15,7 @@ namespace MWMechanics { bool isSummoningEffect(int effectId); - std::string getSummonedCreature(int effectId); + std::string_view getSummonedCreature(int effectId); void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair& summon); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7aab3ec1d9..9b9ad0f770 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -166,13 +166,20 @@ namespace } }; - float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, - const osg::Vec3f& accum, const std::string &groupname) + bool equalsParts(std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {}) + { + if (value.starts_with(s1)) + { + value = value.substr(s1.size()); + if(value.starts_with(s2)) + return value.substr(s2.size()) == s3; + } + return false; + } + + float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, + const osg::Vec3f& accum, std::string_view groupname) { - const std::string start = groupname+": start"; - const std::string loopstart = groupname+": loop start"; - const std::string loopstop = groupname+": loop stop"; - const std::string stop = groupname+": stop"; float starttime = std::numeric_limits::max(); float stoptime = 0.0f; @@ -185,7 +192,7 @@ namespace auto keyiter = keys.rbegin(); while(keyiter != keys.rend()) { - if(keyiter->second == start || keyiter->second == loopstart) + if(equalsParts(keyiter->second, groupname, ": start") || equalsParts(keyiter->second, groupname, ": loop start")) { starttime = keyiter->first; break; @@ -195,9 +202,9 @@ namespace keyiter = keys.rbegin(); while(keyiter != keys.rend()) { - if (keyiter->second == stop) + if (equalsParts(keyiter->second, groupname, ": stop")) stoptime = keyiter->first; - else if (keyiter->second == loopstop) + else if (equalsParts(keyiter->second, groupname, ": loop stop")) { stoptime = keyiter->first; break; @@ -868,24 +875,13 @@ namespace MWRender break; } - auto equals = [] (std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {}) - { - if (value.starts_with(s1)) - { - value = value.substr(s1.size()); - if(value.starts_with(s2)) - return value.substr(s2.size()) == s3; - } - return false; - }; - auto startkey = groupend; - while(startkey != keys.rend() && !equals(startkey->second, groupname, ": ", start)) + while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": ", start)) ++startkey; if(startkey == keys.rend() && start == "loop start") { startkey = groupend; - while(startkey != keys.rend() && !equals(startkey->second, groupname, ": start")) + while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": start")) ++startkey; } if(startkey == keys.rend()) @@ -897,7 +893,7 @@ namespace MWRender // We have to ignore extra garbage at the end. // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". // Why, just why? :( - && !equals(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop)) + && !equalsParts(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop)) ++stopkey; if(stopkey == keys.rend()) return false; @@ -929,9 +925,9 @@ namespace MWRender if (key->first > state.getTime()) continue; - if (equals(key->second, groupname, ": loop start")) + if (equalsParts(key->second, groupname, ": loop start")) state.mLoopStartTime = key->first; - else if (equals(key->second, groupname, ": loop stop")) + else if (equalsParts(key->second, groupname, ": loop stop")) state.mLoopStopTime = key->first; } @@ -1081,7 +1077,7 @@ namespace MWRender resetActiveGroups(); } - float Animation::getVelocity(const std::string &groupname) const + float Animation::getVelocity(std::string_view groupname) const { if (!mAccumRoot) return 0.0f; @@ -1137,7 +1133,7 @@ namespace MWRender } } - mAnimVelocities.insert(std::make_pair(groupname, velocity)); + mAnimVelocities.emplace(groupname, velocity); return velocity; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index a958429f39..55f15e3a69 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -285,7 +285,7 @@ protected: float mAlpha; - mutable std::map mAnimVelocities; + mutable std::map> mAnimVelocities; osg::ref_ptr mLightListCallback; @@ -451,7 +451,7 @@ public: void disable(std::string_view groupname); /** Retrieves the velocity (in units per second) that the animation will move. */ - float getVelocity(const std::string &groupname) const; + float getVelocity(std::string_view groupname) const; virtual osg::Vec3f runAnimation(float duration); diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index a8d918e6cb..444e2dbced 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -87,7 +87,7 @@ namespace MWScript void execute (Interpreter::Runtime& runtime) override { - std::string cell{runtime.getStringLiteral(runtime[0].mInteger)}; + std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); ESM::Position pos; @@ -96,7 +96,7 @@ namespace MWScript if (world->findExteriorPosition(cell, pos)) { - MWWorld::ActionTeleport("", pos, false).execute(playerPtr); + MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); world->adjustPosition(playerPtr, false); } else @@ -130,7 +130,7 @@ namespace MWScript pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - MWWorld::ActionTeleport("", pos, false).execute(playerPtr); + MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); world->adjustPosition(playerPtr, false); } }; diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index f240747f6e..36669f34ac 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -114,7 +114,7 @@ namespace MWScript void execute (Interpreter::Runtime& runtime) override { - std::string cell = ::Misc::StringUtils::lowerCase(runtime.getStringLiteral(runtime[0].mInteger)); + std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); // "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's House as well." @@ -127,9 +127,7 @@ namespace MWScript for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { - std::string name = it->mName; - ::Misc::StringUtils::lowerCaseInPlace(name); - if (name.length() >= cell.length() && name.substr(0, cell.length()) == cell) + if (Misc::StringUtils::ciStartsWith(it->mName, cell)) winMgr->addVisitedLocation(it->mName, it->getGridX(), it->getGridY()); } } @@ -144,11 +142,10 @@ namespace MWScript const MWWorld::Store &cells = MWBase::Environment::get().getWorld ()->getStore().get(); - MWWorld::Store::iterator it = cells.extBegin(); - for (; it != cells.extEnd(); ++it) + for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { - std::string name = it->mName; - if (name != "") + const std::string& name = it->mName; + if (!name.empty()) MWBase::Environment::get().getWindowManager()->addVisitedLocation ( name, it->getGridX(), diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index cb289d83b0..e91b211006 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -591,7 +591,7 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - std::string creature{runtime.getStringLiteral(runtime[0].mInteger)}; + std::string_view creature = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); std::string_view gem = runtime.getStringLiteral(runtime[0].mInteger); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 76f117f4ce..fa48ae7e99 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -757,7 +757,7 @@ namespace MWScript { MWWorld::ConstPtr ptr = R()(runtime, false); - std::string factionId; + std::string_view factionId; if (arg0==1) { @@ -790,7 +790,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - std::string factionId; + std::string_view factionId; if (arg0==1) { @@ -822,7 +822,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - std::string factionId; + std::string_view factionId; if (arg0==1) { diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index eab1ff59da..8b6c9f2ef9 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -336,7 +336,7 @@ namespace MWSound { std::vector filelist; // Is there an ini setting for this filename or something? - std::string filename = "music/special/morrowind title.mp3"; + std::string_view filename = "music/special/morrowind title.mp3"; if (mVFS->exists(filename)) { filelist.emplace_back(filename); diff --git a/apps/openmw/mwworld/actionharvest.cpp b/apps/openmw/mwworld/actionharvest.cpp index 161d1f4e7e..aecb62a3ff 100644 --- a/apps/openmw/mwworld/actionharvest.cpp +++ b/apps/openmw/mwworld/actionharvest.cpp @@ -53,9 +53,9 @@ namespace MWWorld std::ostringstream stream; int lineCount = 0; const static int maxLines = 10; - for (auto & pair : takenMap) + for (const auto& pair : takenMap) { - std::string itemName = pair.first; + const std::string& itemName = pair.first; int itemCount = pair.second; lineCount++; if (lineCount == maxLines) diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 72cafc4eed..17370671a1 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -16,7 +16,7 @@ namespace MWWorld { - ActionTeleport::ActionTeleport (const std::string& cellName, + ActionTeleport::ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers) : Action (true), mCellName (cellName), mPosition (position), mTeleportFollowers(teleportFollowers) { diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index fcbf59a203..b467e1db0f 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -26,7 +27,7 @@ namespace MWWorld /// If cellName is empty, an exterior cell is assumed. /// @param teleportFollowers Whether to teleport any following actors of the target actor as well. - ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers); + ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers); /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the output, /// e.g. so that the teleport action can calm them. diff --git a/apps/openmw/mwworld/cellref.cpp b/apps/openmw/mwworld/cellref.cpp index 69b6a94da8..6e0e5351dd 100644 --- a/apps/openmw/mwworld/cellref.cpp +++ b/apps/openmw/mwworld/cellref.cpp @@ -136,7 +136,7 @@ namespace MWWorld } } - void CellRef::setSoul(const std::string &soul) + void CellRef::setSoul(std::string_view soul) { if (soul != mCellRef.mSoul) { diff --git a/apps/openmw/mwworld/cellref.hpp b/apps/openmw/mwworld/cellref.hpp index c7842919a1..8f11542187 100644 --- a/apps/openmw/mwworld/cellref.hpp +++ b/apps/openmw/mwworld/cellref.hpp @@ -1,6 +1,8 @@ #ifndef OPENMW_MWWORLD_CELLREF_H #define OPENMW_MWWORLD_CELLREF_H +#include + #include namespace ESM @@ -87,7 +89,7 @@ namespace MWWorld // ID of creature trapped in this soul gem const std::string& getSoul() const { return mCellRef.mSoul; } - void setSoul(const std::string& soul); + void setSoul(std::string_view soul); // The faction that owns this object (and will get angry if // you take it and are not a faction member) diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 457e142e18..3ad8a1ee38 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -93,7 +93,7 @@ void MWWorld::Cells::clear() mIdCacheIndex = 0; } -MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, CellStore& cellStore) +MWWorld::Ptr MWWorld::Cells::getPtrAndCache(std::string_view name, CellStore& cellStore) { Ptr ptr = getPtr (name, cellStore); @@ -226,7 +226,7 @@ MWWorld::CellStore *MWWorld::Cells::getCell (const ESM::CellId& id) return getInterior (id.mWorldspace); } -MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, CellStore& cell, +MWWorld::Ptr MWWorld::Cells::getPtr(std::string_view name, CellStore& cell, bool searchInContainers) { if (cell.getState()==CellStore::State_Unloaded) @@ -342,7 +342,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr(CellStore& cellStore, const std::string& id, return cellStore.searchViaRefNum(refNum); } -void MWWorld::Cells::getExteriorPtrs(const std::string &name, std::vector &out) +void MWWorld::Cells::getExteriorPtrs(std::string_view name, std::vector& out) { const MWWorld::Store &cells = mStore.get(); for (MWWorld::Store::iterator iter = cells.extBegin(); iter != cells.extEnd(); ++iter) diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index b377d79803..65567912f3 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -42,7 +42,7 @@ namespace MWWorld CellStore *getCellStore (const ESM::Cell *cell); - Ptr getPtrAndCache (const std::string& name, CellStore& cellStore); + Ptr getPtrAndCache(std::string_view name, CellStore& cellStore); Ptr getPtr(CellStore& cellStore, const std::string& id, const ESM::RefNum& refNum); @@ -60,7 +60,7 @@ namespace MWWorld CellStore *getCell (const ESM::CellId& id); - Ptr getPtr (const std::string& name, CellStore& cellStore, bool searchInContainers = false); + Ptr getPtr(std::string_view name, CellStore& cellStore, bool searchInContainers = false); ///< \param searchInContainers Only affect loaded cells. /// @note name must be lower case @@ -75,7 +75,7 @@ namespace MWWorld /// Get all Ptrs referencing \a name in exterior cells /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. /// @note name must be lower case - void getExteriorPtrs (const std::string& name, std::vector& out); + void getExteriorPtrs(std::string_view name, std::vector& out); /// Get all Ptrs referencing \a name in interior cells /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index eb674e247a..fd4c6161e9 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -36,7 +36,7 @@ namespace { template - MWWorld::Ptr searchInContainerList (MWWorld::CellRefList& containerList, const std::string& id) + MWWorld::Ptr searchInContainerList(MWWorld::CellRefList& containerList, std::string_view id) { for (typename MWWorld::CellRefList::List::iterator iter (containerList.mList.begin()); iter!=containerList.mList.end(); ++iter) @@ -420,7 +420,7 @@ namespace MWWorld return mHasState; } - bool CellStore::hasId (const std::string& id) const + bool CellStore::hasId(std::string_view id) const { if (mState==State_Unloaded) return false; @@ -435,10 +435,10 @@ namespace MWWorld struct SearchVisitor { PtrType mFound; - const std::string *mIdToFind; + std::string_view mIdToFind; bool operator()(const PtrType& ptr) { - if (ptr.getCellRef().getRefId() == *mIdToFind) + if (ptr.getCellRef().getRefId() == mIdToFind) { mFound = ptr; return false; @@ -447,18 +447,18 @@ namespace MWWorld } }; - Ptr CellStore::search (const std::string& id) + Ptr CellStore::search(std::string_view id) { SearchVisitor searchVisitor; - searchVisitor.mIdToFind = &id; + searchVisitor.mIdToFind = id; forEach(searchVisitor); return searchVisitor.mFound; } - ConstPtr CellStore::searchConst (const std::string& id) const + ConstPtr CellStore::searchConst(std::string_view id) const { SearchVisitor searchVisitor; - searchVisitor.mIdToFind = &id; + searchVisitor.mIdToFind = id; forEachConst(searchVisitor); return searchVisitor.mFound; } @@ -676,7 +676,7 @@ namespace MWWorld return (mCell->mData.mFlags & ESM::Cell::QuasiEx) != 0; } - Ptr CellStore::searchInContainer (const std::string& id) + Ptr CellStore::searchInContainer(std::string_view id) { bool oldState = mHasState; diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 5132ef4207..72d17b40dd 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -224,17 +225,17 @@ namespace MWWorld bool hasState() const; ///< Does this cell have state that needs to be stored in a saved game file? - bool hasId (const std::string& id) const; + bool hasId(std::string_view id) const; ///< May return true for deleted IDs when in preload state. Will return false, if cell is /// unloaded. /// @note Will not account for moved references which may exist in Loaded state. Use search() instead if the cell is loaded. - Ptr search (const std::string& id); + Ptr search(std::string_view id); ///< Will return an empty Ptr if cell is not loaded. Does not check references in /// containers. /// @note Triggers CellStore hasState flag. - ConstPtr searchConst (const std::string& id) const; + ConstPtr searchConst(std::string_view id) const; ///< Will return an empty Ptr if cell is not loaded. Does not check references in /// containers. /// @note Does not trigger CellStore hasState flag. @@ -372,7 +373,7 @@ namespace MWWorld bool isQuasiExterior() const; - Ptr searchInContainer (const std::string& id); + Ptr searchInContainer(std::string_view id); void loadState (const ESM::CellState& state); diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index ab55047756..f1288ee548 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -56,15 +56,13 @@ namespace } template - MWWorld::Ptr searchId (MWWorld::CellRefList& list, const std::string& id, - MWWorld::ContainerStore *store) + MWWorld::Ptr searchId(MWWorld::CellRefList& list, std::string_view id, MWWorld::ContainerStore* store) { store->resolve(); - std::string id2 = Misc::StringUtils::lowerCase (id); for (MWWorld::LiveCellRef& liveCellRef : list.mList) { - if (Misc::StringUtils::ciEqual(liveCellRef.mBase->mId, id2) && liveCellRef.mData.getCount()) + if (Misc::StringUtils::ciEqual(liveCellRef.mBase->mId, id) && liveCellRef.mData.getCount()) { MWWorld::Ptr ptr(&liveCellRef, nullptr); ptr.setContainerStore (store); @@ -760,7 +758,7 @@ MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const std::string& id) return item; } -MWWorld::Ptr MWWorld::ContainerStore::search (const std::string& id) +MWWorld::Ptr MWWorld::ContainerStore::search(std::string_view id) { resolve(); { diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 8bbd32af0d..f7f569ec97 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -240,7 +240,7 @@ namespace MWWorld Ptr findReplacement(const std::string& id); ///< Returns replacement for object with given id. Prefer used items (with low durability left). - Ptr search (const std::string& id); + Ptr search(std::string_view id); virtual void writeState (ESM::InventoryState& state) const; diff --git a/apps/openmw/mwworld/datetimemanager.cpp b/apps/openmw/mwworld/datetimemanager.cpp index 67d1ce1fbc..1f62a016fd 100644 --- a/apps/openmw/mwworld/datetimemanager.cpp +++ b/apps/openmw/mwworld/datetimemanager.cpp @@ -139,16 +139,16 @@ namespace MWWorld globalVariables["year"].setInteger(mYear); } - std::string DateTimeManager::getMonthName(int month) const + std::string_view DateTimeManager::getMonthName(int month) const { if (month == -1) month = mMonth; const int months = 12; if (month < 0 || month >= months) - return std::string(); + return {}; - static const char *monthNames[months] = + static const std::string_view monthNames[months] = { "sMonthMorningstar", "sMonthSunsdawn", "sMonthFirstseed", "sMonthRainshand", "sMonthSecondseed", "sMonthMidyear", "sMonthSunsheight", "sMonthLastseed", diff --git a/apps/openmw/mwworld/datetimemanager.hpp b/apps/openmw/mwworld/datetimemanager.hpp index e48eec5184..2c3df40117 100644 --- a/apps/openmw/mwworld/datetimemanager.hpp +++ b/apps/openmw/mwworld/datetimemanager.hpp @@ -1,7 +1,7 @@ #ifndef GAME_MWWORLD_DATETIMEMANAGER_H #define GAME_MWWORLD_DATETIMEMANAGER_H -#include +#include namespace ESM { @@ -27,7 +27,7 @@ namespace MWWorld void setMonth(int month); public: - std::string getMonthName(int month) const; + std::string_view getMonthName(int month) const; TimeStamp getTimeStamp() const; ESM::EpochTimeStamp getEpochTimeStamp() const; float getTimeScaleFactor() const; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 1435235fa0..0dba4860f5 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -231,8 +231,7 @@ namespace } catch (const std::exception& e) { - std::string error ("failed to render '" + ptr.getCellRef().getRefId() + "': "); - Log(Debug::Error) << error + e.what(); + Log(Debug::Error) << "failed to render '" << ptr.getCellRef().getRefId() << "': " << e.what(); } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 3150341876..a98e1b841d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1,5 +1,7 @@ #include "worldimp.hpp" +#include + #include #include #include @@ -665,7 +667,7 @@ namespace MWWorld return mGlobalVariables.getType (name); } - std::string World::getMonthName (int month) const + std::string_view World::getMonthName(int month) const { return mCurrentDate->getMonthName(month); } @@ -1418,7 +1420,10 @@ namespace MWWorld esmPos.pos[0] = traced.x(); esmPos.pos[1] = traced.y(); esmPos.pos[2] = traced.z(); - MWWorld::ActionTeleport(actor.getCell()->isExterior() ? "" : actor.getCell()->getCell()->mName, esmPos, false).execute(actor); + std::string_view cell; + if (!actor.getCell()->isExterior()) + cell = actor.getCell()->getCell()->mName; + MWWorld::ActionTeleport(cell, esmPos, false).execute(actor); } } @@ -1860,7 +1865,7 @@ namespace MWWorld void World::preloadSpells() { - std::string selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); + const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); if (!selectedSpell.empty()) { const ESM::Spell* spell = mStore.get().search(selectedSpell); @@ -2839,29 +2844,29 @@ namespace MWWorld return false; } - bool World::findExteriorPosition(const std::string &name, ESM::Position &pos) + bool World::findExteriorPosition(std::string_view name, ESM::Position& pos) { pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; const ESM::Cell *ext = getExterior(name); - - if (!ext && name.find(',') != std::string::npos) { - try { - int x = std::stoi(name.substr(0, name.find(','))); - int y = std::stoi(name.substr(name.find(',')+1)); - ext = getExterior(x, y)->getCell(); - } - catch (const std::invalid_argument&) + if (!ext) + { + size_t comma = name.find(','); + if (comma != std::string::npos) { - // This exception can be ignored, as this means that name probably refers to a interior cell instead of comma separated coordinates - } - catch (const std::out_of_range&) - { - throw std::runtime_error("Cell coordinates out of range."); + int x, y; + std::from_chars_result xResult = std::from_chars(name.data(), name.data() + comma, x); + std::from_chars_result yResult = std::from_chars(name.data() + comma + 1, name.data() + name.size(), y); + if (xResult.ec == std::errc::result_out_of_range || yResult.ec == std::errc::result_out_of_range) + throw std::runtime_error("Cell coordinates out of range."); + else if (xResult.ec == std::errc{} && yResult.ec == std::errc{}) + ext = getExterior(x, y)->getCell(); + // ignore std::errc::invalid_argument, as this means that name probably refers to a interior cell instead of comma separated coordinates } } - if (ext) { + if (ext) + { int x = ext->getGridX(); int y = ext->getGridY(); indexToPosition(x, y, pos.pos[0], pos.pos[1], true); @@ -2977,7 +2982,7 @@ namespace MWWorld MWWorld::SpellCastState result = MWWorld::SpellCastState::Success; bool isPlayer = (actor == getPlayerPtr()); - std::string selectedSpell = stats.getSpells().getSelectedSpell(); + const std::string& selectedSpell = stats.getSpells().getSelectedSpell(); if (!selectedSpell.empty()) { @@ -3108,7 +3113,7 @@ namespace MWWorld } } - std::string selectedSpell = stats.getSpells().getSelectedSpell(); + const std::string& selectedSpell = stats.getSpells().getSelectedSpell(); MWMechanics::CastSpell cast(actor, target, false, manualSpell); cast.mHitPosition = hitPosition; @@ -3268,7 +3273,7 @@ namespace MWWorld } else { - std::string dest = ref.mRef.getDestCell(); + const std::string& dest = ref.mRef.getDestCell(); if ( !checkedCells.count(dest) && !currentCells.count(dest) ) nextCells.insert(dest); } @@ -3282,7 +3287,7 @@ namespace MWWorld return false; } - MWWorld::ConstPtr World::getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ) + MWWorld::ConstPtr World::getClosestMarker(const MWWorld::ConstPtr& ptr, std::string_view id) { if ( ptr.getCell()->isExterior() ) { return getClosestMarkerFromExteriorPosition(mPlayer->getLastKnownExteriorPosition(), id); @@ -3323,7 +3328,7 @@ namespace MWWorld } else { - std::string dest = ref.mRef.getDestCell(); + const std::string& dest = ref.mRef.getDestCell(); if ( !checkedCells.count(dest) && !currentCells.count(dest) ) nextCells.insert(dest); } @@ -3333,7 +3338,7 @@ namespace MWWorld return MWWorld::Ptr(); } - MWWorld::ConstPtr World::getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ) { + MWWorld::ConstPtr World::getClosestMarkerFromExteriorPosition(const osg::Vec3f& worldPos, std::string_view id) { MWWorld::ConstPtr closestMarker; float closestDistance = std::numeric_limits::max(); @@ -3374,8 +3379,7 @@ namespace MWWorld mCells.recharge(duration); } - void World::teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id) + void World::teleportToClosestMarker(const MWWorld::Ptr& ptr, std::string_view id) { MWWorld::ConstPtr closestMarker = getClosestMarker( ptr, id ); @@ -3385,7 +3389,7 @@ namespace MWWorld return; } - std::string cellName; + std::string_view cellName; if ( !closestMarker.mCell->isExterior() ) cellName = closestMarker.mCell->getCell()->mName; @@ -3584,7 +3588,7 @@ namespace MWWorld Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found."; return; } - std::string prisonName = prisonMarker.getCellRef().getDestCell(); + const std::string& prisonName = prisonMarker.getCellRef().getDestCell(); if ( prisonName.empty() ) { Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior"; @@ -3751,7 +3755,7 @@ namespace MWWorld else areaStatic = mStore.get().find ("VFX_DefaultArea"); - std::string texture = effect->mParticle; + const std::string& texture = effect->mParticle; if (effectInfo.mArea <= 0) { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index db563a7c7b..d3d2ab82e1 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -182,8 +182,8 @@ namespace MWWorld float feetToGameUnits(float feet); float getActivationDistancePlusTelekinesis(); - MWWorld::ConstPtr getClosestMarker( const MWWorld::Ptr &ptr, const std::string &id ); - MWWorld::ConstPtr getClosestMarkerFromExteriorPosition( const osg::Vec3f& worldPos, const std::string &id ); + MWWorld::ConstPtr getClosestMarker(const MWWorld::ConstPtr& ptr, std::string_view id); + MWWorld::ConstPtr getClosestMarkerFromExteriorPosition(const osg::Vec3f& worldPos, std::string_view id); public: // FIXME @@ -320,7 +320,7 @@ namespace MWWorld void advanceTime (double hours, bool incremental = false) override; ///< Advance in-game time. - std::string getMonthName (int month = -1) const override; + std::string_view getMonthName(int month = -1) const override; ///< Return name of month (-1: current month) TimeStamp getTimeStamp() const override; @@ -612,7 +612,7 @@ namespace MWWorld /// Find center of exterior cell above land surface /// \return false if exterior with given name not exists, true otherwise - bool findExteriorPosition(const std::string &name, ESM::Position &pos) override; + bool findExteriorPosition(std::string_view name, ESM::Position& pos) override; /// Find position in interior cell near door entrance /// \return false if interior with given name not exists, true otherwise @@ -667,8 +667,7 @@ namespace MWWorld /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) /// @note id must be lower case - void teleportToClosestMarker (const MWWorld::Ptr& ptr, - const std::string& id) override; + void teleportToClosestMarker(const MWWorld::Ptr& ptr, std::string_view id) override; /// List all references (filtered by \a type) detected by \a ptr. The range /// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type.