diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 63f69ab65..955e77168 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -9,6 +9,7 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/doorstate.hpp" #include "../mwrender/rendermode.hpp" @@ -419,7 +420,7 @@ namespace MWBase /// update movement state of a non-teleport door as specified /// @param state see MWClass::setDoorState /// @note throws an exception when invoked on a teleport door - virtual void activateDoor(const MWWorld::Ptr& door, int state) = 0; + virtual void activateDoor(const MWWorld::Ptr& door, MWWorld::DoorState state) = 0; virtual void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors) = 0; ///< get a list of actors standing on \a object virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 89b628d91..4f144e1f7 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -34,7 +34,7 @@ namespace MWClass class DoorCustomData : public MWWorld::CustomData { public: - int mDoorState; // 0 = nothing, 1 = opening, 2 = closing + MWWorld::DoorState mDoorState; virtual MWWorld::CustomData *clone() const; @@ -71,7 +71,7 @@ namespace MWClass if (ptr.getRefData().getCustomData()) { const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); - if (customData.mDoorState > 0) + if (customData.mDoorState != MWWorld::DoorState::Idle) { MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState); } @@ -201,12 +201,12 @@ namespace MWClass { // animated door std::shared_ptr action(new MWWorld::ActionDoor(ptr)); - int doorstate = getDoorState(ptr); + const auto doorState = getDoorState(ptr); bool opening = true; float doorRot = ptr.getRefData().getPosition().rot[2] - ptr.getCellRef().getPosition().rot[2]; - if (doorstate == 1) + if (doorState == MWWorld::DoorState::Opening) opening = false; - if (doorstate == 0 && doorRot != 0) + if (doorState == MWWorld::DoorState::Idle && doorRot != 0) opening = false; if (opening) @@ -365,20 +365,20 @@ namespace MWClass { std::unique_ptr data(new DoorCustomData); - data->mDoorState = 0; + data->mDoorState = MWWorld::DoorState::Idle; ptr.getRefData().setCustomData(data.release()); } } - int Door::getDoorState (const MWWorld::ConstPtr &ptr) const + MWWorld::DoorState Door::getDoorState (const MWWorld::ConstPtr &ptr) const { if (!ptr.getRefData().getCustomData()) - return 0; + return MWWorld::DoorState::Idle; const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); return customData.mDoorState; } - void Door::setDoorState (const MWWorld::Ptr &ptr, int state) const + void Door::setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const { if (ptr.getCellRef().getTeleport()) throw std::runtime_error("load doors can't be moved"); @@ -396,7 +396,7 @@ namespace MWClass DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); const ESM::DoorState& state2 = dynamic_cast(state); - customData.mDoorState = state2.mDoorState; + customData.mDoorState = static_cast(state2.mDoorState); } void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const @@ -409,7 +409,7 @@ namespace MWClass const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); ESM::DoorState& state2 = dynamic_cast(state); - state2.mDoorState = customData.mDoorState; + state2.mDoorState = static_cast(customData.mDoorState); } } diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 57e475382..b3e4e383c 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -59,10 +59,9 @@ namespace MWClass virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; - /// 0 = nothing, 1 = opening, 2 = closing - virtual int getDoorState (const MWWorld::ConstPtr &ptr) const; + virtual MWWorld::DoorState getDoorState (const MWWorld::ConstPtr &ptr) const; /// This does not actually cause the door to move. Use World::activateDoor instead. - virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const; + virtual void setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const; virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) diff --git a/apps/openmw/mwmechanics/aiavoiddoor.cpp b/apps/openmw/mwmechanics/aiavoiddoor.cpp index 8fc35de49..793bd89ea 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.cpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.cpp @@ -44,7 +44,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterCont return true; // We have tried backing up for more than one second, we've probably cleared it } - if (!mDoorPtr.getClass().getDoorState(mDoorPtr)) + if (mDoorPtr.getClass().getDoorState(mDoorPtr) == MWWorld::DoorState::Idle) return true; //Door is no longer opening ESM::Position tPos = mDoorPtr.getRefData().getPosition(); //Position of the door diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 598292fc3..646b37669 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -232,7 +232,7 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) return; // note: AiWander currently does not open doors - if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == 0) + if (getTypeId() != TypeIdWander && !door.getCellRef().getTeleport() && door.getClass().getDoorState(door) == MWWorld::DoorState::Idle) { if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 )) { diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index b8676a883..c3da92e31 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -52,10 +52,10 @@ namespace MWMechanics // FIXME: cast const MWWorld::Ptr doorPtr = MWWorld::Ptr(&const_cast &>(ref), actor.getCell()); - int doorState = doorPtr.getClass().getDoorState(doorPtr); + const auto doorState = doorPtr.getClass().getDoorState(doorPtr); float doorRot = ref.mData.getPosition().rot[2] - doorPtr.getCellRef().getPosition().rot[2]; - if (doorState != 0 || doorRot != 0) + if (doorState != MWWorld::DoorState::Idle || doorRot != 0) continue; // the door is already opened/opening doorPos.z() = 0; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 47873a3b6..29a25c997 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -188,7 +188,7 @@ namespace MWScript // This is done when using Lock in scripts, but not when using Lock spells. if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport()) { - MWBase::Environment::get().getWorld()->activateDoor(ptr, 0); + MWBase::Environment::get().getWorld()->activateDoor(ptr, MWWorld::DoorState::Idle); } } }; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index f84c7bb8b..191552bc5 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -460,12 +460,12 @@ namespace MWWorld return false; } - int Class::getDoorState (const MWWorld::ConstPtr &ptr) const + MWWorld::DoorState Class::getDoorState (const MWWorld::ConstPtr &ptr) const { throw std::runtime_error("this is not a door"); } - void Class::setDoorState (const MWWorld::Ptr &ptr, int state) const + void Class::setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const { throw std::runtime_error("this is not a door"); } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 8e5cfb981..964ef19a5 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -9,6 +9,7 @@ #include #include "ptr.hpp" +#include "doorstate.hpp" namespace ESM { @@ -298,7 +299,7 @@ namespace MWWorld virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; } ///< Return whether this class of object can be activated with telekinesis - + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; @@ -350,10 +351,9 @@ namespace MWWorld virtual bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const; - /// 0 = nothing, 1 = opening, 2 = closing - virtual int getDoorState (const MWWorld::ConstPtr &ptr) const; + virtual DoorState getDoorState (const MWWorld::ConstPtr &ptr) const; /// This does not actually cause the door to move. Use World::activateDoor instead. - virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const; + virtual void setDoorState (const MWWorld::Ptr &ptr, DoorState state) const; virtual void respawn (const MWWorld::Ptr& ptr) const {} diff --git a/apps/openmw/mwworld/doorstate.hpp b/apps/openmw/mwworld/doorstate.hpp new file mode 100644 index 000000000..aeafa7d8c --- /dev/null +++ b/apps/openmw/mwworld/doorstate.hpp @@ -0,0 +1,14 @@ +#ifndef GAME_MWWORLD_DOORSTATE_H +#define GAME_MWWORLD_DOORSTATE_H + +namespace MWWorld +{ + enum class DoorState + { + Idle = 0, + Opening = 1, + Closing = 2, + }; +} + +#endif diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5babc57be..3ea994683 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1617,7 +1617,7 @@ namespace MWWorld return result.mHit; } - bool World::rotateDoor(const Ptr door, int state, float duration) + bool World::rotateDoor(const Ptr door, MWWorld::DoorState state, float duration) { const ESM::Position& objPos = door.getRefData().getPosition(); float oldRot = objPos.rot[2]; @@ -1626,10 +1626,10 @@ namespace MWWorld float maxRot = minRot + osg::DegreesToRadians(90.f); float diff = duration * osg::DegreesToRadians(90.f); - float targetRot = std::min(std::max(minRot, oldRot + diff * (state == 1 ? 1 : -1)), maxRot); + float targetRot = std::min(std::max(minRot, oldRot + diff * (state == MWWorld::DoorState::Opening ? 1 : -1)), maxRot); rotateObject(door, objPos.rot[0], objPos.rot[1], targetRot); - bool reached = (targetRot == maxRot && state) || targetRot == minRot; + bool reached = (targetRot == maxRot && state != MWWorld::DoorState::Idle) || targetRot == minRot; /// \todo should use convexSweepTest here std::vector collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor); @@ -1658,7 +1658,7 @@ namespace MWWorld void World::processDoors(float duration) { - std::map::iterator it = mDoorStates.begin(); + auto it = mDoorStates.begin(); while (it != mDoorStates.end()) { if (!mWorldScene->isCellActive(*it->first.getCell()) || !it->first.getRefData().getBaseNode()) @@ -1675,7 +1675,7 @@ namespace MWWorld if (reached) { // Mark as non-moving - it->first.getClass().setDoorState(it->first, 0); + it->first.getClass().setDoorState(it->first, MWWorld::DoorState::Idle); mDoorStates.erase(it++); } else @@ -2510,32 +2510,32 @@ namespace MWWorld void World::activateDoor(const MWWorld::Ptr& door) { - int state = door.getClass().getDoorState(door); + auto state = door.getClass().getDoorState(door); switch (state) { - case 0: + case MWWorld::DoorState::Idle: if (door.getRefData().getPosition().rot[2] == door.getCellRef().getPosition().rot[2]) - state = 1; // if closed, then open + state = MWWorld::DoorState::Opening; // if closed, then open else - state = 2; // if open, then close + state = MWWorld::DoorState::Closing; // if open, then close break; - case 2: - state = 1; // if closing, then open + case MWWorld::DoorState::Closing: + state = MWWorld::DoorState::Opening; // if closing, then open break; - case 1: + case MWWorld::DoorState::Opening: default: - state = 2; // if opening, then close + state = MWWorld::DoorState::Closing; // if opening, then close break; } door.getClass().setDoorState(door, state); mDoorStates[door] = state; } - void World::activateDoor(const Ptr &door, int state) + void World::activateDoor(const Ptr &door, MWWorld::DoorState state) { door.getClass().setDoorState(door, state); mDoorStates[door] = state; - if (state == 0) + if (state == MWWorld::DoorState::Idle) { mDoorStates.erase(door); rotateDoor(door, state, 1); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 0f090bf8d..76d015477 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -118,7 +118,7 @@ namespace MWWorld int mActivationDistanceOverride; - std::map mDoorStates; + std::map mDoorStates; ///< only holds doors that are currently moving. 1 = opening, 2 = closing std::string mStartCell; @@ -146,7 +146,7 @@ namespace MWWorld private: void PCDropped (const Ptr& item); - bool rotateDoor(const Ptr door, int state, float duration); + bool rotateDoor(const Ptr door, DoorState state, float duration); void processDoors(float duration); ///< Run physics simulation and modify \a world accordingly. @@ -542,7 +542,7 @@ namespace MWWorld /// update movement state of a non-teleport door as specified /// @param state see MWClass::setDoorState /// @note throws an exception when invoked on a teleport door - void activateDoor(const MWWorld::Ptr& door, int state) override; + void activateDoor(const MWWorld::Ptr& door, MWWorld::DoorState state) override; void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors) override; ///< get a list of actors standing on \a object bool getPlayerStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if the player is standing on \a object