Merge pull request #2504 from elsid/door_state_enum

Add enum type for door state
pull/541/head
Alexei Dobrohotov 5 years ago committed by GitHub
commit ceff1defb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,6 +9,7 @@
#include <components/esm/cellid.hpp> #include <components/esm/cellid.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/doorstate.hpp"
#include "../mwrender/rendermode.hpp" #include "../mwrender/rendermode.hpp"
@ -419,7 +420,7 @@ namespace MWBase
/// update movement state of a non-teleport door as specified /// update movement state of a non-teleport door as specified
/// @param state see MWClass::setDoorState /// @param state see MWClass::setDoorState
/// @note throws an exception when invoked on a teleport door /// @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<MWWorld::Ptr> &actors) = 0; ///< get a list of actors standing on \a object virtual void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector<MWWorld::Ptr> &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 virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object

@ -34,7 +34,7 @@ namespace MWClass
class DoorCustomData : public MWWorld::CustomData class DoorCustomData : public MWWorld::CustomData
{ {
public: public:
int mDoorState; // 0 = nothing, 1 = opening, 2 = closing MWWorld::DoorState mDoorState;
virtual MWWorld::CustomData *clone() const; virtual MWWorld::CustomData *clone() const;
@ -71,7 +71,7 @@ namespace MWClass
if (ptr.getRefData().getCustomData()) if (ptr.getRefData().getCustomData())
{ {
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); 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); MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState);
} }
@ -201,12 +201,12 @@ namespace MWClass
{ {
// animated door // animated door
std::shared_ptr<MWWorld::Action> action(new MWWorld::ActionDoor(ptr)); std::shared_ptr<MWWorld::Action> action(new MWWorld::ActionDoor(ptr));
int doorstate = getDoorState(ptr); const auto doorState = getDoorState(ptr);
bool opening = true; bool opening = true;
float doorRot = ptr.getRefData().getPosition().rot[2] - ptr.getCellRef().getPosition().rot[2]; float doorRot = ptr.getRefData().getPosition().rot[2] - ptr.getCellRef().getPosition().rot[2];
if (doorstate == 1) if (doorState == MWWorld::DoorState::Opening)
opening = false; opening = false;
if (doorstate == 0 && doorRot != 0) if (doorState == MWWorld::DoorState::Idle && doorRot != 0)
opening = false; opening = false;
if (opening) if (opening)
@ -365,20 +365,20 @@ namespace MWClass
{ {
std::unique_ptr<DoorCustomData> data(new DoorCustomData); std::unique_ptr<DoorCustomData> data(new DoorCustomData);
data->mDoorState = 0; data->mDoorState = MWWorld::DoorState::Idle;
ptr.getRefData().setCustomData(data.release()); 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()) if (!ptr.getRefData().getCustomData())
return 0; return MWWorld::DoorState::Idle;
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
return customData.mDoorState; 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()) if (ptr.getCellRef().getTeleport())
throw std::runtime_error("load doors can't be moved"); throw std::runtime_error("load doors can't be moved");
@ -396,7 +396,7 @@ namespace MWClass
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
const ESM::DoorState& state2 = dynamic_cast<const ESM::DoorState&>(state); const ESM::DoorState& state2 = dynamic_cast<const ESM::DoorState&>(state);
customData.mDoorState = state2.mDoorState; customData.mDoorState = static_cast<MWWorld::DoorState>(state2.mDoorState);
} }
void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const
@ -409,7 +409,7 @@ namespace MWClass
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
ESM::DoorState& state2 = dynamic_cast<ESM::DoorState&>(state); ESM::DoorState& state2 = dynamic_cast<ESM::DoorState&>(state);
state2.mDoorState = customData.mDoorState; state2.mDoorState = static_cast<int>(customData.mDoorState);
} }
} }

@ -59,10 +59,9 @@ namespace MWClass
virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; virtual std::string getModel(const MWWorld::ConstPtr &ptr) const;
/// 0 = nothing, 1 = opening, 2 = closing virtual MWWorld::DoorState getDoorState (const MWWorld::ConstPtr &ptr) const;
virtual int getDoorState (const MWWorld::ConstPtr &ptr) const;
/// This does not actually cause the door to move. Use World::activateDoor instead. /// 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) virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)

@ -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 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 return true; //Door is no longer opening
ESM::Position tPos = mDoorPtr.getRefData().getPosition(); //Position of the door ESM::Position tPos = mDoorPtr.getRefData().getPosition(); //Position of the door

@ -232,7 +232,7 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor)
return; return;
// note: AiWander currently does not open doors // 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 )) if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 ))
{ {

@ -52,10 +52,10 @@ namespace MWMechanics
// FIXME: cast // FIXME: cast
const MWWorld::Ptr doorPtr = MWWorld::Ptr(&const_cast<MWWorld::LiveCellRef<ESM::Door> &>(ref), actor.getCell()); const MWWorld::Ptr doorPtr = MWWorld::Ptr(&const_cast<MWWorld::LiveCellRef<ESM::Door> &>(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]; 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 continue; // the door is already opened/opening
doorPos.z() = 0; doorPos.z() = 0;

@ -188,7 +188,7 @@ namespace MWScript
// This is done when using Lock in scripts, but not when using Lock spells. // This is done when using Lock in scripts, but not when using Lock spells.
if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport()) 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);
} }
} }
}; };

