1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-04 12:39:55 +00:00
OpenMW/apps/openmw/mwmechanics/character.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

321 lines
8.8 KiB
C++
Raw Normal View History

#ifndef GAME_MWMECHANICS_CHARACTER_HPP
#define GAME_MWMECHANICS_CHARACTER_HPP
2015-06-03 23:04:35 +02:00
#include <deque>
#include <components/esm3/loadweap.hpp>
#include "../mwworld/ptr.hpp"
2015-05-22 00:55:43 +02:00
#include "../mwrender/animation.hpp"
namespace MWWorld
{
class InventoryStore;
}
namespace MWRender
{
class Animation;
}
namespace MWMechanics
{
struct Movement;
class CreatureStats;
2022-09-22 21:26:05 +03:00
2013-05-13 00:54:44 -07:00
enum Priority
{
Priority_Default,
2015-07-26 01:35:36 +02:00
Priority_WeaponLowerBody,
Priority_SneakIdleLowerBody,
Priority_SwimIdle,
Priority_Jump,
Priority_Movement,
2013-12-31 13:24:20 +02:00
Priority_Hit,
Priority_Weapon,
Priority_Block,
2014-01-08 16:05:14 +02:00
Priority_Knockdown,
Priority_Torch,
Priority_Storm,
2013-05-13 00:54:44 -07:00
Priority_Death,
Priority_Persistent,
2022-09-22 21:26:05 +03:00
2013-05-13 00:54:44 -07:00
Num_Priorities
};
2022-09-22 21:26:05 +03:00
enum CharacterState
{
CharState_None,
2022-09-22 21:26:05 +03:00
CharState_SpecialIdle,
CharState_Idle,
2013-02-05 19:05:07 -08:00
CharState_IdleSwim,
2013-03-06 16:58:56 +01:00
CharState_IdleSneak,
2022-09-22 21:26:05 +03:00
CharState_WalkForward,
CharState_WalkBack,
CharState_WalkLeft,
CharState_WalkRight,
2022-09-22 21:26:05 +03:00
2013-02-05 19:05:07 -08:00
CharState_SwimWalkForward,
CharState_SwimWalkBack,
CharState_SwimWalkLeft,
CharState_SwimWalkRight,
2022-09-22 21:26:05 +03:00
2013-02-06 16:53:52 -08:00
CharState_RunForward,
CharState_RunBack,
CharState_RunLeft,
CharState_RunRight,
2022-09-22 21:26:05 +03:00
2013-02-06 16:53:52 -08:00
CharState_SwimRunForward,
CharState_SwimRunBack,
CharState_SwimRunLeft,
CharState_SwimRunRight,
2022-09-22 21:26:05 +03:00
2013-03-06 16:58:56 +01:00
CharState_SneakForward,
CharState_SneakBack,
CharState_SneakLeft,
CharState_SneakRight,
2022-09-22 21:26:05 +03:00
2013-03-31 03:50:20 -07:00
CharState_TurnLeft,
CharState_TurnRight,
CharState_SwimTurnLeft,
CharState_SwimTurnRight,
2022-09-22 21:26:05 +03:00
2013-02-03 00:19:22 -08:00
CharState_Death1,
CharState_Death2,
CharState_Death3,
CharState_Death4,
CharState_Death5,
CharState_SwimDeath,
CharState_SwimDeathKnockDown,
CharState_SwimDeathKnockOut,
CharState_DeathKnockDown,
CharState_DeathKnockOut,
2022-09-22 21:26:05 +03:00
2014-01-02 21:54:41 +02:00
CharState_Hit,
2017-09-22 15:26:35 +04:00
CharState_SwimHit,
CharState_KnockDown,
CharState_KnockOut,
CharState_SwimKnockDown,
2013-08-18 23:42:56 -07:00
CharState_SwimKnockOut,
CharState_Block
2013-08-18 23:42:56 -07:00
};
2022-09-22 21:26:05 +03:00
2015-05-22 00:55:43 +02:00
enum class UpperBodyState
2022-09-22 21:26:05 +03:00
{
2015-05-22 00:55:43 +02:00
None,
Equipping,
Unequipping,
WeaponEquipped,
AttackWindUp,
AttackRelease,
AttackEnd,
Casting
};
2022-09-22 21:26:05 +03:00
enum JumpingState
{
JumpState_None,
JumpState_InAir,
JumpState_Landing
};
struct WeaponInfo;
class CharacterController : public MWRender::Animation::TextKeyListener
2022-09-22 21:26:05 +03:00
{
MWWorld::Ptr mPtr;
MWWorld::Ptr mWeapon;
MWRender::Animation* mAnimation;
struct AnimationQueueEntry
2022-09-22 21:26:05 +03:00
{
std::string mGroup;
size_t mLoopCount;
bool mPersist;
};
typedef std::deque<AnimationQueueEntry> AnimationQueue;
AnimationQueue mAnimQueue;
CharacterState mIdleState{ CharState_None };
2013-12-31 13:24:20 +02:00
std::string mCurrentIdle;
CharacterState mMovementState{ CharState_None };
std::string mCurrentMovement;
float mMovementAnimSpeed{ 0.f };
bool mAdjustMovementAnimSpeed{ false };
bool mMovementAnimationControlled{ true };
CharacterState mDeathState{ CharState_None };
2013-08-19 08:10:18 -07:00
std::string mCurrentDeath;
bool mFloatToSurface{ true };
2013-08-18 23:42:56 -07:00
CharacterState mHitState{ CharState_None };
2013-07-23 02:50:52 -07:00
std::string mCurrentHit;
UpperBodyState mUpperBodyState{ UpperBodyState::None };
JumpingState mJumpState{ JumpState_None };
std::string mCurrentJump;
int mWeaponType{ ESM::Weapon::None };
std::string mCurrentWeapon;
2013-04-28 07:53:04 +02:00
float mAttackStrength{ -1.f };
MWWorld::Ptr mAttackVictim;
osg::Vec3f mAttackHitPos;
bool mAttackSuccess{ false };
bool mSkipAnim{ false };
// counted for skill increase
float mSecondsOfSwimming{ 0.f };
float mSecondsOfRunning{ 0.f };
MWWorld::ConstPtr mHeadTrackTarget;
float mTurnAnimationThreshold{
2022-09-22 21:26:05 +03:00
0.f
}; // how long to continue playing turning animation after actor stopped turning
2020-09-04 15:03:33 +02:00
std::string mAttackType; // slash, chop or thrust
bool mCanCast{ false };
bool mCastingManualSpell{ false };
bool mIsMovingBackward{ false };
osg::Vec2f mSmoothedSpeed;
std::string_view getMovementBasedAttackType() const;
void clearStateAnimation(std::string& anim) const;
void resetCurrentJumpState();
void resetCurrentMovementState();
void resetCurrentIdleState();
void resetCurrentHitState();
void resetCurrentWeaponState();
void resetCurrentDeathState();
void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force = false);
void refreshHitRecoilAnims();
void refreshJumpAnims(JumpingState jump, bool force = false);
void refreshMovementAnims(CharacterState movement, bool force = false);
void refreshIdleAnims(CharacterState idle, bool force = false);
void clearAnimQueue(bool clearPersistAnims = false);
2016-08-22 23:02:57 +02:00
bool updateWeaponState();
void updateIdleStormState(bool inwater) const;
std::string chooseRandomAttackAnimation() const;
static bool isRandomAttackAnimation(std::string_view group);
bool isPersistentAnimPlaying() const;
void updateAnimQueue();
2013-12-31 13:24:20 +02:00
2018-10-09 10:21:12 +04:00
void updateHeadTracking(float duration);
void updateMagicEffects() const;
void playDeath(float startpoint, CharacterState death);
CharacterState chooseRandomDeathState() const;
void playRandomDeath(float startpoint = 0.0f);
2019-08-09 12:10:28 +04:00
/// choose a random animation group with \a prefix and numeric suffix
/// @param num if non-nullptr, the chosen animation number will be written here
std::string chooseRandomGroup(const std::string& prefix, int* num = nullptr) const;
2019-08-09 12:58:20 +04:00
bool updateCarriedLeftVisible(int weaptype) const;
std::string fallbackShortWeaponGroup(
const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask = nullptr) const;
std::string_view getWeaponAnimation(int weaponType) const;
std::string_view getWeaponShortGroup(int weaponType) const;
bool getAttackingOrSpell() const;
void setAttackingOrSpell(bool attackingOrSpell) const;
2022-09-22 21:26:05 +03:00
public:
CharacterController(const MWWorld::Ptr& ptr, MWRender::Animation* anim);
virtual ~CharacterController();
2015-05-22 00:55:43 +02:00
CharacterController(const CharacterController&) = delete;
CharacterController(CharacterController&&) = delete;
const MWWorld::Ptr& getPtr() const { return mPtr; }
void handleTextKey(std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key,
const SceneUtil::TextKeyMap& map) override;
// Be careful when to call this, see comment in Actors
void updateContinuousVfx() const;
void updatePtr(const MWWorld::Ptr& ptr);
void update(float duration);
bool onOpen() const;
void onClose() const;
2014-05-14 07:14:08 +02:00
void persistAnimationState() const;
void unpersistAnimationState();
bool playGroup(std::string_view groupname, int mode, int count, bool persist = false);
void skipAnim();
bool isAnimPlaying(std::string_view groupName) const;
enum KillResult
2022-09-22 21:26:05 +03:00
{
Result_DeathAnimStarted,
Result_DeathAnimPlaying,
Result_DeathAnimJustFinished,
Result_DeathAnimFinished
2022-09-22 21:26:05 +03:00
};
KillResult kill();
void resurrect();
2015-07-03 05:58:12 +02:00
bool isDead() const { return mDeathState != CharState_None; }
void forceStateUpdate();
2015-07-03 05:58:12 +02:00
bool isAttackPreparing() const;
bool isCastingSpell() const;
2015-07-03 05:58:12 +02:00
bool isReadyToBlock() const;
2017-09-22 15:26:35 +04:00
bool isKnockedDown() const;
bool isKnockedOut() const;
2017-09-22 15:49:42 +04:00
bool isRecovery() const;
bool isSneaking() const;
bool isRunning() const;
bool isTurning() const;
2015-07-03 05:58:12 +02:00
bool isAttackingOrSpell() const;
void setVisibility(float visibility) const;
void castSpell(const std::string& spellId, bool manualSpell = false);
void setAIAttackType(std::string_view attackType);
static std::string_view getRandomAttackType();
bool readyToPrepareAttack() const;
bool readyToStartAttack() const;
float calculateWindUp() const;
2022-09-22 21:26:05 +03:00
float getAttackStrength() const;
2022-09-22 21:26:05 +03:00
/// @see Animation::setActive
2022-06-12 03:02:23 +03:00
void setActive(int active) const;
2022-09-22 21:26:05 +03:00
/// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr.
void setHeadTrackTarget(const MWWorld::ConstPtr& target);
2022-09-22 21:26:05 +03:00
void playSwishSound() const;
};
}
#endif /* GAME_MWMECHANICS_CHARACTER_HPP */