mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-22 04:23:53 +00:00
Merge pull request #2504 from elsid/door_state_enum
Add enum type for door state
This commit is contained in:
commit
ceff1defb4
12 changed files with 58 additions and 44 deletions
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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 {}
|
||||||
|
|
||||||
|
|
14
apps/openmw/mwworld/doorstate.hpp
Normal file
14
apps/openmw/mwworld/doorstate.hpp
Normal file
|
@ -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…
Reference in a new issue