1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-20 15:40:32 +00:00
OpenMW/apps/openmw/mwmechanics/creaturestats.hpp

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

294 lines
8.7 KiB
C++
Raw Normal View History

#ifndef GAME_MWMECHANICS_CREATURESTATS_H
#define GAME_MWMECHANICS_CREATURESTATS_H
#include <map>
#include <set>
2012-07-22 18:29:54 +04:00
#include <stdexcept>
2022-09-22 21:26:05 +03:00
#include <string>
#include "activespells.hpp"
#include "aisequence.hpp"
#include "aisetting.hpp"
2022-09-22 21:26:05 +03:00
#include "drawstate.hpp"
#include "magiceffects.hpp"
#include "spells.hpp"
#include "stat.hpp"
#include <components/esm/attr.hpp>
#include <components/esm3/magiceffects.hpp>
namespace ESM
{
struct CreatureStats;
}
namespace MWMechanics
{
struct CorprusStats
{
static constexpr int sWorseningPeriod = 24;
int mWorsenings[ESM::Attribute::Length];
MWWorld::TimeStamp mNextWorsening;
};
2012-07-22 18:29:54 +04:00
/// \brief Common creature stats
///
///
class CreatureStats
{
2014-04-29 15:27:49 +02:00
static int sActorId;
DrawState mDrawState;
AttributeValue mAttributes[ESM::Attribute::Length];
2012-09-15 17:12:42 +02:00
DynamicStat<float> mDynamic[3]; // health, magicka, fatigue
Spells mSpells;
ActiveSpells mActiveSpells;
MagicEffects mMagicEffects;
Stat<int> mAiSettings[4];
AiSequence mAiSequence;
bool mDead;
bool mDeathAnimationFinished;
bool mDied; // flag for OnDeath script function
bool mMurdered;
int mFriendlyHits;
bool mTalkedTo;
bool mAlarmed;
bool mAttacked;
bool mKnockdown;
2014-04-27 20:54:22 -04:00
bool mKnockdownOneFrame;
bool mKnockdownOverOneFrame;
bool mHitRecovery;
bool mBlock;
unsigned int mMovementFlags;
2012-09-15 17:12:42 +02:00
float mFallHeight;
2013-07-26 08:08:52 -07:00
std::string mLastHitObject; // The last object to hit this actor
std::string mLastHitAttemptObject; // The last object to attempt to hit this actor
2013-07-26 08:08:52 -07:00
// For merchants: the last time items were restocked and gold pool refilled.
MWWorld::TimeStamp mLastRestock;
// The pool of merchant gold (not in inventory)
int mGoldPool;
2014-04-29 15:27:49 +02:00
int mActorId;
2017-02-06 21:32:36 +09:00
int mHitAttemptActorId; // Stores an actor that attacked this actor. Only one is stored at a time,
// and it is not changed if a different actor attacks. It is cleared when combat ends.
// The index of the death animation that was played, or -1 if none played
signed char mDeathAnimation;
MWWorld::TimeStamp mTimeOfDeath;
2020-06-22 02:03:38 +02:00
// The difference between view direction and lower body direction.
float mSideMovementAngle;
private:
std::multimap<int, int> mSummonedCreatures; // <Effect, ActorId>
// Contains ActorIds of summoned creatures with an expired lifetime that have not been deleted yet.
// This may be necessary when the creature is in an inactive cell.
std::vector<int> mSummonGraveyard;
2013-08-09 05:14:58 -07:00
protected:
int mLevel;
bool mAttackingOrSpell;
2013-08-09 05:14:58 -07:00
2012-07-22 18:29:54 +04:00
public:
2012-09-15 17:12:42 +02:00
CreatureStats();
2012-07-22 18:29:54 +04:00
DrawState getDrawState() const;
void setDrawState(DrawState state);
void recalculateMagicka();
float getFallHeight() const;
void addToFallHeight(float height);
/// Reset the fall height
/// @return total fall height
2022-09-22 21:26:05 +03:00
float land(bool isPlayer = false);
2022-09-22 21:26:05 +03:00
const AttributeValue& getAttribute(int index) const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const DynamicStat<float>& getHealth() const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const DynamicStat<float>& getMagicka() const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const DynamicStat<float>& getFatigue() const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const DynamicStat<float>& getDynamic(int index) const;
2022-09-22 21:26:05 +03:00
const Spells& getSpells() const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const ActiveSpells& getActiveSpells() const;
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
const MagicEffects& getMagicEffects() const;
2012-07-22 18:29:54 +04:00
bool getAttackingOrSpell() const { return mAttackingOrSpell; }
2013-07-13 22:24:52 +01:00
2012-07-22 18:29:54 +04:00
int getLevel() const;
2022-09-22 21:26:05 +03:00
Spells& getSpells();
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
ActiveSpells& getActiveSpells();
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
MagicEffects& getMagicEffects();
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
void setAttribute(int index, const AttributeValue& value);
// Shortcut to set only the base
void setAttribute(int index, float base);
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
void setHealth(const DynamicStat<float>& value);
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
void setMagicka(const DynamicStat<float>& value);
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
void setFatigue(const DynamicStat<float>& value);
2012-07-22 18:29:54 +04:00
2022-09-22 21:26:05 +03:00
void setDynamic(int index, const DynamicStat<float>& value);
/// Set Modifier for each magic effect according to \a effects. Does not touch Base values.
2022-09-22 21:26:05 +03:00
void modifyMagicEffects(const MagicEffects& effects);
2012-07-22 18:29:54 +04:00
void setAttackingOrSpell(bool attackingOrSpell) { mAttackingOrSpell = attackingOrSpell; }
2013-07-13 22:24:52 +01:00
2012-07-22 18:29:54 +04:00
void setLevel(int level);
2022-09-22 21:26:05 +03:00
void setAiSetting(AiSetting index, Stat<int> value);
void setAiSetting(AiSetting index, int base);
Stat<int> getAiSetting(AiSetting index) const;
const AiSequence& getAiSequence() const;
AiSequence& getAiSequence();
float getFatigueTerm() const;
///< Return effective fatigue
2012-09-15 17:12:42 +02:00
bool isParalyzed() const;
bool isDead() const;
bool isDeathAnimationFinished() const;
void setDeathAnimationFinished(bool finished);
void notifyDied();
2013-03-18 10:46:45 +01:00
bool hasDied() const;
void clearHasDied();
bool hasBeenMurdered() const;
void clearHasBeenMurdered();
void notifyMurder();
void resurrect();
2012-11-09 18:16:29 +01:00
bool hasCommonDisease() const;
bool hasBlightDisease() const;
int getFriendlyHits() const;
///< Number of friendly hits received.
void friendlyHit();
///< Increase number of friendly hits by one.
bool hasTalkedToPlayer() const;
///< Has this creature talked with the player before?
void talkedToPlayer();
bool isAlarmed() const;
2022-09-22 21:26:05 +03:00
void setAlarmed(bool alarmed);
bool getAttacked() const;
2022-09-22 21:26:05 +03:00
void setAttacked(bool attacked);
2013-07-31 12:25:14 -07:00
float getEvasion() const;
void setKnockedDown(bool value);
/// Returns true for the entire duration of the actor being knocked down or knocked out,
/// including transition animations (falling down & standing up)
bool getKnockedDown() const;
2014-04-27 20:54:22 -04:00
void setKnockedDownOneFrame(bool value);
2022-09-22 21:26:05 +03:00
/// Returns true only for the first frame of the actor being knocked out; used for "onKnockedOut" command
2014-04-27 20:54:22 -04:00
bool getKnockedDownOneFrame() const;
void setKnockedDownOverOneFrame(bool value);
2022-09-22 21:26:05 +03:00
/// Returns true for all but the first frame of being knocked out; used to know to not reset
/// mKnockedDownOneFrame
2014-04-27 20:54:22 -04:00
bool getKnockedDownOverOneFrame() const;
void setHitRecovery(bool value);
bool getHitRecovery() const;
void setBlock(bool value);
bool getBlock() const;
std::multimap<int, int>& getSummonedCreatureMap(); // <Effect, ActorId of summoned creature>
std::vector<int>& getSummonedCreatureGraveyard(); // ActorIds
enum Flag
{
Flag_ForceRun = 1,
Flag_ForceSneak = 2,
Flag_Run = 4,
2014-08-02 22:42:40 -07:00
Flag_Sneak = 8,
Flag_ForceJump = 16,
Flag_ForceMoveJump = 32
};
enum Stance
{
Stance_Run,
Stance_Sneak
};
2022-09-22 21:26:05 +03:00
bool getMovementFlag(Flag flag) const;
void setMovementFlag(Flag flag, bool state);
/// Like getMovementFlag, but also takes into account if the flag is Forced
2022-09-22 21:26:05 +03:00
bool getStance(Stance flag) const;
2022-09-22 21:26:05 +03:00
void setLastHitObject(const std::string& objectid);
void clearLastHitObject();
2022-09-22 21:26:05 +03:00
const std::string& getLastHitObject() const;
void setLastHitAttemptObject(const std::string& objectid);
void clearLastHitAttemptObject();
2022-09-22 21:26:05 +03:00
const std::string& getLastHitAttemptObject() const;
2017-02-06 21:32:36 +09:00
void setHitAttemptActorId(const int actorId);
int getHitAttemptActorId() const;
2022-09-22 21:26:05 +03:00
void writeState(ESM::CreatureStats& state) const;
2022-09-22 21:26:05 +03:00
void readState(const ESM::CreatureStats& state);
2022-09-22 21:26:05 +03:00
static void writeActorIdCounter(ESM::ESMWriter& esm);
static void readActorIdCounter(ESM::ESMReader& esm);
2014-05-14 09:47:49 +02:00
void setLastRestockTime(MWWorld::TimeStamp tradeTime);
MWWorld::TimeStamp getLastRestockTime() const;
void setGoldPool(int pool);
int getGoldPool() const;
2014-04-29 15:27:49 +02:00
signed char getDeathAnimation() const; // -1 means not decided
void setDeathAnimation(signed char index);
MWWorld::TimeStamp getTimeOfDeath() const;
2014-04-29 15:27:49 +02:00
int getActorId();
///< Will generate an actor ID, if the actor does not have one yet.
2022-09-22 21:26:05 +03:00
bool matchesActorId(int id) const;
2014-04-29 15:27:49 +02:00
///< Check if \a id matches the actor ID of *this (if the actor does not have an ID
/// assigned this function will return false).
2014-04-29 19:56:33 +02:00
static void cleanup();
2020-06-22 02:03:38 +02:00
float getSideMovementAngle() const { return mSideMovementAngle; }
void setSideMovementAngle(float angle) { mSideMovementAngle = angle; }
};
}
#endif