diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a0f9e8e13c..2dd16a4e6c 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -74,7 +74,7 @@ add_openmw_dir (mwphysics add_openmw_dir (mwclass classes activator creature npc weapon armor potion apparatus book clothing container door - ingredient creaturelevlist itemlevlist light lockpick misc probe repair static + ingredient creaturelevlist itemlevlist light lockpick misc probe repair static actor ) add_openmw_dir (mwmechanics diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp new file mode 100644 index 0000000000..d58047d06f --- /dev/null +++ b/apps/openmw/mwclass/actor.cpp @@ -0,0 +1,87 @@ +#include "actor.hpp" + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" + +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/movement.hpp" +#include "../mwmechanics/magiceffects.hpp" + +#include "../mwphysics/physicssystem.hpp" + +#include "../mwworld/inventorystore.hpp" + +namespace MWClass +{ + Actor::Actor() {} + + Actor::~Actor() {} + + void Actor::adjustPosition(const MWWorld::Ptr& ptr, bool force) const + { + MWBase::Environment::get().getWorld()->adjustPosition(ptr, force); + } + + void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const + { + if (!model.empty()) + { + physics.addActor(ptr, model); + if (getCreatureStats(ptr).isDead()) + MWBase::Environment::get().getWorld()->enableActorCollision(ptr, false); + } + MWBase::Environment::get().getMechanicsManager()->add(ptr); + } + + void Actor::block(const MWWorld::Ptr &ptr) const + { + MWWorld::InventoryStore& inv = getInventoryStore(ptr); + MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (shield == inv.end()) + return; + + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + switch (shield->getClass().getEquipmentSkill(*shield)) + { + case ESM::Skill::LightArmor: + sndMgr->playSound3D(ptr, "Light Armor Hit", 1.0f, 1.0f); + break; + case ESM::Skill::MediumArmor: + sndMgr->playSound3D(ptr, "Medium Armor Hit", 1.0f, 1.0f); + break; + case ESM::Skill::HeavyArmor: + sndMgr->playSound3D(ptr, "Heavy Armor Hit", 1.0f, 1.0f); + break; + default: + return; + } + } + + bool Actor::hasToolTip(const MWWorld::Ptr& ptr) const + { + return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead(); + } + + osg::Vec3f Actor::getRotationVector(const MWWorld::Ptr& ptr) const + { + MWMechanics::Movement &movement = getMovementSettings(ptr); + osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]); + movement.mRotation[0] = 0.0f; + movement.mRotation[1] = 0.0f; + movement.mRotation[2] = 0.0f; + return vec; + } + + float Actor::getEncumbrance(const MWWorld::Ptr& ptr) const + { + float weight = getContainerStore(ptr).getWeight(); + const MWMechanics::MagicEffects& effects = getCreatureStats(ptr).getMagicEffects(); + weight -= effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Feather)).getMagnitude(); + weight += effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); + return (weight < 0) ? 0.0f : weight; + } +} diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp new file mode 100644 index 0000000000..3f795dff9d --- /dev/null +++ b/apps/openmw/mwclass/actor.hpp @@ -0,0 +1,47 @@ +#ifndef GAME_MWCLASS_MOBILE_H +#define GAME_MWCLASS_MOBILE_H + +#include "../mwworld/class.hpp" + +namespace ESM +{ + struct GameSetting; +} + +namespace MWClass +{ + /// \brief Class holding functionality common to Creature and NPC + class Actor : public MWWorld::Class + { + protected: + + Actor(); + + public: + virtual ~Actor(); + + virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; + ///< Adjust position to stand on ground. Must be called post model load + /// @param force do this even if the ptr is flying + + virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; + + virtual void block(const MWWorld::Ptr &ptr) const; + + virtual bool hasToolTip(const MWWorld::Ptr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: false) + + virtual osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const; + ///< Return desired rotations, as euler angles. + + virtual float getEncumbrance(const MWWorld::Ptr& ptr) const; + ///< Returns total weight of objects inside this object (including modifications from magic + /// effects). Throws an exception, if the object can't hold other objects. + + // not implemented + Actor(const Actor&); + Actor& operator= (const Actor&); + }; +} + +#endif diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index ff09282c1f..e14d9f8ba4 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -156,11 +156,6 @@ namespace MWClass return ref->mBase->mId; } - void Creature::adjustPosition(const MWWorld::Ptr& ptr, bool force) const - { - MWBase::Environment::get().getWorld()->adjustPosition(ptr, force); - } - void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { MWWorld::LiveCellRef *ref = ptr.get(); @@ -169,17 +164,6 @@ namespace MWClass objects.insertCreature(ptr, model, (ref->mBase->mFlags & ESM::Creature::Weapon) != 0); } - void Creature::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const - { - if(!model.empty()) - { - physics.addActor(ptr, model); - if (getCreatureStats(ptr).isDead()) - MWBase::Environment::get().getWorld()->enableActorCollision(ptr, false); - } - MWBase::Environment::get().getMechanicsManager()->add(ptr); - } - std::string Creature::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -408,30 +392,6 @@ namespace MWClass } } - void Creature::block(const MWWorld::Ptr &ptr) const - { - MWWorld::InventoryStore& inv = getInventoryStore(ptr); - MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield == inv.end()) - return; - - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - switch(shield->getClass().getEquipmentSkill(*shield)) - { - case ESM::Skill::LightArmor: - sndMgr->playSound3D(ptr, "Light Armor Hit", 1.0f, 1.0f); - break; - case ESM::Skill::MediumArmor: - sndMgr->playSound3D(ptr, "Medium Armor Hit", 1.0f, 1.0f); - break; - case ESM::Skill::HeavyArmor: - sndMgr->playSound3D(ptr, "Heavy Armor Hit", 1.0f, 1.0f); - break; - default: - return; - } - } - boost::shared_ptr Creature::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { @@ -499,11 +459,6 @@ namespace MWClass registerClass (typeid (ESM::Creature).name(), instance); } - bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const - { - return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead(); - } - float Creature::getSpeed(const MWWorld::Ptr &ptr) const { MWMechanics::CreatureStats& stats = getCreatureStats(ptr); @@ -562,16 +517,6 @@ namespace MWClass return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; } - osg::Vec3f Creature::getRotationVector (const MWWorld::Ptr& ptr) const - { - MWMechanics::Movement &movement = getMovementSettings(ptr); - osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]); - movement.mRotation[0] = 0.0f; - movement.mRotation[1] = 0.0f; - movement.mRotation[2] = 0.0f; - return vec; - } - MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const { MWWorld::LiveCellRef *ref = @@ -600,21 +545,6 @@ namespace MWClass return static_cast(stats.getAttribute(0).getModified() * 5); } - float Creature::getEncumbrance (const MWWorld::Ptr& ptr) const - { - float weight = getContainerStore (ptr).getWeight(); - - const MWMechanics::MagicEffects& effects = getCreatureStats(ptr).getMagicEffects(); - weight -= effects.get(ESM::MagicEffect::Feather).getMagnitude(); - weight += effects.get(ESM::MagicEffect::Burden).getMagnitude(); - - if (weight<0) - weight = 0; - - return weight; - } - - int Creature::getServices(const MWWorld::Ptr &actor) const { MWWorld::LiveCellRef* ref = actor.get(); diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index b2a333beb3..c4ea09255e 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -1,7 +1,7 @@ #ifndef GAME_MWCLASS_CREATURE_H #define GAME_MWCLASS_CREATURE_H -#include "../mwworld/class.hpp" +#include "actor.hpp" namespace ESM { @@ -10,7 +10,7 @@ namespace ESM namespace MWClass { - class Creature : public MWWorld::Class + class Creature : public Actor { void ensureCustomData (const MWWorld::Ptr& ptr) const; @@ -47,19 +47,10 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; - - virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; - ///< Adjust position to stand on ground. Must be called post model load - /// @param force do this even if the ptr is flying - virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. - virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; - ///< @return true if this object has a tooltip when focused (default implementation: false) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. @@ -68,8 +59,6 @@ namespace MWClass virtual void hit(const MWWorld::Ptr& ptr, float attackStrength, int type) const; - virtual void block(const MWWorld::Ptr &ptr) const; - virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, @@ -92,10 +81,6 @@ namespace MWClass ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects. - virtual float getEncumbrance (const MWWorld::Ptr& ptr) const; - ///< Returns total weight of objects inside this object (including modifications from magic - /// effects). Throws an exception, if the object can't hold other objects. - virtual float getArmorRating (const MWWorld::Ptr& ptr) const; ///< @return combined armor rating of this actor @@ -111,9 +96,6 @@ namespace MWClass virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. - virtual osg::Vec3f getRotationVector (const MWWorld::Ptr& ptr) const; - ///< Return desired rotations, as euler angles. - float getSpeed (const MWWorld::Ptr& ptr) const; static void registerSelf(); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5f166b3e32..9fa2cc6037 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -402,24 +402,11 @@ namespace MWClass return ref->mBase->mId; } - void Npc::adjustPosition(const MWWorld::Ptr& ptr, bool force) const - { - MWBase::Environment::get().getWorld()->adjustPosition(ptr, force); - } - void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { renderingInterface.getObjects().insertNPC(ptr); } - void Npc::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const - { - physics.addActor(ptr, model); - MWBase::Environment::get().getMechanicsManager()->add(ptr); - if (getCreatureStats(ptr).isDead()) - MWBase::Environment::get().getWorld()->enableActorCollision(ptr, false); - } - bool Npc::isPersistent(const MWWorld::Ptr &actor) const { MWWorld::LiveCellRef* ref = actor.get(); @@ -756,30 +743,6 @@ namespace MWClass } } - void Npc::block(const MWWorld::Ptr &ptr) const - { - MWWorld::InventoryStore& inv = getInventoryStore(ptr); - MWWorld::ContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield == inv.end()) - return; - - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - switch(shield->getClass().getEquipmentSkill(*shield)) - { - case ESM::Skill::LightArmor: - sndMgr->playSound3D(ptr, "Light Armor Hit", 1.0f, 1.0f); - break; - case ESM::Skill::MediumArmor: - sndMgr->playSound3D(ptr, "Medium Armor Hit", 1.0f, 1.0f); - break; - case ESM::Skill::HeavyArmor: - sndMgr->playSound3D(ptr, "Heavy Armor Hit", 1.0f, 1.0f); - break; - default: - return; - } - } - boost::shared_ptr Npc::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { @@ -937,16 +900,6 @@ namespace MWClass return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; } - osg::Vec3f Npc::getRotationVector (const MWWorld::Ptr& ptr) const - { - MWMechanics::Movement &movement = getMovementSettings(ptr); - osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]); - movement.mRotation[0] = 0.0f; - movement.mRotation[1] = 0.0f; - movement.mRotation[2] = 0.0f; - return vec; - } - bool Npc::isEssential (const MWWorld::Ptr& ptr) const { MWWorld::LiveCellRef *ref = @@ -961,11 +914,6 @@ namespace MWClass registerClass (typeid (ESM::NPC).name(), instance); } - bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const - { - return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead(); - } - MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const { MWWorld::LiveCellRef *ref = ptr.get(); @@ -996,21 +944,9 @@ namespace MWClass float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const { - const MWMechanics::NpcStats &stats = getNpcStats(ptr); - // According to UESP, inventory weight is ignored in werewolf form. Does that include // feather and burden effects? - float weight = 0.0f; - if(!stats.isWerewolf()) - { - weight = getContainerStore(ptr).getWeight(); - weight -= stats.getMagicEffects().get(ESM::MagicEffect::Feather).getMagnitude(); - weight += stats.getMagicEffects().get(ESM::MagicEffect::Burden).getMagnitude(); - if(weight < 0.0f) - weight = 0.0f; - } - - return weight; + return getNpcStats(ptr).isWerewolf() ? 0.0f : Actor::getEncumbrance(ptr); } bool Npc::apply (const MWWorld::Ptr& ptr, const std::string& id, diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index b12b7b13fb..d919131db9 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -1,7 +1,7 @@ #ifndef GAME_MWCLASS_NPC_H #define GAME_MWCLASS_NPC_H -#include "../mwworld/class.hpp" +#include "actor.hpp" namespace ESM { @@ -10,7 +10,7 @@ namespace ESM namespace MWClass { - class Npc : public MWWorld::Class + class Npc : public Actor { void ensureCustomData (const MWWorld::Ptr& ptr) const; @@ -51,12 +51,6 @@ namespace MWClass virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const; ///< Add reference into a cell for rendering - virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const; - - virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; - ///< Adjust position to stand on ground. Must be called post model load - /// @param force do this even if the ptr is flying - virtual std::string getName (const MWWorld::Ptr& ptr) const; ///< \return name (the one that is to be presented to the user; not the internal one); /// can return an empty string. @@ -70,9 +64,6 @@ namespace MWClass virtual MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const; ///< Return container store - virtual bool hasToolTip (const MWWorld::Ptr& ptr) const; - ///< @return true if this object has a tooltip when focused (default implementation: false) - virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. @@ -85,8 +76,6 @@ namespace MWClass virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, bool successful) const; - virtual void block(const MWWorld::Ptr &ptr) const; - virtual boost::shared_ptr activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const; ///< Generate action for activation @@ -103,9 +92,6 @@ namespace MWClass virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. - virtual osg::Vec3f getRotationVector (const MWWorld::Ptr& ptr) const; - ///< Return desired rotations, as euler angles. - virtual float getCapacity (const MWWorld::Ptr& ptr) const; ///< Return total weight that fits into the object. Throws an exception, if the object can't /// hold other objects.