1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-13 11:13:06 +00:00

Use more string_view in the character controller

This commit is contained in:
Evil Eye 2022-08-27 13:47:15 +02:00
parent 19bd2f3c3d
commit 534994b42a
8 changed files with 55 additions and 56 deletions

View file

@ -56,7 +56,7 @@
namespace 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 slash = weapon->mData.mSlash[0] + weapon->mData.mSlash[1];
int chop = weapon->mData.mChop[0] + weapon->mData.mChop[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. // 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; using namespace MWMechanics;
switch (state) 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. // 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; using namespace MWMechanics;
switch (state) switch (state)
@ -350,8 +350,8 @@ void CharacterController::refreshHitRecoilAnims()
return; return;
MWRender::Animation::AnimPriority priority(Priority_Knockdown); MWRender::Animation::AnimPriority priority(Priority_Knockdown);
std::string startKey = "start"; std::string_view startKey = "start";
std::string stopKey = "stop"; std::string_view stopKey = "stop";
if (knockout) if (knockout)
{ {
mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut; mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut;
@ -563,15 +563,16 @@ void CharacterController::refreshMovementAnims(CharacterState movement, bool for
if (movement == mMovementState && !force) if (movement == mMovementState && !force)
return; return;
std::string movementAnimName = movementStateToAnimGroup(movement); std::string_view movementAnimGroup = movementStateToAnimGroup(movement);
if (movementAnimName.empty()) if (movementAnimGroup.empty())
{ {
if (!mCurrentMovement.empty()) if (!mCurrentMovement.empty())
resetCurrentIdleState(); resetCurrentIdleState();
resetCurrentMovementState(); resetCurrentMovementState();
return; return;
} }
std::string movementAnimName{movementAnimGroup};
mMovementState = movement; mMovementState = movement;
std::string::size_type swimpos = movementAnimName.find("swim"); 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<ESM::Creature>()->mBase->mFlags & ESM::Creature::Flies)) if (mPtr.getClass().getType() == ESM::Creature::sRecordId && !(mPtr.get<ESM::Creature>()->mBase->mFlags & ESM::Creature::Flies))
{ {
CharacterState walkState = runStateToWalkState(mMovementState); CharacterState walkState = runStateToWalkState(mMovementState);
std::string anim = movementStateToAnimGroup(walkState); std::string_view anim = movementStateToAnimGroup(walkState);
mMovementAnimSpeed = mAnimation->getVelocity(anim); mMovementAnimSpeed = mAnimation->getVelocity(anim);
if (mMovementAnimSpeed <= 1.0f) if (mMovementAnimSpeed <= 1.0f)
@ -1009,19 +1010,21 @@ void CharacterController::handleTextKey(std::string_view groupname, SceneUtil::T
{ {
std::multimap<float, std::string>::const_iterator hitKey = key; std::multimap<float, std::string>::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. // Not all animations have a hit key defined. If there is none, the hit happens with the start key.
bool hasHitKey = false; bool hasHitKey = false;
while (hitKey != map.end()) while (hitKey != map.end())
{ {
if (hitKey->second == hitKeyName) if (hitKey->second.starts_with(groupname))
{ {
hasHitKey = true; std::string_view suffix = std::string_view(hitKey->second).substr(groupname.size());
break; if (suffix == ": hit")
{
hasHitKey = true;
break;
}
if (suffix == ": stop")
break;
} }
if (hitKey->second == stopKeyName)
break;
++hitKey; ++hitKey;
} }
if (!hasHitKey) if (!hasHitKey)
@ -1386,7 +1389,7 @@ bool CharacterController::updateWeaponState()
const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
stats.getSpells().setSelectedSpell(selectedSpell); stats.getSpells().setSelectedSpell(selectedSpell);
} }
std::string spellid = stats.getSpells().getSelectedSpell(); std::string_view spellid = stats.getSpells().getSelectedSpell();
bool isMagicItem = false; bool isMagicItem = false;
// Play hand VFX and allow castSpell use (assuming an animation is going to be played) if spellcasting is successful. // 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()) if (!target.isEmpty())
{ {
std::string resultMessage, resultSound; std::string_view resultMessage, resultSound;
if (mWeapon.getType() == ESM::Lockpick::sRecordId) if (mWeapon.getType() == ESM::Lockpick::sRecordId)
Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound); Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound);
else if (mWeapon.getType() == ESM::Probe::sRecordId) else if (mWeapon.getType() == ESM::Probe::sRecordId)
@ -2082,7 +2085,7 @@ void CharacterController::update(float duration)
if (playLandingSound) if (playLandingSound)
{ {
std::string sound; std::string_view sound;
osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3());
if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr)) if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr))
sound = "DefaultLandWater"; sound = "DefaultLandWater";
@ -2425,7 +2428,7 @@ bool CharacterController::isPersistentAnimPlaying() const
return false; return false;
} }
bool CharacterController::isAnimPlaying(const std::string &groupName) const bool CharacterController::isAnimPlaying(std::string_view groupName) const
{ {
if(mAnimation == nullptr) if(mAnimation == nullptr)
return false; return false;
@ -2714,7 +2717,7 @@ void CharacterController::setHeadTrackTarget(const MWWorld::ConstPtr &target)
void CharacterController::playSwishSound() const void CharacterController::playSwishSound() const
{ {
std::string soundId = "Weapon Swish"; std::string_view soundId = "Weapon Swish";
float volume = 0.98f + mAttackStrength * 0.02f; float volume = 0.98f + mAttackStrength * 0.02f;
float pitch = 0.75f + mAttackStrength * 0.4f; float pitch = 0.75f + mAttackStrength * 0.4f;

View file

@ -262,7 +262,7 @@ public:
bool playGroup(std::string_view groupname, int mode, int count, bool persist=false); bool playGroup(std::string_view groupname, int mode, int count, bool persist=false);
void skipAnim(); void skipAnim();
bool isAnimPlaying(const std::string &groupName) const; bool isAnimPlaying(std::string_view groupName) const;
enum KillResult enum KillResult
{ {

View file

@ -26,7 +26,7 @@ namespace MWMechanics
} }
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, 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 || if (lock.getCellRef().getLockLevel() <= 0 ||
lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || lock.getCellRef().getLockLevel() == ESM::UnbreakableLock ||
@ -72,7 +72,7 @@ namespace MWMechanics
} }
void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, 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()) if (trap.getCellRef().getTrap().empty())
return; return;

View file

@ -13,9 +13,9 @@ namespace MWMechanics
Security (const MWWorld::Ptr& actor); Security (const MWWorld::Ptr& actor);
void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, 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, 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: private:
float mAgility, mLuck, mSecuritySkill, mFatigueTerm; float mAgility, mLuck, mSecuritySkill, mFatigueTerm;

View file

@ -435,7 +435,7 @@ namespace MWMechanics
return true; 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(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
if (enchantment) if (enchantment)

View file

@ -54,7 +54,7 @@ namespace MWMechanics
/// @note Auto detects if spell, ingredient or potion /// @note Auto detects if spell, ingredient or potion
bool cast (const std::string& id); 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. /// Launch a bolt with the given effects.
void launchMagicBolt (); void launchMagicBolt ();

View file

@ -166,13 +166,20 @@ namespace
} }
}; };
float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, bool equalsParts(std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {})
const osg::Vec3f& accum, const std::string &groupname) {
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<float>::max(); float starttime = std::numeric_limits<float>::max();
float stoptime = 0.0f; float stoptime = 0.0f;
@ -185,7 +192,7 @@ namespace
auto keyiter = keys.rbegin(); auto keyiter = keys.rbegin();
while(keyiter != keys.rend()) 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; starttime = keyiter->first;
break; break;
@ -195,9 +202,9 @@ namespace
keyiter = keys.rbegin(); keyiter = keys.rbegin();
while(keyiter != keys.rend()) while(keyiter != keys.rend())
{ {
if (keyiter->second == stop) if (equalsParts(keyiter->second, groupname, ": stop"))
stoptime = keyiter->first; stoptime = keyiter->first;
else if (keyiter->second == loopstop) else if (equalsParts(keyiter->second, groupname, ": loop stop"))
{ {
stoptime = keyiter->first; stoptime = keyiter->first;
break; break;
@ -868,24 +875,13 @@ namespace MWRender
break; 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; auto startkey = groupend;
while(startkey != keys.rend() && !equals(startkey->second, groupname, ": ", start)) while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": ", start))
++startkey; ++startkey;
if(startkey == keys.rend() && start == "loop start") if(startkey == keys.rend() && start == "loop start")
{ {
startkey = groupend; startkey = groupend;
while(startkey != keys.rend() && !equals(startkey->second, groupname, ": start")) while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": start"))
++startkey; ++startkey;
} }
if(startkey == keys.rend()) if(startkey == keys.rend())
@ -897,7 +893,7 @@ namespace MWRender
// We have to ignore extra garbage at the end. // We have to ignore extra garbage at the end.
// The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop".
// Why, just why? :( // 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; ++stopkey;
if(stopkey == keys.rend()) if(stopkey == keys.rend())
return false; return false;
@ -929,9 +925,9 @@ namespace MWRender
if (key->first > state.getTime()) if (key->first > state.getTime())
continue; continue;
if (equals(key->second, groupname, ": loop start")) if (equalsParts(key->second, groupname, ": loop start"))
state.mLoopStartTime = key->first; state.mLoopStartTime = key->first;
else if (equals(key->second, groupname, ": loop stop")) else if (equalsParts(key->second, groupname, ": loop stop"))
state.mLoopStopTime = key->first; state.mLoopStopTime = key->first;
} }
@ -1081,7 +1077,7 @@ namespace MWRender
resetActiveGroups(); resetActiveGroups();
} }
float Animation::getVelocity(const std::string &groupname) const float Animation::getVelocity(std::string_view groupname) const
{ {
if (!mAccumRoot) if (!mAccumRoot)
return 0.0f; return 0.0f;
@ -1137,7 +1133,7 @@ namespace MWRender
} }
} }
mAnimVelocities.insert(std::make_pair(groupname, velocity)); mAnimVelocities.emplace(groupname, velocity);
return velocity; return velocity;
} }

View file

@ -285,7 +285,7 @@ protected:
float mAlpha; float mAlpha;
mutable std::map<std::string, float> mAnimVelocities; mutable std::map<std::string, float, std::less<>> mAnimVelocities;
osg::ref_ptr<SceneUtil::LightListCallback> mLightListCallback; osg::ref_ptr<SceneUtil::LightListCallback> mLightListCallback;
@ -451,7 +451,7 @@ public:
void disable(std::string_view groupname); void disable(std::string_view groupname);
/** Retrieves the velocity (in units per second) that the animation will move. */ /** 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); virtual osg::Vec3f runAnimation(float duration);