@ -460,12 +460,12 @@ namespace MWWorld
return false; 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"); 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"); throw std::runtime_error("this is not a door");
} }

@ -9,6 +9,7 @@
#include <osg/Vec4f> #include <osg/Vec4f>
#include "ptr.hpp" #include "ptr.hpp"
#include "doorstate.hpp"
namespace ESM namespace ESM
{ {
@ -298,7 +299,7 @@ namespace MWWorld
virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; } virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; }
///< Return whether this class of object can be activated with telekinesis ///< 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) /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; 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; virtual bool isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const;
/// 0 = nothing, 1 = opening, 2 = closing virtual DoorState getDoorState (const MWWorld::ConstPtr &ptr) const;
virtual int getDoorState (const MWWorld::ConstPtr &ptr) const;
/// This does not actually cause the door to move. Use World::activateDoor instead. /// 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 {} virtual void respawn (const MWWorld::Ptr& ptr) const {}

@ -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

@ -1617,7 +1617,7 @@ namespace MWWorld
return result.mHit; 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(); const ESM::Position& objPos = door.getRefData().getPosition();
float oldRot = objPos.rot[2]; float oldRot = objPos.rot[2];
@ -1626,10 +1626,10 @@ namespace MWWorld
float maxRot = minRot + osg::DegreesToRadians(90.f); float maxRot = minRot + osg::DegreesToRadians(90.f);
float diff = duration * 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); 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 /// \todo should use convexSweepTest here
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor); std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
@ -1658,7 +1658,7 @@ namespace MWWorld
void World::processDoors(float duration) void World::processDoors(float duration)
{ {
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin(); auto it = mDoorStates.begin();
while (it != mDoorStates.end()) while (it != mDoorStates.end())
{ {
if (!mWorldScene->isCellActive(*it->first.getCell()) || !it->first.getRefData().getBaseNode()) if (!mWorldScene->isCellActive(*it->first.getCell()) || !it->first.getRefData().getBaseNode())
@ -1675,7 +1675,7 @@ namespace MWWorld
if (reached) if (reached)
{ {
// Mark as non-moving // Mark as non-moving
it->first.getClass().setDoorState(it->first, 0); it->first.getClass().setDoorState(it->first, MWWorld::DoorState::Idle);
mDoorStates.erase(it++); mDoorStates.erase(it++);
} }
else else
@ -2510,32 +2510,32 @@ namespace MWWorld
void World::activateDoor(const MWWorld::Ptr& door) void World::activateDoor(const MWWorld::Ptr& door)
{ {
int state = door.getClass().getDoorState(door); auto state = door.getClass().getDoorState(door);
switch (state) switch (state)
{ {
case 0: case MWWorld::DoorState::Idle:
if (door.getRefData().getPosition().rot[2] == door.getCellRef().getPosition().rot[2]) 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 else
state = 2; // if open, then close state = MWWorld::DoorState::Closing; // if open, then close
break; break;
case 2: case MWWorld::DoorState::Closing:
state = 1; // if closing, then open state = MWWorld::DoorState::Opening; // if closing, then open
break; break;
case 1: case MWWorld::DoorState::Opening:
default: default:
state = 2; // if opening, then close state = MWWorld::DoorState::Closing; // if opening, then close
break; break;
} }
door.getClass().setDoorState(door, state); door.getClass().setDoorState(door, state);
mDoorStates[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); door.getClass().setDoorState(door, state);
mDoorStates[door] = state; mDoorStates[door] = state;
if (state == 0) if (state == MWWorld::DoorState::Idle)
{ {
mDoorStates.erase(door); mDoorStates.erase(door);
rotateDoor(door, state, 1); rotateDoor(door, state, 1);

@ -118,7 +118,7 @@ namespace MWWorld
int mActivationDistanceOverride; int mActivationDistanceOverride;
std::map<MWWorld::Ptr, int> mDoorStates; std::map<MWWorld::Ptr, MWWorld::DoorState> mDoorStates;
///< only holds doors that are currently moving. 1 = opening, 2 = closing ///< only holds doors that are currently moving. 1 = opening, 2 = closing
std::string mStartCell; std::string mStartCell;
@ -146,7 +146,7 @@ namespace MWWorld
private: private:
void PCDropped (const Ptr& item); 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); void processDoors(float duration);
///< Run physics simulation and modify \a world accordingly. ///< Run physics simulation and modify \a world accordingly.
@ -542,7 +542,7 @@ namespace MWWorld
/// update movement state of a non-teleport door as specified /// update movement state of a non-teleport door as specified
/// @param state see MWClass::setDoorState /// @param state see MWClass::setDoorState
/// @note throws an exception when invoked on a teleport door /// @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<MWWorld::Ptr> &actors) override; ///< get a list of actors standing on \a object void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector<MWWorld::Ptr> &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 bool getPlayerStandingOn (const MWWorld::ConstPtr& object) override; ///< @return true if the player is standing on \a object

Loading…
Cancel
Save