1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-17 10:21:11 +00:00

Mark not changing variables as const

This commit is contained in:
elsid 2022-07-04 21:48:26 +02:00
parent f8b8569f3b
commit 5e8df40718
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

View File

@ -95,13 +95,13 @@ void adjustCommandedActor (const MWWorld::Ptr& actor)
std::pair<float, float> getRestorationPerHourOfSleep(const MWWorld::Ptr& ptr) std::pair<float, float> getRestorationPerHourOfSleep(const MWWorld::Ptr& ptr)
{ {
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); const float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified();
const float health = 0.1f * endurance; const float health = 0.1f * endurance;
float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat (); static const float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat();
const float magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); const float magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
return {health, magicka}; return {health, magicka};
@ -153,10 +153,10 @@ void soulTrap(const MWWorld::Ptr& creature)
const auto& stats = creature.getClass().getCreatureStats(creature); const auto& stats = creature.getClass().getCreatureStats(creature);
if(!stats.getMagicEffects().get(ESM::MagicEffect::Soultrap).getMagnitude()) if(!stats.getMagicEffects().get(ESM::MagicEffect::Soultrap).getMagnitude())
return; return;
int creatureSoulValue = creature.get<ESM::Creature>()->mBase->mData.mSoul; const int creatureSoulValue = creature.get<ESM::Creature>()->mBase->mData.mSoul;
if (creatureSoulValue == 0) if (creatureSoulValue == 0)
return; return;
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* const world = MWBase::Environment::get().getWorld();
static const float fSoulgemMult = world->getStore().get<ESM::GameSetting>().find("fSoulgemMult")->mValue.getFloat(); static const float fSoulgemMult = world->getStore().get<ESM::GameSetting>().find("fSoulgemMult")->mValue.getFloat();
for(const auto& params : stats.getActiveSpells()) for(const auto& params : stats.getActiveSpells())
{ {
@ -203,9 +203,8 @@ void soulTrap(const MWWorld::Ptr& creature)
if (caster == MWMechanics::getPlayer()) if (caster == MWMechanics::getPlayer())
MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}");
const ESM::Static* fx = world->getStore().get<ESM::Static>() const ESM::Static* const fx = world->getStore().get<ESM::Static>().search("VFX_Soul_Trap");
.search("VFX_Soul_Trap"); if (fx != nullptr)
if (fx)
{ {
const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
world->spawnEffect( world->spawnEffect(
@ -265,7 +264,7 @@ namespace MWMechanics
const osg::Vec3f actor1Pos(actorRefData.getPosition().asVec3()); const osg::Vec3f actor1Pos(actorRefData.getPosition().asVec3());
const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3()); const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3());
float sqrDist = (actor1Pos - actor2Pos).length2(); const float sqrDist = (actor1Pos - actor2Pos).length2();
if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance) && !inCombatOrPursue) if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance) && !inCombatOrPursue)
return; return;
@ -382,7 +381,7 @@ namespace MWMechanics
const osg::Vec3f playerPos(getPlayer().getRefData().getPosition().asVec3()); const osg::Vec3f playerPos(getPlayer().getRefData().getPosition().asVec3());
const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* const world = MWBase::Environment::get().getWorld();
if (world->isSwimming(actor) || (playerPos - actorPos).length2() >= 3000 * 3000) if (world->isSwimming(actor) || (playerPos - actorPos).length2() >= 3000 * 3000)
return; return;
@ -405,13 +404,13 @@ namespace MWMechanics
if (!seq.isEmpty() && seq.getActivePackage().useVariableSpeed()) if (!seq.isEmpty() && seq.getActivePackage().useVariableSpeed())
{ {
osg::Vec3f targetPos = seq.getActivePackage().getDestination(); const osg::Vec3f targetPos = seq.getActivePackage().getDestination();
osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3();
float distance = (targetPos - actorPos).length(); const float distance = (targetPos - actorPos).length();
if (distance < DECELERATE_DISTANCE) if (distance < DECELERATE_DISTANCE)
{ {
float speedCoef = std::max(0.7f, 0.2f + 0.8f * distance / DECELERATE_DISTANCE); const float speedCoef = std::max(0.7f, 0.2f + 0.8f * distance / DECELERATE_DISTANCE);
auto& movement = actorClass.getMovementSettings(actor); auto& movement = actorClass.getMovementSettings(actor);
movement.mPosition[0] *= speedCoef; movement.mPosition[0] *= speedCoef;
movement.mPosition[1] *= speedCoef; movement.mPosition[1] *= speedCoef;
@ -439,10 +438,10 @@ namespace MWMechanics
return; return;
} }
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
osg::Vec3f playerPos(player.getRefData().getPosition().asVec3()); const osg::Vec3f playerPos(player.getRefData().getPosition().asVec3());
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
osg::Vec3f dir = playerPos - actorPos; const osg::Vec3f dir = playerPos - actorPos;
if (actorState.isTurningToPlayer()) if (actorState.isTurningToPlayer())
{ {
@ -464,7 +463,7 @@ namespace MWMechanics
static const int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore() static const int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore()
.get<ESM::GameSetting>().find("iGreetDistanceMultiplier")->mValue.getInteger(); .get<ESM::GameSetting>().find("iGreetDistanceMultiplier")->mValue.getInteger();
float helloDistance = static_cast<float>(actorStats.getAiSetting(CreatureStats::AI_Hello).getModified() * iGreetDistanceMultiplier); const float helloDistance = static_cast<float>(actorStats.getAiSetting(CreatureStats::AI_Hello).getModified() * iGreetDistanceMultiplier);
const auto& playerStats = player.getClass().getCreatureStats(player); const auto& playerStats = player.getClass().getCreatureStats(player);
int greetingTimer = actorState.getGreetingTimer(); int greetingTimer = actorState.getGreetingTimer();
@ -702,7 +701,7 @@ namespace MWMechanics
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature, float duration) void Actors::adjustMagicEffects (const MWWorld::Ptr& creature, float duration)
{ {
CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature); CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature);
bool wasDead = creatureStats.isDead(); const bool wasDead = creatureStats.isDead();
creatureStats.getActiveSpells().update(creature, duration); creatureStats.getActiveSpells().update(creature, duration);
@ -710,7 +709,7 @@ namespace MWMechanics
{ {
// The actor was killed by a magic effect. Figure out if the player was responsible for it. // The actor was killed by a magic effect. Figure out if the player was responsible for it.
const ActiveSpells& spells = creatureStats.getActiveSpells(); const ActiveSpells& spells = creatureStats.getActiveSpells();
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
std::set<MWWorld::Ptr> playerFollowers; std::set<MWWorld::Ptr> playerFollowers;
getActorsSidingWith(player, playerFollowers); getActorsSidingWith(player, playerFollowers);
@ -727,7 +726,7 @@ namespace MWMechanics
ESM::MagicEffect::SunDamage, ESM::MagicEffect::DamageHealth, ESM::MagicEffect::AbsorbHealth ESM::MagicEffect::SunDamage, ESM::MagicEffect::DamageHealth, ESM::MagicEffect::AbsorbHealth
}; };
bool isDamageEffect = std::find(damageEffects.begin(), damageEffects.end(), effect.mEffectId) != damageEffects.end(); const bool isDamageEffect = std::find(damageEffects.begin(), damageEffects.end(), effect.mEffectId) != damageEffects.end();
if (isDamageEffect) if (isDamageEffect)
{ {
@ -766,14 +765,14 @@ namespace MWMechanics
if (sleep) if (sleep)
{ {
auto [health, magicka] = getRestorationPerHourOfSleep(ptr); const auto [health, magicka] = getRestorationPerHourOfSleep(ptr);
DynamicStat<float> stat = stats.getHealth(); DynamicStat<float> stat = stats.getHealth();
stat.setCurrent(stat.getCurrent() + health * hours); stat.setCurrent(stat.getCurrent() + health * hours);
stats.setHealth(stat); stats.setHealth(stat);
double restoreHours = hours; double restoreHours = hours;
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; const bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0;
if (stunted) if (stunted)
{ {
// Stunted Magicka effect should be taken into account. // Stunted Magicka effect should be taken into account.
@ -807,18 +806,18 @@ namespace MWMechanics
return; return;
// Restore fatigue // Restore fatigue
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat ();
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat (); static const float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat ();
float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); const float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
float normalizedEncumbrance = ptr.getClass().getNormalizedEncumbrance(ptr); float normalizedEncumbrance = ptr.getClass().getNormalizedEncumbrance(ptr);
if (normalizedEncumbrance > 1) if (normalizedEncumbrance > 1)
normalizedEncumbrance = 1; normalizedEncumbrance = 1;
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance); const float x = (fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance))
x *= fEndFatigueMult * endurance; * (fEndFatigueMult * endurance);
fatigue.setCurrent (fatigue.getCurrent() + 3600 * x * hours); fatigue.setCurrent (fatigue.getCurrent() + 3600 * x * hours);
stats.setFatigue (fatigue); stats.setFatigue (fatigue);
@ -838,12 +837,12 @@ namespace MWMechanics
return; return;
// Restore fatigue // Restore fatigue
float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified(); const float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified();
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat ();
static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
float x = fFatigueReturnBase + fFatigueReturnMult * endurance; const float x = fFatigueReturnBase + fFatigueReturnMult * endurance;
fatigue.setCurrent (fatigue.getCurrent() + duration * x); fatigue.setCurrent (fatigue.getCurrent() + duration * x);
stats.setFatigue (fatigue); stats.setFatigue (fatigue);
@ -875,7 +874,7 @@ namespace MWMechanics
void Actors::updateDrowning(const MWWorld::Ptr& ptr, float duration, bool isKnockedOut, bool isPlayer) void Actors::updateDrowning(const MWWorld::Ptr& ptr, float duration, bool isKnockedOut, bool isPlayer)
{ {
auto& actorClass = ptr.getClass(); const auto& actorClass = ptr.getClass();
NpcStats& stats = actorClass.getNpcStats(ptr); NpcStats& stats = actorClass.getNpcStats(ptr);
// When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST // When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST
@ -890,8 +889,8 @@ namespace MWMechanics
seq.stack(AiBreathe(), ptr); seq.stack(AiBreathe(), ptr);
} }
MWBase::World* world = MWBase::Environment::get().getWorld(); const MWBase::World* const world = MWBase::Environment::get().getWorld();
bool knockedOutUnderwater = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3()))); const bool knockedOutUnderwater = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
if ((world->isSubmerged(ptr) || knockedOutUnderwater) if ((world->isSubmerged(ptr) || knockedOutUnderwater)
&& stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0) && stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0)
{ {
@ -906,7 +905,7 @@ namespace MWMechanics
stats.setTimeToStartDrowning(timeLeft); stats.setTimeToStartDrowning(timeLeft);
} }
bool godmode = isPlayer && world->getGodModeState(); const bool godmode = isPlayer && world->getGodModeState();
if (timeLeft == 0.0f && !godmode) if (timeLeft == 0.0f && !godmode)
{ {
@ -933,7 +932,7 @@ namespace MWMechanics
{ {
const bool isPlayer = (ptr == getPlayer()); const bool isPlayer = (ptr == getPlayer());
auto& actorClass = ptr.getClass(); const auto& actorClass = ptr.getClass();
auto& inventoryStore = actorClass.getInventoryStore(ptr); auto& inventoryStore = actorClass.getInventoryStore(ptr);
auto heldIter = inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); auto heldIter = inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
@ -1031,11 +1030,11 @@ namespace MWMechanics
void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration)
{ {
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
if (ptr == player) if (ptr == player)
return; return;
auto& actorClass = ptr.getClass(); const auto& actorClass = ptr.getClass();
if (!actorClass.isNpc()) if (!actorClass.isNpc())
return; return;
@ -1158,9 +1157,9 @@ namespace MWMechanics
// Fade away actors on large distance (>90% of actor's processing distance) // Fade away actors on large distance (>90% of actor's processing distance)
float visibilityRatio = 1.0; float visibilityRatio = 1.0;
float fadeStartDistance = mActorsProcessingRange*0.9f; const float fadeStartDistance = mActorsProcessingRange*0.9f;
float fadeEndDistance = mActorsProcessingRange; const float fadeEndDistance = mActorsProcessingRange;
float fadeRatio = (dist - fadeStartDistance)/(fadeEndDistance - fadeStartDistance); const float fadeRatio = (dist - fadeStartDistance)/(fadeEndDistance - fadeStartDistance);
if (fadeRatio > 0) if (fadeRatio > 0)
visibilityRatio -= std::max(0.f, fadeRatio); visibilityRatio -= std::max(0.f, fadeRatio);
@ -1210,7 +1209,7 @@ namespace MWMechanics
if (neighbor == actor) if (neighbor == actor)
continue; continue;
bool result = MWBase::Environment::get().getWorld()->getLOS(neighbor, actor) const bool result = MWBase::Environment::get().getWorld()->getLOS(neighbor, actor)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, neighbor); && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, neighbor);
if (result) if (result)
@ -1244,10 +1243,10 @@ namespace MWMechanics
void Actors::updateCombatMusic () void Actors::updateCombatMusic ()
{ {
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
bool hasHostiles = false; // need to know this to play Battle music bool hasHostiles = false; // need to know this to play Battle music
bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive(); const bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive();
if (aiActive) if (aiActive)
{ {
@ -1296,20 +1295,20 @@ namespace MWMechanics
static const bool giveWayWhenIdle = Settings::Manager::getBool("NPCs give way", "Game"); static const bool giveWayWhenIdle = Settings::Manager::getBool("NPCs give way", "Game");
const MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
const MWBase::World* world = MWBase::Environment::get().getWorld(); const MWBase::World* const world = MWBase::Environment::get().getWorld();
for (const Actor& actor : mActors) for (const Actor& actor : mActors)
{ {
const MWWorld::Ptr& ptr = actor.getPtr(); const MWWorld::Ptr& ptr = actor.getPtr();
if (ptr == player) if (ptr == player)
continue; // Don't interfere with player controls. continue; // Don't interfere with player controls.
float maxSpeed = ptr.getClass().getMaxSpeed(ptr); const float maxSpeed = ptr.getClass().getMaxSpeed(ptr);
if (maxSpeed == 0.0) if (maxSpeed == 0.0)
continue; // Can't move, so there is no sense to predict collisions. continue; // Can't move, so there is no sense to predict collisions.
Movement& movement = ptr.getClass().getMovementSettings(ptr); Movement& movement = ptr.getClass().getMovementSettings(ptr);
osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]); const osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]);
bool isMoving = origMovement.length2() > 0.01; const bool isMoving = origMovement.length2() > 0.01;
if (movement.mPosition[1] < 0) if (movement.mPosition[1] < 0)
continue; // Actors can not see others when move backward. continue; // Actors can not see others when move backward.
@ -1344,11 +1343,11 @@ namespace MWMechanics
if (!shouldAvoidCollision && !shouldGiveWay) if (!shouldAvoidCollision && !shouldGiveWay)
continue; continue;
osg::Vec2f baseSpeed = origMovement * maxSpeed; const osg::Vec2f baseSpeed = origMovement * maxSpeed;
osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3(); const osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3();
float baseRotZ = ptr.getRefData().getPosition().rot[2]; const float baseRotZ = ptr.getRefData().getPosition().rot[2];
const osg::Vec3f halfExtents = world->getHalfExtents(ptr); const osg::Vec3f halfExtents = world->getHalfExtents(ptr);
float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding; const float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding;
float timeToCheck = maxTimeToCheck; float timeToCheck = maxTimeToCheck;
if (!shouldGiveWay && !aiSequence.isEmpty()) if (!shouldGiveWay && !aiSequence.isEmpty())
@ -1366,9 +1365,9 @@ namespace MWMechanics
continue; continue;
const osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr); const osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr);
osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos; const osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos;
osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ); const osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ);
float dist = deltaPos.length(); const float dist = deltaPos.length();
// Ignore actors which are not close enough or come from behind. // Ignore actors which are not close enough or come from behind.
if (dist > maxDistToCheck || relPos.y() < 0) if (dist > maxDistToCheck || relPos.y() < 0)
@ -1378,21 +1377,21 @@ namespace MWMechanics
if (deltaPos.z() > halfExtents.z() * 2 || deltaPos.z() < -otherHalfExtents.z() * 2) if (deltaPos.z() > halfExtents.z() * 2 || deltaPos.z() < -otherHalfExtents.z() * 2)
continue; continue;
osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3() * const osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3()
otherPtr.getClass().getMaxSpeed(otherPtr); * otherPtr.getClass().getMaxSpeed(otherPtr);
float rotZ = otherPtr.getRefData().getPosition().rot[2]; const float rotZ = otherPtr.getRefData().getPosition().rot[2];
osg::Vec2f relSpeed = Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed; const osg::Vec2f relSpeed = Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed;
float collisionDist = minGap + halfExtents.x() + otherHalfExtents.x(); float collisionDist = minGap + halfExtents.x() + otherHalfExtents.x();
collisionDist = std::min(collisionDist, relPos.length()); collisionDist = std::min(collisionDist, relPos.length());
// Find the earliest `t` when |relPos + relSpeed * t| == collisionDist. // Find the earliest `t` when |relPos + relSpeed * t| == collisionDist.
float vr = relPos.x() * relSpeed.x() + relPos.y() * relSpeed.y(); const float vr = relPos.x() * relSpeed.x() + relPos.y() * relSpeed.y();
float v2 = relSpeed.length2(); const float v2 = relSpeed.length2();
float Dh = vr * vr - v2 * (relPos.length2() - collisionDist * collisionDist); const float Dh = vr * vr - v2 * (relPos.length2() - collisionDist * collisionDist);
if (Dh <= 0 || v2 == 0) if (Dh <= 0 || v2 == 0)
continue; // No solution; distance is always >= collisionDist. continue; // No solution; distance is always >= collisionDist.
float t = (-vr - std::sqrt(Dh)) / v2; const float t = (-vr - std::sqrt(Dh)) / v2;
if (t < 0 || t > timeToCollision) if (t < 0 || t > timeToCollision)
continue; continue;
@ -1405,9 +1404,9 @@ namespace MWMechanics
timeToCollision = t; timeToCollision = t;
angleToApproachingActor = std::atan2(deltaPos.x(), deltaPos.y()); angleToApproachingActor = std::atan2(deltaPos.x(), deltaPos.y());
osg::Vec2f posAtT = relPos + relSpeed * t; const osg::Vec2f posAtT = relPos + relSpeed * t;
float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * collisionDist * maxSpeed); const float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * collisionDist * maxSpeed)
coef *= std::clamp((maxDistForPartialAvoiding - dist) / (maxDistForPartialAvoiding - maxDistForStrictAvoiding), 0.f, 1.f); * std::clamp((maxDistForPartialAvoiding - dist) / (maxDistForPartialAvoiding - maxDistForStrictAvoiding), 0.f, 1.f);
movementCorrection = posAtT * coef; movementCorrection = posAtT * coef;
if (otherPtr.getClass().getCreatureStats(otherPtr).isDead()) if (otherPtr.getClass().getCreatureStats(otherPtr).isDead())
// In case of dead body still try to go around (it looks natural), but reduce the correction twice. // In case of dead body still try to go around (it looks natural), but reduce the correction twice.
@ -1450,18 +1449,18 @@ namespace MWMechanics
mTimerUpdateEquippedLight = 0; mTimerUpdateEquippedLight = 0;
// show torches only when there are darkness and no precipitations // show torches only when there are darkness and no precipitations
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* const world = MWBase::Environment::get().getWorld();
bool showTorches = world->useTorches(); const bool showTorches = world->useTorches();
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3();
/// \todo move update logic to Actor class where appropriate /// \todo move update logic to Actor class where appropriate
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> > cachedAllies; // will be filled as engageCombat iterates std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> > cachedAllies; // will be filled as engageCombat iterates
bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive(); const bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive();
int attackedByPlayerId = player.getClass().getCreatureStats(player).getHitAttemptActorId(); const int attackedByPlayerId = player.getClass().getCreatureStats(player).getHitAttemptActorId();
if (attackedByPlayerId != -1) if (attackedByPlayerId != -1)
{ {
const MWWorld::Ptr playerHitAttemptActor = world->searchPtrViaActorId(attackedByPlayerId); const MWWorld::Ptr playerHitAttemptActor = world->searchPtrViaActorId(attackedByPlayerId);
@ -1469,7 +1468,7 @@ namespace MWMechanics
if (!playerHitAttemptActor.isInCell()) if (!playerHitAttemptActor.isInCell())
player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); player.getClass().getCreatureStats(player).setHitAttemptActorId(-1);
} }
bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); const bool godmode = MWBase::Environment::get().getWorld()->getGodModeState();
// AI and magic effects update // AI and magic effects update
for (Actor& actor : mActors) for (Actor& actor : mActors)
@ -1481,7 +1480,7 @@ namespace MWMechanics
const float distSqr = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2(); const float distSqr = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2();
// AI processing is only done within given distance to the player. // AI processing is only done within given distance to the player.
bool inProcessingRange = distSqr <= mActorsProcessingRange*mActorsProcessingRange; const bool inProcessingRange = distSqr <= mActorsProcessingRange*mActorsProcessingRange;
// If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player. // If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player.
if (!isPlayer && (actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead() if (!isPlayer && (actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead()
@ -1505,7 +1504,7 @@ namespace MWMechanics
} }
else else
{ {
bool cellChanged = world->hasCellChanged(); const bool cellChanged = world->hasCellChanged();
const MWWorld::Ptr actorPtr = actor.getPtr(); // make a copy of the map key to avoid it being invalidated when the player teleports const MWWorld::Ptr actorPtr = actor.getPtr(); // make a copy of the map key to avoid it being invalidated when the player teleports
updateActor(actorPtr, duration); updateActor(actorPtr, duration);
@ -1595,11 +1594,9 @@ namespace MWMechanics
MWMechanics::AiSequence& seq = stats.getAiSequence(); MWMechanics::AiSequence& seq = stats.getAiSequence();
alwaysActive = !seq.isEmpty() && seq.getActivePackage().alwaysActive(); alwaysActive = !seq.isEmpty() && seq.getActivePackage().alwaysActive();
} }
bool inRange = isPlayer || dist <= mActorsProcessingRange || alwaysActive; const bool inRange = isPlayer || dist <= mActorsProcessingRange || alwaysActive;
int activeFlag = 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower) const int activeFlag = isPlayer ? 2 : 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower)
if (isPlayer) const int active = inRange ? activeFlag : 0;
activeFlag = 2;
int active = inRange ? activeFlag : 0;
CharacterController& ctrl = actor.getCharacterController(); CharacterController& ctrl = actor.getCharacterController();
ctrl.setActive(active); ctrl.setActive(active);
@ -1726,7 +1723,7 @@ namespace MWMechanics
// Reset magic effects and recalculate derived effects // Reset magic effects and recalculate derived effects
// One case where we need this is to make sure bound items are removed upon death // One case where we need this is to make sure bound items are removed upon death
float vampirism = stats.getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude(); const float vampirism = stats.getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude();
stats.getActiveSpells().clear(actor.getPtr()); stats.getActiveSpells().clear(actor.getPtr());
// Make sure spell effects are removed // Make sure spell effects are removed
purgeSpellEffects(stats.getActorId()); purgeSpellEffects(stats.getActorId());
@ -1751,7 +1748,7 @@ namespace MWMechanics
void Actors::cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId) void Actors::cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId)
{ {
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId); const MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId);
if (!ptr.isEmpty()) if (!ptr.isEmpty())
{ {
MWBase::Environment::get().getWorld()->deleteObject(ptr); MWBase::Environment::get().getWorld()->deleteObject(ptr);
@ -1796,7 +1793,7 @@ namespace MWMechanics
void Actors::rest(double hours, bool sleep) void Actors::rest(double hours, bool sleep)
{ {
float duration = hours * 3600.f; float duration = hours * 3600.f;
float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); const float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor();
if (timeScale != 0.f) if (timeScale != 0.f)
duration /= timeScale; duration /= timeScale;
@ -1839,7 +1836,7 @@ namespace MWMechanics
return; return;
} }
MWWorld::Ptr player = getPlayer(); const MWWorld::Ptr player = getPlayer();
if (!MWBase::Environment::get().getMechanicsManager()->isSneaking(player)) if (!MWBase::Environment::get().getMechanicsManager()->isSneaking(player))
{ {
@ -1847,7 +1844,7 @@ namespace MWMechanics
return; return;
} }
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* const world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>();
static const float fSneakUseDist = gmst.find("fSneakUseDist")->mValue.getFloat(); static const float fSneakUseDist = gmst.find("fSneakUseDist")->mValue.getFloat();
static const float fSneakUseDelay = gmst.find("fSneakUseDelay")->mValue.getFloat(); static const float fSneakUseDelay = gmst.find("fSneakUseDelay")->mValue.getFloat();
@ -1862,8 +1859,8 @@ namespace MWMechanics
bool detected = false; bool detected = false;
std::vector<MWWorld::Ptr> observers; std::vector<MWWorld::Ptr> observers;
osg::Vec3f position(player.getRefData().getPosition().asVec3()); const osg::Vec3f position(player.getRefData().getPosition().asVec3());
float radius = std::min(fSneakUseDist, mActorsProcessingRange); const float radius = std::min(fSneakUseDist, mActorsProcessingRange);
getObjectsInRange(position, radius, observers); getObjectsInRange(position, radius, observers);
std::set<MWWorld::Ptr> sidingActors; std::set<MWWorld::Ptr> sidingActors;
@ -1909,25 +1906,24 @@ namespace MWMechanics
int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const
{ {
auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr); const auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr);
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; const bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0;
float healthHours = healthPerHour > 0 const float healthHours = healthPerHour > 0
? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour
: 1.0f; : 1.0f;
float magickaHours = magickaPerHour > 0 && !stunted const float magickaHours = magickaPerHour > 0 && !stunted
? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour ? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour
: 1.0f; : 1.0f;
int autoHours = static_cast<int>(std::ceil(std::max(1.f, std::max(healthHours, magickaHours)))); return static_cast<int>(std::ceil(std::max(1.f, std::max(healthHours, magickaHours))));
return autoHours;
} }
int Actors::countDeaths (const std::string& id) const int Actors::countDeaths (const std::string& id) const
{ {
std::map<std::string, int>::const_iterator iter = mDeathCount.find(id); const auto iter = mDeathCount.find(id);
if(iter != mDeathCount.end()) if(iter != mDeathCount.end())
return iter->second; return iter->second;
return 0; return 0;
@ -2077,8 +2073,7 @@ namespace MWMechanics
out.insert(search->second.begin(), search->second.end()); out.insert(search->second.begin(), search->second.end());
else else
{ {
auto followers = getActorsSidingWith(actor, true); for (const MWWorld::Ptr &follower : getActorsSidingWith(actor, true))
for (const MWWorld::Ptr &follower : followers)
if (out.insert(follower).second) if (out.insert(follower).second)
getActorsSidingWith(follower, out, cachedAllies); getActorsSidingWith(follower, out, cachedAllies);
@ -2117,7 +2112,7 @@ namespace MWMechanics
{ {
if (package->followTargetThroughDoors() && package->getTarget() == actor) if (package->followTargetThroughDoors() && package->getTarget() == actor)
{ {
int index = static_cast<const AiFollow*>(package.get())->getFollowIndex(); const int index = static_cast<const AiFollow*>(package.get())->getFollowIndex();
map[index] = otherActor.getPtr(); map[index] = otherActor.getPtr();
return false; return false;
} }
@ -2131,7 +2126,7 @@ namespace MWMechanics
std::vector<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) { std::vector<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
std::vector<MWWorld::Ptr> list; std::vector<MWWorld::Ptr> list;
std::vector<MWWorld::Ptr> neighbors; std::vector<MWWorld::Ptr> neighbors;
osg::Vec3f position (actor.getRefData().getPosition().asVec3()); const osg::Vec3f position(actor.getRefData().getPosition().asVec3());
getObjectsInRange(position, mActorsProcessingRange, neighbors); getObjectsInRange(position, mActorsProcessingRange, neighbors);
for(const MWWorld::Ptr& neighbor : neighbors) for(const MWWorld::Ptr& neighbor : neighbors)
{ {