1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-31 06:32:39 +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.

326 lines
8.9 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;
bool mInJump{ false };
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;
void prepareHit();
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;
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID Slowly going through all the changes to make, still hundreds of errors a lot of functions/structures use std::string or stringview to designate an ID. So it takes time Continues slowly replacing ids. There are technically more and more compilation errors I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type Continue moving forward, changes to the stores slowly moving along Starting to see the fruit of those changes. still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type. More replacements. Things are starting to get easier I can see more and more often the issue is that the function is awaiting a RefId, but is given a string there is less need to go down functions and to fix a long list of them. Still moving forward, and for the first time error count is going down! Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably Cells are back to using string for the name, haven't fixed everything yet. Many other changes Under the bar of 400 compilation errors. more good progress <100 compile errors! More progress Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string some more progress on other fronts Mostly game settings clean one error opened a lot of other errors. Down to 18, but more will prbably appear only link errors left?? Fixed link errors OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
void castSpell(const ESM::RefId& 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;
MWWorld::MovementDirectionFlags getSupportedMovementDirections() const;
};
}
#endif /* GAME_MWMECHANICS_CHARACTER_HPP */