1 #ifndef GAME_MWMECHANICS_CHARACTER_HPP
2 #define GAME_MWMECHANICS_CHARACTER_HPP
3 
4 #include <deque>
5 
6 #include "../mwworld/ptr.hpp"
7 #include "../mwworld/containerstore.hpp"
8 
9 #include "../mwrender/animation.hpp"
10 
11 #include "weapontype.hpp"
12 
13 namespace MWWorld
14 {
15     class InventoryStore;
16 }
17 
18 namespace MWRender
19 {
20     class Animation;
21 }
22 
23 namespace MWMechanics
24 {
25 
26 struct Movement;
27 class CreatureStats;
28 
29 enum Priority {
30     Priority_Default,
31     Priority_WeaponLowerBody,
32     Priority_SneakIdleLowerBody,
33     Priority_SwimIdle,
34     Priority_Jump,
35     Priority_Movement,
36     Priority_Hit,
37     Priority_Weapon,
38     Priority_Block,
39     Priority_Knockdown,
40     Priority_Torch,
41     Priority_Storm,
42     Priority_Death,
43     Priority_Persistent,
44 
45     Num_Priorities
46 };
47 
48 enum CharacterState {
49     CharState_None,
50 
51     CharState_SpecialIdle,
52     CharState_Idle,
53     CharState_Idle2,
54     CharState_Idle3,
55     CharState_Idle4,
56     CharState_Idle5,
57     CharState_Idle6,
58     CharState_Idle7,
59     CharState_Idle8,
60     CharState_Idle9,
61     CharState_IdleSwim,
62     CharState_IdleSneak,
63 
64     CharState_WalkForward,
65     CharState_WalkBack,
66     CharState_WalkLeft,
67     CharState_WalkRight,
68 
69     CharState_SwimWalkForward,
70     CharState_SwimWalkBack,
71     CharState_SwimWalkLeft,
72     CharState_SwimWalkRight,
73 
74     CharState_RunForward,
75     CharState_RunBack,
76     CharState_RunLeft,
77     CharState_RunRight,
78 
79     CharState_SwimRunForward,
80     CharState_SwimRunBack,
81     CharState_SwimRunLeft,
82     CharState_SwimRunRight,
83 
84     CharState_SneakForward,
85     CharState_SneakBack,
86     CharState_SneakLeft,
87     CharState_SneakRight,
88 
89     CharState_TurnLeft,
90     CharState_TurnRight,
91     CharState_SwimTurnLeft,
92     CharState_SwimTurnRight,
93 
94     CharState_Jump,
95 
96     CharState_Death1,
97     CharState_Death2,
98     CharState_Death3,
99     CharState_Death4,
100     CharState_Death5,
101     CharState_SwimDeath,
102     CharState_SwimDeathKnockDown,
103     CharState_SwimDeathKnockOut,
104     CharState_DeathKnockDown,
105     CharState_DeathKnockOut,
106 
107     CharState_Hit,
108     CharState_SwimHit,
109     CharState_KnockDown,
110     CharState_KnockOut,
111     CharState_SwimKnockDown,
112     CharState_SwimKnockOut,
113     CharState_Block
114 };
115 
116 enum UpperBodyCharacterState {
117     UpperCharState_Nothing,
118     UpperCharState_EquipingWeap,
119     UpperCharState_UnEquipingWeap,
120     UpperCharState_WeapEquiped,
121     UpperCharState_StartToMinAttack,
122     UpperCharState_MinAttackToMaxAttack,
123     UpperCharState_MaxAttackToMinHit,
124     UpperCharState_MinHitToHit,
125     UpperCharState_FollowStartToFollowStop,
126     UpperCharState_CastingSpell
127 };
128 
129 enum JumpingState {
130     JumpState_None,
131     JumpState_InAir,
132     JumpState_Landing
133 };
134 
135 struct WeaponInfo;
136 
137 class CharacterController : public MWRender::Animation::TextKeyListener
138 {
139     MWWorld::Ptr mPtr;
140     MWWorld::Ptr mWeapon;
141     MWRender::Animation *mAnimation;
142 
143     struct AnimationQueueEntry
144     {
145         std::string mGroup;
146         size_t mLoopCount;
147         bool mPersist;
148     };
149     typedef std::deque<AnimationQueueEntry> AnimationQueue;
150     AnimationQueue mAnimQueue;
151 
152     CharacterState mIdleState;
153     std::string mCurrentIdle;
154 
155     CharacterState mMovementState;
156     std::string mCurrentMovement;
157     float mMovementAnimSpeed;
158     bool mAdjustMovementAnimSpeed;
159     bool mHasMovedInXY;
160     bool mMovementAnimationControlled;
161 
162     CharacterState mDeathState;
163     std::string mCurrentDeath;
164     bool mFloatToSurface;
165 
166     CharacterState mHitState;
167     std::string mCurrentHit;
168 
169     UpperBodyCharacterState mUpperBodyState;
170 
171     JumpingState mJumpState;
172     std::string mCurrentJump;
173 
174     int mWeaponType;
175     std::string mCurrentWeapon;
176 
177     float mAttackStrength;
178 
179     bool mSkipAnim;
180 
181     // counted for skill increase
182     float mSecondsOfSwimming;
183     float mSecondsOfRunning;
184 
185     MWWorld::ConstPtr mHeadTrackTarget;
186 
187     float mTurnAnimationThreshold; // how long to continue playing turning animation after actor stopped turning
188 
189     std::string mAttackType; // slash, chop or thrust
190 
191     bool mAttackingOrSpell;
192     bool mCastingManualSpell;
193 
194     float mTimeUntilWake;
195 
196     bool mIsMovingBackward;
197     osg::Vec2f mSmoothedSpeed;
198 
199     void setAttackTypeBasedOnMovement();
200 
201     void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false);
202     void refreshHitRecoilAnims(CharacterState& idle);
203     void refreshJumpAnims(const std::string& weapShortGroup, JumpingState jump, CharacterState& idle, bool force=false);
204     void refreshMovementAnims(const std::string& weapShortGroup, CharacterState movement, CharacterState& idle, bool force=false);
205     void refreshIdleAnims(const std::string& weapShortGroup, CharacterState idle, bool force=false);
206 
207     void clearAnimQueue(bool clearPersistAnims = false);
208 
209     bool updateWeaponState(CharacterState& idle);
210     bool updateCreatureState();
211     void updateIdleStormState(bool inwater);
212 
213     std::string chooseRandomAttackAnimation() const;
214     bool isRandomAttackAnimation(const std::string& group) const;
215 
216     bool isPersistentAnimPlaying();
217 
218     void updateAnimQueue();
219 
220     void updateHeadTracking(float duration);
221 
222     void updateMagicEffects();
223 
224     void playDeath(float startpoint, CharacterState death);
225     CharacterState chooseRandomDeathState() const;
226     void playRandomDeath(float startpoint = 0.0f);
227 
228     /// choose a random animation group with \a prefix and numeric suffix
229     /// @param num if non-nullptr, the chosen animation number will be written here
230     std::string chooseRandomGroup (const std::string& prefix, int* num = nullptr) const;
231 
232     bool updateCarriedLeftVisible(int weaptype) const;
233 
234     std::string fallbackShortWeaponGroup(const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask = nullptr);
235 
236     std::string getWeaponAnimation(int weaponType) const;
237 
238 public:
239     CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
240     virtual ~CharacterController();
241 
242     void handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override;
243 
244     // Be careful when to call this, see comment in Actors
245     void updateContinuousVfx();
246 
247     void updatePtr(const MWWorld::Ptr &ptr);
248 
249     void update(float duration);
250 
251     bool onOpen();
252     void onClose();
253 
254     void persistAnimationState();
255     void unpersistAnimationState();
256 
257     bool playGroup(const std::string &groupname, int mode, int count, bool persist=false);
258     void skipAnim();
259     bool isAnimPlaying(const std::string &groupName);
260 
261     enum KillResult
262     {
263         Result_DeathAnimStarted,
264         Result_DeathAnimPlaying,
265         Result_DeathAnimJustFinished,
266         Result_DeathAnimFinished
267     };
268     KillResult kill();
269 
270     void resurrect();
isDead() const271     bool isDead() const
272     { return mDeathState != CharState_None; }
273 
274     void forceStateUpdate();
275 
276     bool isAttackPreparing() const;
277     bool isCastingSpell() const;
278     bool isReadyToBlock() const;
279     bool isKnockedDown() const;
280     bool isKnockedOut() const;
281     bool isRecovery() const;
282     bool isSneaking() const;
283     bool isRunning() const;
284     bool isTurning() const;
285     bool isAttackingOrSpell() const;
286 
287     void setVisibility(float visibility);
288     void setAttackingOrSpell(bool attackingOrSpell);
289     void castSpell(const std::string spellId, bool manualSpell=false);
290     void setAIAttackType(const std::string& attackType);
291     static void setAttackTypeRandomly(std::string& attackType);
292 
293     bool readyToPrepareAttack() const;
294     bool readyToStartAttack() const;
295 
296     float getAttackStrength() const;
297 
298     /// @see Animation::setActive
299     void setActive(int active);
300 
301     /// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr.
302     void setHeadTrackTarget(const MWWorld::ConstPtr& target);
303 
304     void playSwishSound(float attackStrength);
305 };
306 }
307 
308 #endif /* GAME_MWMECHANICS_CHARACTER_HPP */
309