Issue #777: Handle creatures with weapons in CharacterController. Move attack strength to CreatureStats.

This commit is contained in:
scrawl 2014-01-19 13:31:17 +01:00
parent 198bb0de60
commit 13646a651b
8 changed files with 35 additions and 33 deletions

View File

@ -42,13 +42,14 @@ namespace MWMechanics
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
if(actor.getTypeName() == typeid(ESM::NPC).name()) if (actor.getClass().hasInventoryStore(actor))
{ {
MWMechanics::DrawState_ state = actor.getClass().getNpcStats(actor).getDrawState(); MWMechanics::DrawState_ state = actor.getClass().getCreatureStats(actor).getDrawState();
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
actor.getClass().getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); actor.getClass().getCreatureStats(actor).setDrawState(MWMechanics::DrawState_Weapon);
//MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); //MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true);
} }
ESM::Position pos = actor.getRefData().getPosition(); ESM::Position pos = actor.getRefData().getPosition();
const ESM::Pathgrid *pathgrid = const ESM::Pathgrid *pathgrid =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->mCell); MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*actor.getCell()->mCell);

View File

@ -323,7 +323,7 @@ void CharacterController::getWeaponGroup(WeaponType weaptype, std::string &group
} }
MWWorld::ContainerStoreIterator CharacterController::getActiveWeapon(NpcStats &stats, MWWorld::InventoryStore &inv, WeaponType *weaptype) MWWorld::ContainerStoreIterator CharacterController::getActiveWeapon(CreatureStats &stats, MWWorld::InventoryStore &inv, WeaponType *weaptype)
{ {
if(stats.getDrawState() == DrawState_Spell) if(stats.getDrawState() == DrawState_Spell)
{ {
@ -434,15 +434,16 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
* handle knockout and death which moves the character down. */ * handle knockout and death which moves the character down. */
mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
if(mPtr.getTypeName() == typeid(ESM::NPC).name()) if (cls.hasInventoryStore(mPtr))
{ {
getActiveWeapon(cls.getNpcStats(mPtr), cls.getInventoryStore(mPtr), &mWeaponType); getActiveWeapon(cls.getCreatureStats(mPtr), cls.getInventoryStore(mPtr), &mWeaponType);
if(mWeaponType != WeapType_None) if(mWeaponType != WeapType_None)
{ {
getWeaponGroup(mWeaponType, mCurrentWeapon); getWeaponGroup(mWeaponType, mCurrentWeapon);
mUpperBodyState = UpperCharState_WeapEquiped; mUpperBodyState = UpperCharState_WeapEquiped;
mAnimation->showWeapons(true); mAnimation->showWeapons(true);
} }
mAnimation->showCarriedLeft(mWeaponType != WeapType_Spell && mWeaponType != WeapType_HandToHand);
} }
if(!cls.getCreatureStats(mPtr).isDead()) if(!cls.getCreatureStats(mPtr).isDead())
@ -517,14 +518,14 @@ bool CharacterController::updateCreatureState()
return false; return false;
} }
bool CharacterController::updateNpcState(bool inwater, bool isrunning) bool CharacterController::updateWeaponState(bool inwater, bool isrunning)
{ {
const MWWorld::Class &cls = MWWorld::Class::get(mPtr); const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
NpcStats &stats = cls.getNpcStats(mPtr); CreatureStats &stats = cls.getCreatureStats(mPtr);
WeaponType weaptype = WeapType_None; WeaponType weaptype = WeapType_None;
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype); MWWorld::ContainerStoreIterator weapon = getActiveWeapon(stats, inv, &weaptype);
const bool isWerewolf = stats.isWerewolf(); const bool isWerewolf = cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf();
bool forcestateupdate = false; bool forcestateupdate = false;
if(weaptype != mWeaponType && mHitState != CharState_KnockDown) if(weaptype != mWeaponType && mHitState != CharState_KnockDown)
@ -613,7 +614,7 @@ bool CharacterController::updateNpcState(bool inwater, bool isrunning)
{ {
// Unset casting flag, otherwise pressing the mouse button down would // Unset casting flag, otherwise pressing the mouse button down would
// continue casting every frame if there is no animation // continue casting every frame if there is no animation
mPtr.getClass().getCreatureStats(mPtr).setAttackingOrSpell(false); stats.setAttackingOrSpell(false);
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
@ -1128,8 +1129,8 @@ void CharacterController::update(float duration)
} }
} }
if(cls.isNpc()) if(cls.hasInventoryStore(mPtr))
forcestateupdate = updateNpcState(inwater, isrunning) || forcestateupdate; forcestateupdate = updateWeaponState(inwater, isrunning) || forcestateupdate;
else else
forcestateupdate = updateCreatureState() || forcestateupdate; forcestateupdate = updateCreatureState() || forcestateupdate;

View File

@ -22,7 +22,7 @@ namespace MWMechanics
{ {
class Movement; class Movement;
class NpcStats; class CreatureStats;
enum Priority { enum Priority {
Priority_Default, Priority_Default,
@ -170,13 +170,13 @@ class CharacterController
static void getWeaponGroup(WeaponType weaptype, std::string &group); static void getWeaponGroup(WeaponType weaptype, std::string &group);
static MWWorld::ContainerStoreIterator getActiveWeapon(NpcStats &stats, static MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats,
MWWorld::InventoryStore &inv, MWWorld::InventoryStore &inv,
WeaponType *weaptype); WeaponType *weaptype);
void clearAnimQueue(); void clearAnimQueue();
bool updateNpcState(bool inwater, bool isrunning); bool updateWeaponState(bool inwater, bool isrunning);
bool updateCreatureState(); bool updateCreatureState();
void updateVisibility(); void updateVisibility();

View File

@ -16,7 +16,7 @@ namespace MWMechanics
mAttackingOrSpell(false), mAttackType(AT_Chop), mAttackingOrSpell(false), mAttackType(AT_Chop),
mIsWerewolf(false), mIsWerewolf(false),
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false), mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false),
mMovementFlags(0), mDrawState (DrawState_Nothing) mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
mAiSettings[i] = 0; mAiSettings[i] = 0;
@ -462,4 +462,14 @@ namespace MWMechanics
mDrawState = state; mDrawState = state;
} }
float CreatureStats::getAttackStrength() const
{
return mAttackStrength;
}
void CreatureStats::setAttackStrength(float value)
{
mAttackStrength = value;
}
} }

