mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Make greeting-related actor data temporary (bug #5397)
This commit is contained in:
parent
505a5e9ca6
commit
efd5f13b2b
14 changed files with 173 additions and 95 deletions
|
@ -13,6 +13,7 @@
|
||||||
Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound
|
Bug #5367: Selecting a spell on an enchanted item per hotkey always plays the equip sound
|
||||||
Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures
|
Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures
|
||||||
Bug #5370: Opening an unlocked but trapped door uses the key
|
Bug #5370: Opening an unlocked but trapped door uses the key
|
||||||
|
Bug #5397: NPC greeting does not reset if you leave + reenter area
|
||||||
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
|
Bug #5400: Editor: Verifier checks race of non-skin bodyparts
|
||||||
Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work
|
Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work
|
||||||
Bug #5416: Junk non-node records before the root node are not handled gracefully
|
Bug #5416: Junk non-node records before the root node are not handled gracefully
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
// For MWMechanics::GreetingState
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
|
@ -272,6 +275,11 @@ namespace MWBase
|
||||||
virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0;
|
virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
|
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;
|
||||||
|
|
||||||
|
virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
virtual MWMechanics::GreetingState getGreetingState(const MWWorld::Ptr& ptr) const = 0;
|
||||||
|
virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,4 +18,44 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
return mCharacterController.get();
|
return mCharacterController.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Actor::getGreetingTimer() const
|
||||||
|
{
|
||||||
|
return mGreetingTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setGreetingTimer(int timer)
|
||||||
|
{
|
||||||
|
mGreetingTimer = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Actor::getAngleToPlayer() const
|
||||||
|
{
|
||||||
|
return mTargetAngleRadians;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setAngleToPlayer(float angle)
|
||||||
|
{
|
||||||
|
mTargetAngleRadians = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
GreetingState Actor::getGreetingState() const
|
||||||
|
{
|
||||||
|
return mGreetingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setGreetingState(GreetingState state)
|
||||||
|
{
|
||||||
|
mGreetingState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Actor::isTurningToPlayer() const
|
||||||
|
{
|
||||||
|
return mIsTurningToPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setTurningToPlayer(bool turning)
|
||||||
|
{
|
||||||
|
mIsTurningToPlayer = turning;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class Animation;
|
class Animation;
|
||||||
|
@ -27,8 +29,24 @@ namespace MWMechanics
|
||||||
|
|
||||||
CharacterController* getCharacterController();
|
CharacterController* getCharacterController();
|
||||||
|
|
||||||
|
int getGreetingTimer() const;
|
||||||
|
void setGreetingTimer(int timer);
|
||||||
|
|
||||||
|
float getAngleToPlayer() const;
|
||||||
|
void setAngleToPlayer(float angle);
|
||||||
|
|
||||||
|
GreetingState getGreetingState() const;
|
||||||
|
void setGreetingState(GreetingState state);
|
||||||
|
|
||||||
|
bool isTurningToPlayer() const;
|
||||||
|
void setTurningToPlayer(bool turning);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<CharacterController> mCharacterController;
|
std::unique_ptr<CharacterController> mCharacterController;
|
||||||
|
int mGreetingTimer{0};
|
||||||
|
float mTargetAngleRadians{0.f};
|
||||||
|
GreetingState mGreetingState{Greet_None};
|
||||||
|
bool mIsTurningToPlayer{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -447,7 +447,7 @@ namespace MWMechanics
|
||||||
actor.getClass().getMovementSettings(actor).mSpeedFactor = newSpeedFactor;
|
actor.getClass().getMovementSettings(actor).mSpeedFactor = newSpeedFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::updateGreetingState(const MWWorld::Ptr& actor, bool turnOnly)
|
void Actors::updateGreetingState(const MWWorld::Ptr& actor, Actor* actorState, bool turnOnly)
|
||||||
{
|
{
|
||||||
if (!actor.getClass().isActor() || actor == getPlayer())
|
if (!actor.getClass().isActor() || actor == getPlayer())
|
||||||
return;
|
return;
|
||||||
|
@ -460,9 +460,9 @@ namespace MWMechanics
|
||||||
MWBase::Environment::get().getWorld()->isSwimming(actor) ||
|
MWBase::Environment::get().getWorld()->isSwimming(actor) ||
|
||||||
(packageId != AiPackage::TypeIdWander && packageId != AiPackage::TypeIdTravel && packageId != -1))
|
(packageId != AiPackage::TypeIdWander && packageId != AiPackage::TypeIdTravel && packageId != -1))
|
||||||
{
|
{
|
||||||
stats.setTurningToPlayer(false);
|
actorState->setTurningToPlayer(false);
|
||||||
stats.setGreetingTimer(0);
|
actorState->setGreetingTimer(0);
|
||||||
stats.setGreetingState(Greet_None);
|
actorState->setGreetingState(Greet_None);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,14 +471,14 @@ namespace MWMechanics
|
||||||
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||||
osg::Vec3f dir = playerPos - actorPos;
|
osg::Vec3f dir = playerPos - actorPos;
|
||||||
|
|
||||||
if (stats.isTurningToPlayer())
|
if (actorState->isTurningToPlayer())
|
||||||
{
|
{
|
||||||
// Reduce the turning animation glitch by using a *HUGE* value of
|
// Reduce the turning animation glitch by using a *HUGE* value of
|
||||||
// epsilon... TODO: a proper fix might be in either the physics or the
|
// epsilon... TODO: a proper fix might be in either the physics or the
|
||||||
// animation subsystem
|
// animation subsystem
|
||||||
if (zTurn(actor, stats.getAngleToPlayer(), osg::DegreesToRadians(5.f)))
|
if (zTurn(actor, actorState->getAngleToPlayer(), osg::DegreesToRadians(5.f)))
|
||||||
{
|
{
|
||||||
stats.setTurningToPlayer(false);
|
actorState->setTurningToPlayer(false);
|
||||||
// An original engine launches an endless idle2 when an actor greets player.
|
// An original engine launches an endless idle2 when an actor greets player.
|
||||||
playAnimationGroup (actor, "idle2", 0, std::numeric_limits<int>::max(), false);
|
playAnimationGroup (actor, "idle2", 0, std::numeric_limits<int>::max(), false);
|
||||||
}
|
}
|
||||||
|
@ -493,8 +493,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
float helloDistance = static_cast<float>(stats.getAiSetting(CreatureStats::AI_Hello).getModified() * iGreetDistanceMultiplier);
|
float helloDistance = static_cast<float>(stats.getAiSetting(CreatureStats::AI_Hello).getModified() * iGreetDistanceMultiplier);
|
||||||
|
|
||||||
int greetingTimer = stats.getGreetingTimer();
|
int greetingTimer = actorState->getGreetingTimer();
|
||||||
GreetingState greetingState = stats.getGreetingState();
|
GreetingState greetingState = actorState->getGreetingState();
|
||||||
if (greetingState == Greet_None)
|
if (greetingState == Greet_None)
|
||||||
{
|
{
|
||||||
if ((playerPos - actorPos).length2() <= helloDistance*helloDistance &&
|
if ((playerPos - actorPos).length2() <= helloDistance*helloDistance &&
|
||||||
|
@ -516,7 +516,7 @@ namespace MWMechanics
|
||||||
greetingTimer++;
|
greetingTimer++;
|
||||||
|
|
||||||
if (greetingTimer <= GREETING_SHOULD_END || MWBase::Environment::get().getSoundManager()->sayActive(actor))
|
if (greetingTimer <= GREETING_SHOULD_END || MWBase::Environment::get().getSoundManager()->sayActive(actor))
|
||||||
turnActorToFacePlayer(actor, dir);
|
turnActorToFacePlayer(actor, actorState, dir);
|
||||||
|
|
||||||
if (greetingTimer >= GREETING_COOLDOWN)
|
if (greetingTimer >= GREETING_COOLDOWN)
|
||||||
{
|
{
|
||||||
|
@ -532,20 +532,19 @@ namespace MWMechanics
|
||||||
greetingState = Greet_None;
|
greetingState = Greet_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.setGreetingTimer(greetingTimer);
|
actorState->setGreetingTimer(greetingTimer);
|
||||||
stats.setGreetingState(greetingState);
|
actorState->setGreetingState(greetingState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::turnActorToFacePlayer(const MWWorld::Ptr& actor, const osg::Vec3f& dir)
|
void Actors::turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor* actorState, const osg::Vec3f& dir)
|
||||||
{
|
{
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||||
actor.getClass().getMovementSettings(actor).mPosition[0] = 0;
|
actor.getClass().getMovementSettings(actor).mPosition[0] = 0;
|
||||||
|
|
||||||
CreatureStats &stats = actor.getClass().getCreatureStats(actor);
|
if (!actorState->isTurningToPlayer())
|
||||||
if (!stats.isTurningToPlayer())
|
|
||||||
{
|
{
|
||||||
stats.setAngleToPlayer(std::atan2(dir.x(), dir.y()));
|
actorState->setAngleToPlayer(std::atan2(dir.x(), dir.y()));
|
||||||
stats.setTurningToPlayer(true);
|
actorState->setTurningToPlayer(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1695,7 +1694,7 @@ namespace MWMechanics
|
||||||
if (isConscious(iter->first))
|
if (isConscious(iter->first))
|
||||||
{
|
{
|
||||||
stats.getAiSequence().execute(iter->first, *ctrl, duration);
|
stats.getAiSequence().execute(iter->first, *ctrl, duration);
|
||||||
updateGreetingState(iter->first, timerUpdateHello > 0);
|
updateGreetingState(iter->first, iter->second, timerUpdateHello > 0);
|
||||||
playIdleDialogue(iter->first);
|
playIdleDialogue(iter->first);
|
||||||
updateMovementSpeed(iter->first);
|
updateMovementSpeed(iter->first);
|
||||||
}
|
}
|
||||||
|
@ -2390,6 +2389,42 @@ namespace MWMechanics
|
||||||
return ctrl->isAttackingOrSpell();
|
return ctrl->isAttackingOrSpell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Actors::getGreetingTimer(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
PtrActorMap::const_iterator it = mActors.find(ptr);
|
||||||
|
if (it == mActors.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return it->second->getGreetingTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Actors::getAngleToPlayer(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
PtrActorMap::const_iterator it = mActors.find(ptr);
|
||||||
|
if (it == mActors.end())
|
||||||
|
return 0.f;
|
||||||
|
|
||||||
|
return it->second->getAngleToPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
GreetingState Actors::getGreetingState(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
PtrActorMap::const_iterator it = mActors.find(ptr);
|
||||||
|
if (it == mActors.end())
|
||||||
|
return Greet_None;
|
||||||
|
|
||||||
|
return it->second->getGreetingState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Actors::isTurningToPlayer(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
PtrActorMap::const_iterator it = mActors.find(ptr);
|
||||||
|
if (it == mActors.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return it->second->isTurningToPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
void Actors::fastForwardAi()
|
void Actors::fastForwardAi()
|
||||||
{
|
{
|
||||||
if (!MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
if (!MWBase::Environment::get().getMechanicsManager()->isAIActive())
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
@ -123,8 +125,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
void playIdleDialogue(const MWWorld::Ptr& actor);
|
void playIdleDialogue(const MWWorld::Ptr& actor);
|
||||||
void updateMovementSpeed(const MWWorld::Ptr& actor);
|
void updateMovementSpeed(const MWWorld::Ptr& actor);
|
||||||
void updateGreetingState(const MWWorld::Ptr& actor, bool turnOnly);
|
void updateGreetingState(const MWWorld::Ptr& actor, Actor* actorState, bool turnOnly);
|
||||||
void turnActorToFacePlayer(const MWWorld::Ptr& actor, const osg::Vec3f& dir);
|
void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor* actorState, const osg::Vec3f& dir);
|
||||||
|
|
||||||
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
|
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
|
||||||
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
|
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
|
||||||
|
@ -195,6 +197,11 @@ namespace MWMechanics
|
||||||
bool isReadyToBlock(const MWWorld::Ptr& ptr) const;
|
bool isReadyToBlock(const MWWorld::Ptr& ptr) const;
|
||||||
bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const;
|
bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
int getGreetingTimer(const MWWorld::Ptr& ptr) const;
|
||||||
|
float getAngleToPlayer(const MWWorld::Ptr& ptr) const;
|
||||||
|
GreetingState getGreetingState(const MWWorld::Ptr& ptr) const;
|
||||||
|
bool isTurningToPlayer(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl);
|
void updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,13 @@ namespace MWWorld
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
enum GreetingState
|
||||||
|
{
|
||||||
|
Greet_None,
|
||||||
|
Greet_InProgress,
|
||||||
|
Greet_Done
|
||||||
|
};
|
||||||
|
|
||||||
MWWorld::Ptr getPlayer();
|
MWWorld::Ptr getPlayer();
|
||||||
bool isPlayerInCombat();
|
bool isPlayerInCombat();
|
||||||
bool canActorMoveByZAxis(const MWWorld::Ptr& actor);
|
bool canActorMoveByZAxis(const MWWorld::Ptr& actor);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <components/esm/aisequence.hpp>
|
#include <components/esm/aisequence.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
@ -43,14 +44,15 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
auto& stats = actor.getClass().getCreatureStats(actor);
|
MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager();
|
||||||
|
|
||||||
if (stats.isTurningToPlayer() || stats.getGreetingState() == Greet_InProgress)
|
if (mechMgr->isTurningToPlayer(actor) || mechMgr->getGreetingState(actor) == Greet_InProgress)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||||
const osg::Vec3f targetPos(mX, mY, mZ);
|
const osg::Vec3f targetPos(mX, mY, mZ);
|
||||||
|
|
||||||
|
auto& stats = actor.getClass().getCreatureStats(actor);
|
||||||
stats.setMovementFlag(CreatureStats::Flag_Run, false);
|
stats.setMovementFlag(CreatureStats::Flag_Run, false);
|
||||||
stats.setDrawState(DrawState_Nothing);
|
stats.setDrawState(DrawState_Nothing);
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ namespace MWMechanics
|
||||||
storage.setState(AiWanderStorage::Wander_Walking);
|
storage.setState(AiWanderStorage::Wander_Walking);
|
||||||
}
|
}
|
||||||
|
|
||||||
GreetingState greetingState = cStats.getGreetingState();
|
GreetingState greetingState = MWBase::Environment::get().getMechanicsManager()->getGreetingState(actor);
|
||||||
if (greetingState == Greet_InProgress)
|
if (greetingState == Greet_InProgress)
|
||||||
{
|
{
|
||||||
if (storage.mState == AiWanderStorage::Wander_Walking)
|
if (storage.mState == AiWanderStorage::Wander_Walking)
|
||||||
|
@ -442,7 +442,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if idle animation finished
|
// Check if idle animation finished
|
||||||
GreetingState greetingState = actor.getClass().getCreatureStats(actor).getGreetingState();
|
GreetingState greetingState = MWBase::Environment::get().getMechanicsManager()->getGreetingState(actor);
|
||||||
if (!checkIdle(actor, storage.mIdleAnimation) && (greetingState == Greet_Done || greetingState == Greet_None))
|
if (!checkIdle(actor, storage.mIdleAnimation) && (greetingState == Greet_Done || greetingState == Greet_None))
|
||||||
{
|
{
|
||||||
if (mPathFinder.isPathConstructed())
|
if (mPathFinder.isPathConstructed())
|
||||||
|
|
|
@ -23,53 +23,12 @@ namespace MWMechanics
|
||||||
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
||||||
mHitRecovery(false), mBlock(false), mMovementFlags(0),
|
mHitRecovery(false), mBlock(false), mMovementFlags(0),
|
||||||
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1), mHitAttemptActorId(-1),
|
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1), mHitAttemptActorId(-1),
|
||||||
mDeathAnimation(-1), mTimeOfDeath(), mGreetingState(Greet_None),
|
mDeathAnimation(-1), mTimeOfDeath(), mLevel (0)
|
||||||
mGreetingTimer(0), mTargetAngleRadians(0), mIsTurningToPlayer(false), mLevel (0)
|
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; ++i)
|
for (int i=0; i<4; ++i)
|
||||||
mAiSettings[i] = 0;
|
mAiSettings[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWMechanics::CreatureStats::getGreetingTimer() const
|
|
||||||
{
|
|
||||||
return mGreetingTimer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWMechanics::CreatureStats::setGreetingTimer(int timer)
|
|
||||||
{
|
|
||||||
mGreetingTimer = timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
float MWMechanics::CreatureStats::getAngleToPlayer() const
|
|
||||||
{
|
|
||||||
return mTargetAngleRadians;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWMechanics::CreatureStats::setAngleToPlayer(float angle)
|
|
||||||
{
|
|
||||||
mTargetAngleRadians = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
GreetingState MWMechanics::CreatureStats::getGreetingState() const
|
|
||||||
{
|
|
||||||
return mGreetingState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWMechanics::CreatureStats::setGreetingState(GreetingState state)
|
|
||||||
{
|
|
||||||
mGreetingState = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MWMechanics::CreatureStats::isTurningToPlayer() const
|
|
||||||
{
|
|
||||||
return mIsTurningToPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWMechanics::CreatureStats::setTurningToPlayer(bool turning)
|
|
||||||
{
|
|
||||||
mIsTurningToPlayer = turning;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AiSequence& CreatureStats::getAiSequence() const
|
const AiSequence& CreatureStats::getAiSequence() const
|
||||||
{
|
{
|
||||||
return mAiSequence;
|
return mAiSequence;
|
||||||
|
|
|
@ -19,13 +19,6 @@ namespace ESM
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
enum GreetingState
|
|
||||||
{
|
|
||||||
Greet_None,
|
|
||||||
Greet_InProgress,
|
|
||||||
Greet_Done
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Common creature stats
|
/// \brief Common creature stats
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
|
@ -77,11 +70,6 @@ namespace MWMechanics
|
||||||
|
|
||||||
MWWorld::TimeStamp mTimeOfDeath;
|
MWWorld::TimeStamp mTimeOfDeath;
|
||||||
|
|
||||||
GreetingState mGreetingState;
|
|
||||||
int mGreetingTimer;
|
|
||||||
float mTargetAngleRadians;
|
|
||||||
bool mIsTurningToPlayer;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::pair<int, std::string> SummonKey; // <ESM::MagicEffect index, spell ID>
|
typedef std::pair<int, std::string> SummonKey; // <ESM::MagicEffect index, spell ID>
|
||||||
private:
|
private:
|
||||||
|
@ -97,18 +85,6 @@ namespace MWMechanics
|
||||||
public:
|
public:
|
||||||
CreatureStats();
|
CreatureStats();
|
||||||
|
|
||||||
int getGreetingTimer() const;
|
|
||||||
void setGreetingTimer(int timer);
|
|
||||||
|
|
||||||
float getAngleToPlayer() const;
|
|
||||||
void setAngleToPlayer(float angle);
|
|
||||||
|
|
||||||
GreetingState getGreetingState() const;
|
|
||||||
void setGreetingState(GreetingState state);
|
|
||||||
|
|
||||||
bool isTurningToPlayer() const;
|
|
||||||
void setTurningToPlayer(bool turning);
|
|
||||||
|
|
||||||
DrawState_ getDrawState() const;
|
DrawState_ getDrawState() const;
|
||||||
void setDrawState(DrawState_ state);
|
void setDrawState(DrawState_ state);
|
||||||
|
|
||||||
|
|
|
@ -1951,4 +1951,24 @@ namespace MWMechanics
|
||||||
stats.setAttribute(frameNumber, "Mechanics Actors", mActors.size());
|
stats.setAttribute(frameNumber, "Mechanics Actors", mActors.size());
|
||||||
stats.setAttribute(frameNumber, "Mechanics Objects", mObjects.size());
|
stats.setAttribute(frameNumber, "Mechanics Objects", mObjects.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MechanicsManager::getGreetingTimer(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return mActors.getGreetingTimer(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MechanicsManager::getAngleToPlayer(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return mActors.getAngleToPlayer(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
GreetingState MechanicsManager::getGreetingState(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return mActors.getGreetingState(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MechanicsManager::isTurningToPlayer(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return mActors.isTurningToPlayer(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,6 +242,11 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const override;
|
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const override;
|
||||||
|
|
||||||
|
virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const override;
|
||||||
|
virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const override;
|
||||||
|
virtual GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override;
|
||||||
|
virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
|
||||||
bool canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set<MWWorld::Ptr> &playerFollowers);
|
bool canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set<MWWorld::Ptr> &playerFollowers);
|
||||||
|
|
|
@ -430,13 +430,13 @@ namespace MWScript
|
||||||
if (!targetPtr.isEmpty() && targetPtr.getCellRef().getRefId() == testedTargetId)
|
if (!targetPtr.isEmpty() && targetPtr.getCellRef().getRefId() == testedTargetId)
|
||||||
targetsAreEqual = true;
|
targetsAreEqual = true;
|
||||||
}
|
}
|
||||||
else
|
else if (testedTargetId == "player") // Currently the player ID is hardcoded
|
||||||
{
|
{
|
||||||
bool turningToPlayer = creatureStats.isTurningToPlayer();
|
MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager();
|
||||||
bool greeting = creatureStats.getGreetingState() == MWMechanics::Greet_InProgress;
|
bool greeting = mechMgr->getGreetingState(actor) == MWMechanics::Greet_InProgress;
|
||||||
bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor);
|
bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor);
|
||||||
if (turningToPlayer || (greeting && sayActive))
|
if ((greeting && sayActive) || mechMgr->isTurningToPlayer(actor))
|
||||||
targetsAreEqual = (testedTargetId == "player"); // Currently the player ID is hardcoded
|
targetsAreEqual = true;
|
||||||
}
|
}
|
||||||
runtime.push(int(targetsAreEqual));
|
runtime.push(int(targetsAreEqual));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue