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 "../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<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

@ -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<MWWorld::Action> 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<DoorCustomData> 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<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
@ -409,7 +409,7 @@ namespace MWClass
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
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;
/// 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)

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

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

@ -52,10 +52,10 @@ namespace MWMechanics
// FIXME: cast
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];
if (doorState != 0 || doorRot != 0)
if (doorState != MWWorld::DoorState::Idle || doorRot != 0)
continue; // the door is already opened/opening
doorPos.z() = 0;

@ -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);
}
}
};

@ -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");
}

@ -9,6 +9,7 @@
#include <osg/Vec4f>
#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 {}

@ -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;
}
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<MWWorld::Ptr> collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
@ -1658,7 +1658,7 @@ namespace MWWorld
void World::processDoors(float duration)
{
std::map<MWWorld::Ptr, int>::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);

@ -118,7 +118,7 @@ namespace MWWorld
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
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<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

Loading…
Cancel
Save