View File

@ -40,6 +40,7 @@ namespace MWMechanics
bool mKnockdown; bool mKnockdown;
bool mHitRecovery; bool mHitRecovery;
unsigned int mMovementFlags; unsigned int mMovementFlags;
float mAttackStrength; // Note only some creatures attack with weapons
float mFallHeight; float mFallHeight;
@ -62,6 +63,10 @@ namespace MWMechanics
DrawState_ getDrawState() const; DrawState_ getDrawState() const;
void setDrawState(DrawState_ state); void setDrawState(DrawState_ state);
/// When attacking, stores how strong the attack should be (0 = weakest, 1 = strongest)
float getAttackStrength() const;
void setAttackStrength(float value);
bool needToRecalcDynamicStats(); bool needToRecalcDynamicStats();
void addToFallHeight(float height); void addToFallHeight(float height);

View File

@ -28,23 +28,12 @@ MWMechanics::NpcStats::NpcStats()
, mReputation(0) , mReputation(0)
, mWerewolfKills (0) , mWerewolfKills (0)
, mProfit(0) , mProfit(0)
, mAttackStrength(0.0f)
, mTimeToStartDrowning(20.0) , mTimeToStartDrowning(20.0)
, mLastDrowningHit(0) , mLastDrowningHit(0)
{ {
mSkillIncreases.resize (ESM::Attribute::Length, 0); mSkillIncreases.resize (ESM::Attribute::Length, 0);
} }
float MWMechanics::NpcStats::getAttackStrength() const
{
return mAttackStrength;
}
void MWMechanics::NpcStats::setAttackStrength(float value)
{
mAttackStrength = value;
}
int MWMechanics::NpcStats::getBaseDisposition() const int MWMechanics::NpcStats::getBaseDisposition() const
{ {
return mDisposition; return mDisposition;

View File

@ -59,10 +59,6 @@ namespace MWMechanics
int getProfit() const; int getProfit() const;
void modifyProfit(int diff); void modifyProfit(int diff);
/// When attacking, stores how strong the attack should be (0 = weakest, 1 = strongest)
float getAttackStrength() const;
void setAttackStrength(float value);
int getBaseDisposition() const; int getBaseDisposition() const;
void setBaseDisposition(int disposition); void setBaseDisposition(int disposition);

View File

@ -34,8 +34,8 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr) CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr)
: Animation(ptr, ptr.getRefData().getBaseNode()) : Animation(ptr, ptr.getRefData().getBaseNode())
, mShowWeapons(true) // TODO: change to false, once charactercontroller handles creature weapons , mShowWeapons(false)
, mShowCarriedLeft(true) // TODO: change to false, once charactercontroller handles creature weapons , mShowCarriedLeft(false)
{ {
MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>();