2010-08-03 15:24:44 +02:00
|
|
|
#include "door.hpp"
|
|
|
|
|
2022-06-04 15:26:36 +02:00
|
|
|
#include <MyGUI_TextIterator.h>
|
|
|
|
|
2022-01-22 15:58:41 +01:00
|
|
|
#include <components/esm3/doorstate.hpp>
|
|
|
|
#include <components/esm3/loaddoor.hpp>
|
2022-09-05 19:35:15 +02:00
|
|
|
#include <components/esm3/loadmgef.hpp>
|
2019-02-21 20:14:18 +04:00
|
|
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
2010-08-03 15:24:44 +02:00
|
|
|
|
2012-04-23 15:27:03 +02:00
|
|
|
#include "../mwbase/environment.hpp"
|
2013-07-26 18:43:06 +02:00
|
|
|
#include "../mwbase/soundmanager.hpp"
|
2012-08-12 18:11:09 +02:00
|
|
|
#include "../mwbase/windowmanager.hpp"
|
2012-07-03 12:30:50 +02:00
|
|
|
#include "../mwbase/world.hpp"
|
2012-04-23 15:27:03 +02:00
|
|
|
|
2015-05-10 01:09:00 +02:00
|
|
|
#include "../mwphysics/physicssystem.hpp"
|
2013-04-28 14:59:15 +02:00
|
|
|
#include "../mwworld/actiondoor.hpp"
|
2010-08-03 18:44:52 +02:00
|
|
|
#include "../mwworld/actionteleport.hpp"
|
2013-11-13 14:02:15 +01:00
|
|
|
#include "../mwworld/actiontrap.hpp"
|
2014-05-15 01:58:44 +02:00
|
|
|
#include "../mwworld/cellstore.hpp"
|
2022-05-23 19:21:44 +02:00
|
|
|
#include "../mwworld/cellutils.hpp"
|
2022-08-17 19:16:01 +02:00
|
|
|
#include "../mwworld/containerstore.hpp"
|
|
|
|
#include "../mwworld/customdata.hpp"
|
2014-12-19 11:26:54 +01:00
|
|
|
#include "../mwworld/esmstore.hpp"
|
2012-11-17 18:17:08 +01:00
|
|
|
#include "../mwworld/failedaction.hpp"
|
2010-08-03 17:11:41 +02:00
|
|
|
#include "../mwworld/ptr.hpp"
|
|
|
|
|
2012-04-16 22:58:16 +02:00
|
|
|
#include "../mwgui/tooltips.hpp"
|
2022-08-24 22:16:03 +02:00
|
|
|
#include "../mwgui/ustring.hpp"
|
2012-04-16 22:58:16 +02:00
|
|
|
|
2016-08-03 02:45:42 +09:00
|
|
|
#include "../mwrender/animation.hpp"
|
2015-04-12 15:34:50 +02:00
|
|
|
#include "../mwrender/objects.hpp"
|
2012-07-03 13:15:20 +02:00
|
|
|
#include "../mwrender/renderinginterface.hpp"
|
2020-04-20 18:47:14 +02:00
|
|
|
#include "../mwrender/vismask.hpp"
|
2010-08-14 10:02:54 +02:00
|
|
|
|
2015-08-21 21:12:39 +12:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
|
|
|
|
2022-06-29 00:32:11 +02:00
|
|
|
#include "classmodel.hpp"
|
|
|
|
|
2015-11-29 14:13:14 +01:00
|
|
|
namespace MWClass
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2021-04-03 12:59:44 +02:00
|
|
|
class DoorCustomData : public MWWorld::TypedCustomData<DoorCustomData>
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2015-11-29 14:13:14 +01:00
|
|
|
public:
|
2019-12-21 14:35:08 +04:00
|
|
|
MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle;
|
2014-05-15 01:58:44 +02:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
DoorCustomData& asDoorCustomData() override { return *this; }
|
|
|
|
const DoorCustomData& asDoorCustomData() const override { return *this; }
|
2014-05-15 01:58:44 +02:00
|
|
|
};
|
|
|
|
|
2022-04-04 02:44:53 +02:00
|
|
|
Door::Door()
|
|
|
|
: MWWorld::RegisteredClass<Door>(ESM::Door::sRecordId)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-01-12 11:29:56 +01:00
|
|
|
void Door::insertObjectRendering(
|
|
|
|
const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
2010-08-14 10:02:54 +02:00
|
|
|
{
|
2019-02-21 20:14:18 +04:00
|
|
|
if (!model.empty())
|
|
|
|
{
|
2023-01-14 04:36:06 +03:00
|
|
|
renderingInterface.getObjects().insertModel(ptr, model);
|
2020-04-20 18:47:14 +02:00
|
|
|
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
|
2010-08-14 10:02:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 22:58:16 +02:00
|
|
|
void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation,
|
|
|
|
MWPhysics::PhysicsSystem& physics) const
|
2011-11-11 23:01:12 -05:00
|
|
|
{
|
2021-09-30 22:58:16 +02:00
|
|
|
insertObjectPhysics(ptr, model, rotation, physics);
|
2014-05-15 01:58:44 +02:00
|
|
|
|
|
|
|
// Resume the door's opening/closing animation if it wasn't finished
|
2014-06-14 19:12:49 +02:00
|
|
|
if (ptr.getRefData().getCustomData())
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2015-11-29 14:13:14 +01:00
|
|
|
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
2019-08-25 15:20:14 +02:00
|
|
|
if (customData.mDoorState != MWWorld::DoorState::Idle)
|
2014-06-14 19:12:49 +02:00
|
|
|
{
|
2014-07-22 17:55:54 +02:00
|
|
|
MWBase::Environment::get().getWorld()->activateDoor(ptr, customData.mDoorState);
|
2014-06-14 19:12:49 +02:00
|
|
|
}
|
2014-05-15 01:58:44 +02:00
|
|
|
}
|
2017-02-20 19:04:02 +01:00
|
|
|
}
|
2014-12-22 18:50:24 +01:00
|
|
|
|
2021-09-30 22:58:16 +02:00
|
|
|
void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation,
|
|
|
|
MWPhysics::PhysicsSystem& physics) const
|
2021-03-05 22:21:53 +01:00
|
|
|
{
|
2022-04-03 17:38:33 +00:00
|
|
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door);
|
2021-03-05 22:21:53 +01:00
|
|
|
}
|
|
|
|
|
2017-08-18 17:06:47 +04:00
|
|
|
bool Door::isDoor() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-02-20 19:04:02 +01:00
|
|
|
bool Door::useAnim() const
|
|
|
|
{
|
|
|
|
return true;
|
2012-07-24 20:22:11 +04:00
|
|
|
}
|
2012-07-27 12:00:10 +02:00
|
|
|
|
2015-12-18 15:51:05 +01:00
|
|
|
std::string Door::getModel(const MWWorld::ConstPtr& ptr) const
|
2012-07-24 20:22:11 +04:00
|
|
|
{
|
2022-06-29 00:32:11 +02:00
|
|
|
return getClassModel<ESM::Door>(ptr);
|
2011-11-11 23:01:12 -05:00
|
|
|
}
|
|
|
|
|
2022-08-16 21:15:03 +02:00
|
|
|
std::string_view Door::getName(const MWWorld::ConstPtr& ptr) const
|
2010-08-03 17:11:41 +02:00
|
|
|
{
|
2015-12-18 15:27:06 +01:00
|
|
|
const MWWorld::LiveCellRef<ESM::Door>* ref = ptr.get<ESM::Door>();
|
2019-09-11 00:06:50 +03:00
|
|
|
const std::string& name = ref->mBase->mName;
|
2010-08-03 17:11:41 +02:00
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
return !name.empty() ? name : ref->mBase->mId.getRefIdString();
|
2010-08-03 17:11:41 +02:00
|
|
|
}
|
|
|
|
|
2022-04-06 17:06:55 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> Door::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const
|
2010-08-03 18:44:52 +02:00
|
|
|
{
|
2013-08-09 01:35:29 -07:00
|
|
|
MWWorld::LiveCellRef<ESM::Door>* ref = ptr.get<ESM::Door>();
|
2010-08-03 18:44:52 +02:00
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& openSound = ref->mBase->mOpenSound;
|
|
|
|
const ESM::RefId& closeSound = ref->mBase->mCloseSound;
|
2022-10-18 09:26:55 +02:00
|
|
|
const ESM::RefId lockedSound = ESM::RefId::stringRefId("LockedDoor");
|
2012-02-27 09:39:35 +02:00
|
|
|
|
2018-06-16 14:21:28 +04:00
|
|
|
// FIXME: If NPC activate teleporting door, it can lead to crash due to iterator invalidation in the Actors
|
2018-06-17 10:13:03 +02:00
|
|
|
// update. Make such activation a no-op for now, like how it is in the vanilla game.
|
2018-06-16 14:21:28 +04:00
|
|
|
if (actor != MWMechanics::getPlayer() && ptr.getCellRef().getTeleport())
|
|
|
|
{
|
2022-08-24 20:38:52 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> action = std::make_unique<MWWorld::FailedAction>(std::string_view{}, ptr);
|
2018-06-16 14:21:28 +04:00
|
|
|
action->setSound(lockedSound);
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
2016-08-07 03:08:46 +09:00
|
|
|
// make door glow if player activates it with telekinesis
|
2018-06-16 14:21:28 +04:00
|
|
|
if (actor == MWMechanics::getPlayer()
|
|
|
|
&& MWBase::Environment::get().getWorld()->getDistanceToFacedObject()
|
2016-08-03 02:45:42 +09:00
|
|
|
> MWBase::Environment::get().getWorld()->getMaxActivationDistance())
|
|
|
|
{
|
|
|
|
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
2021-06-23 18:08:49 +02:00
|
|
|
if (animation)
|
|
|
|
{
|
|
|
|
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
int index = ESM::MagicEffect::effectStringToId("sEffectTelekinesis");
|
|
|
|
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(index);
|
2016-08-03 02:45:42 +09:00
|
|
|
|
2021-06-23 18:08:49 +02:00
|
|
|
animation->addSpellCastGlow(
|
|
|
|
effect, 1); // 1 second glow to match the time taken for a door opening or closing
|
|
|
|
}
|
2016-08-03 02:45:42 +09:00
|
|
|
}
|
|
|
|
|
2022-08-24 20:38:52 +02:00
|
|
|
MWWorld::ContainerStore& invStore = actor.getClass().getContainerStore(actor);
|
|
|
|
|
|
|
|
bool isLocked = ptr.getCellRef().getLockLevel() > 0;
|
|
|
|
bool isTrapped = !ptr.getCellRef().getTrap().empty();
|
|
|
|
bool hasKey = false;
|
|
|
|
std::string_view keyName;
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& keyId = ptr.getCellRef().getKey();
|
2017-06-10 22:33:14 +04:00
|
|
|
if (!keyId.empty())
|
2012-09-10 17:44:59 +02:00
|
|
|
{
|
2017-12-01 10:07:02 +04:00
|
|
|
MWWorld::Ptr keyPtr = invStore.search(keyId);
|
|
|
|
if (!keyPtr.isEmpty())
|
2012-09-10 17:44:59 +02:00
|
|
|
{
|
2017-12-01 10:07:02 +04:00
|
|
|
hasKey = true;
|
|
|
|
keyName = keyPtr.getClass().getName(keyPtr);
|
2012-09-10 17:44:59 +02:00
|
|
|
}
|
2010-08-30 12:02:47 +02:00
|
|
|
}
|
|
|
|
|
2020-04-12 14:40:06 +03:00
|
|
|
if (isLocked && hasKey)
|
2012-02-27 16:59:45 +02:00
|
|
|
{
|
2015-08-21 21:12:39 +12:00
|
|
|
if (actor == MWMechanics::getPlayer())
|
2022-08-24 20:38:52 +02:00
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox(std::string{ keyName } + " #{sKeyUsed}");
|
2020-04-12 14:40:06 +03:00
|
|
|
ptr.getCellRef().unlock(); // Call the function here. because that makes sense.
|
2012-09-10 17:44:59 +02:00
|
|
|
// using a key disarms the trap
|
2016-07-10 22:29:21 +09:00
|
|
|
if (isTrapped)
|
2016-07-10 21:42:03 +09:00
|
|
|
{
|
2023-02-17 19:20:29 +01:00
|
|
|
ptr.getCellRef().setTrap(ESM::RefId());
|
2022-10-18 09:26:55 +02:00
|
|
|
MWBase::Environment::get().getSoundManager()->playSound3D(
|
|
|
|
ptr, ESM::RefId::stringRefId("Disarm Trap"), 1.0f, 1.0f);
|
2016-07-10 22:29:21 +09:00
|
|
|
isTrapped = false;
|
2016-07-10 21:42:03 +09:00
|
|
|
}
|
2012-02-27 16:59:45 +02:00
|
|
|
}
|
2010-08-30 11:56:55 +02:00
|
|
|
|
2016-07-10 22:29:21 +09:00
|
|
|
if (!isLocked || hasKey)
|
2010-08-03 18:44:52 +02:00
|
|
|
{
|
2016-07-10 22:29:21 +09:00
|
|
|
if (isTrapped)
|
2010-08-03 18:44:52 +02:00
|
|
|
{
|
2012-09-10 17:44:59 +02:00
|
|
|
// Trap activation
|
2022-05-29 13:24:48 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> action
|
|
|
|
= std::make_unique<MWWorld::ActionTrap>(ptr.getCellRef().getTrap(), ptr);
|
2022-10-18 09:26:55 +02:00
|
|
|
action->setSound(ESM::RefId::stringRefId("Disarm Trap Fail"));
|
2012-08-19 20:11:50 -03:00
|
|
|
return action;
|
2010-08-03 18:44:52 +02:00
|
|
|
}
|
2012-09-10 17:44:59 +02:00
|
|
|
|
2014-05-25 14:13:07 +02:00
|
|
|
if (ptr.getCellRef().getTeleport())
|
2012-09-10 17:44:59 +02:00
|
|
|
{
|
2016-07-09 00:31:39 +09:00
|
|
|
if (actor == MWMechanics::getPlayer()
|
|
|
|
&& MWBase::Environment::get().getWorld()->getDistanceToFacedObject()
|
|
|
|
> MWBase::Environment::get().getWorld()->getMaxActivationDistance())
|
|
|
|
{
|
|
|
|
// player activated teleport door with telekinesis
|
2022-05-29 13:24:48 +02:00
|
|
|
return std::make_unique<MWWorld::FailedAction>();
|
2016-07-09 00:31:39 +09:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-05-29 13:24:48 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> action = std::make_unique<MWWorld::ActionTeleport>(
|
|
|
|
ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true);
|
2016-07-09 00:31:39 +09:00
|
|
|
action->setSound(openSound);
|
|
|
|
return action;
|
2018-06-19 14:17:33 +04:00
|
|
|
}
|
2012-09-10 17:44:59 +02:00
|
|
|
}
|
2010-08-03 18:44:52 +02:00
|
|
|
else
|
|
|
|
{
|
2012-09-10 17:44:59 +02:00
|
|
|
// animated door
|
2022-05-29 13:24:48 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> action = std::make_unique<MWWorld::ActionDoor>(ptr);
|
2019-08-25 15:20:14 +02:00
|
|
|
const auto doorState = getDoorState(ptr);
|
2014-05-15 01:58:44 +02:00
|
|
|
bool opening = true;
|
2015-11-12 00:58:29 +01:00
|
|
|
float doorRot = ptr.getRefData().getPosition().rot[2] - ptr.getCellRef().getPosition().rot[2];
|
2019-08-25 15:20:14 +02:00
|
|
|
if (doorState == MWWorld::DoorState::Opening)
|
2014-05-15 01:58:44 +02:00
|
|
|
opening = false;
|
2019-08-25 15:20:14 +02:00
|
|
|
if (doorState == MWWorld::DoorState::Idle && doorRot != 0)
|
2014-05-15 01:58:44 +02:00
|
|
|
opening = false;
|
|
|
|
|
|
|
|
if (opening)
|
2013-07-26 18:43:06 +02:00
|
|
|
{
|
|
|
|
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, closeSound, 0.5f);
|
2015-11-26 23:40:02 -08:00
|
|
|
// Doors rotate at 90 degrees per second, so start the sound at
|
|
|
|
// where it would be at the current rotation.
|
2018-09-17 14:52:43 +04:00
|
|
|
float offset = doorRot / (osg::PI * 0.5f);
|
2013-07-26 18:43:06 +02:00
|
|
|
action->setSoundOffset(offset);
|
2013-04-28 14:59:15 +02:00
|
|
|
action->setSound(openSound);
|
2013-07-26 18:43:06 +02:00
|
|
|
}
|
2013-04-28 14:59:15 +02:00
|
|
|
else
|
2013-07-26 18:43:06 +02:00
|
|
|
{
|
|
|
|
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, openSound, 0.5f);
|
2018-09-17 14:52:43 +04:00
|
|
|
float offset = 1.0f - doorRot / (osg::PI * 0.5f);
|
2015-11-26 23:40:02 -08:00
|
|
|
action->setSoundOffset(std::max(offset, 0.0f));
|
2013-04-28 14:59:15 +02:00
|
|
|
action->setSound(closeSound);
|
2013-07-26 18:43:06 +02:00
|
|
|
}
|
2012-09-10 17:44:59 +02:00
|
|
|
|
|
|
|
return action;
|
2010-08-03 18:44:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-10 17:44:59 +02:00
|
|
|
// locked, and we can't open.
|
2022-08-24 20:38:52 +02:00
|
|
|
std::unique_ptr<MWWorld::Action> action = std::make_unique<MWWorld::FailedAction>(std::string_view{}, ptr);
|
2012-09-10 17:44:59 +02:00
|
|
|
action->setSound(lockedSound);
|
2012-08-19 20:11:50 -03:00
|
|
|
return action;
|
2010-08-03 18:44:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-18 16:50:32 +01:00
|
|
|
bool Door::canLock(const MWWorld::ConstPtr& ptr) const
|
2015-08-04 17:33:34 +02:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-07-07 00:03:14 +09:00
|
|
|
bool Door::allowTelekinesis(const MWWorld::ConstPtr& ptr) const
|
|
|
|
{
|
2016-07-09 00:31:39 +09:00
|
|
|
if (ptr.getCellRef().getTeleport() && ptr.getCellRef().getLockLevel() <= 0
|
|
|
|
&& ptr.getCellRef().getTrap().empty())
|
2016-07-07 00:03:14 +09:00
|
|
|
return false;
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& Door::getScript(const MWWorld::ConstPtr& ptr) const
|
2010-08-05 15:40:03 +02:00
|
|
|
{
|
2015-12-18 00:12:03 +01:00
|
|
|
const MWWorld::LiveCellRef<ESM::Door>* ref = ptr.get<ESM::Door>();
|
2010-08-05 15:40:03 +02:00
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
return ref->mBase->mScript;
|
2010-08-05 15:40:03 +02:00
|
|
|
}
|
|
|
|
|
2015-12-19 16:29:07 +01:00
|
|
|
MWGui::ToolTipInfo Door::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const
|
2012-04-16 22:58:16 +02:00
|
|
|
{
|
2015-12-18 15:27:06 +01:00
|
|
|
const MWWorld::LiveCellRef<ESM::Door>* ref = ptr.get<ESM::Door>();
|
2012-04-16 22:58:16 +02:00
|
|
|
|
|
|
|
MWGui::ToolTipInfo info;
|
2022-08-16 21:15:03 +02:00
|
|
|
std::string_view name = getName(ptr);
|
2022-08-24 22:16:03 +02:00
|
|
|
info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name));
|
2012-04-16 22:58:16 +02:00
|
|
|
|
|
|
|
std::string text;
|
|
|
|
|
2014-05-25 14:13:07 +02:00
|
|
|
if (ptr.getCellRef().getTeleport())
|
2012-04-16 22:58:16 +02:00
|
|
|
{
|
2012-09-22 21:35:57 +02:00
|
|
|
text += "\n#{sTo}";
|
2012-12-23 23:23:24 +04:00
|
|
|
text += "\n" + getDestination(*ref);
|
2012-04-16 22:58:16 +02:00
|
|
|
}
|
|
|
|
|
2018-06-19 14:17:33 +04:00
|
|
|
int lockLevel = ptr.getCellRef().getLockLevel();
|
|
|
|
if (lockLevel > 0 && lockLevel != ESM::UnbreakableLock)
|
2014-05-25 14:13:07 +02:00
|
|
|
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ptr.getCellRef().getLockLevel());
|
|
|
|
else if (ptr.getCellRef().getLockLevel() < 0)
|
2014-04-23 13:02:51 -04:00
|
|
|
text += "\n#{sUnlocked}";
|
2022-08-16 21:15:03 +02:00
|
|
|
if (!ptr.getCellRef().getTrap().empty())
|
2012-09-22 21:35:57 +02:00
|
|
|
text += "\n#{sTrapped}";
|
2012-04-16 22:58:16 +02:00
|
|
|
|
2012-04-24 02:02:03 +02:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
|
2014-07-11 11:57:21 +02:00
|
|
|
{
|
2014-07-22 20:03:35 +02:00
|
|
|
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript.getRefIdString(), "Script");
|
2014-07-11 11:57:21 +02:00
|
|
|
}
|
2012-04-16 22:58:16 +02:00
|
|
|
info.text = text;
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
2012-07-25 17:18:17 +04:00
|
|
|
|
2012-12-23 23:23:24 +04:00
|
|
|
std::string Door::getDestination(const MWWorld::LiveCellRef<ESM::Door>& door)
|
|
|
|
{
|
2023-01-19 17:31:45 +01:00
|
|
|
std::string_view dest = door.mRef.getDestCell();
|
2021-02-10 22:13:04 +01:00
|
|
|
if (dest.empty())
|
2012-12-23 23:23:24 +04:00
|
|
|
{
|
|
|
|
// door leads to exterior, use cell name (if any), otherwise translated region name
|
2021-02-10 22:13:04 +01:00
|
|
|
auto world = MWBase::Environment::get().getWorld();
|
2022-05-23 19:21:44 +02:00
|
|
|
const osg::Vec2i index
|
|
|
|
= MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]);
|
|
|
|
const ESM::Cell* cell = world->getStore().get<ESM::Cell>().search(index.x(), index.y());
|
2021-02-10 22:13:04 +01:00
|
|
|
dest = world->getCellName(cell);
|
2012-12-23 23:23:24 +04:00
|
|
|
}
|
|
|
|
|
2022-12-01 22:09:30 +01:00
|
|
|
return "#{sCell=" + std::string{ dest } + "}";
|
2012-12-23 23:23:24 +04:00
|
|
|
}
|
|
|
|
|
2015-12-18 16:24:24 +01:00
|
|
|
MWWorld::Ptr Door::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const
|
2012-07-25 17:18:17 +04:00
|
|
|
{
|
2015-12-18 16:24:24 +01:00
|
|
|
const MWWorld::LiveCellRef<ESM::Door>* ref = ptr.get<ESM::Door>();
|
2012-07-25 17:18:17 +04:00
|
|
|
|
2015-11-14 17:12:05 +01:00
|
|
|
return MWWorld::Ptr(cell.insert(ref), &cell);
|
2012-07-25 17:18:17 +04:00
|
|
|
}
|
2014-05-15 01:58:44 +02:00
|
|
|
|
|
|
|
void Door::ensureCustomData(const MWWorld::Ptr& ptr) const
|
|
|
|
{
|
|
|
|
if (!ptr.getRefData().getCustomData())
|
|
|
|
{
|
2021-04-03 00:48:35 +02:00
|
|
|
ptr.getRefData().setCustomData(std::make_unique<DoorCustomData>());
|
2014-05-15 01:58:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-25 15:20:14 +02:00
|
|
|
MWWorld::DoorState Door::getDoorState(const MWWorld::ConstPtr& ptr) const
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2015-12-19 15:57:37 +01:00
|
|
|
if (!ptr.getRefData().getCustomData())
|
2019-08-25 15:20:14 +02:00
|
|
|
return MWWorld::DoorState::Idle;
|
2015-11-29 14:13:14 +01:00
|
|
|
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
2014-05-15 01:58:44 +02:00
|
|
|
return customData.mDoorState;
|
|
|
|
}
|
|
|
|
|
2019-08-25 15:20:14 +02:00
|
|
|
void Door::setDoorState(const MWWorld::Ptr& ptr, MWWorld::DoorState state) const
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2014-09-11 05:48:46 +02:00
|
|
|
if (ptr.getCellRef().getTeleport())
|
|
|
|
throw std::runtime_error("load doors can't be moved");
|
|
|
|
|
2014-05-15 01:58:44 +02:00
|
|
|
ensureCustomData(ptr);
|
2015-11-29 14:13:14 +01:00
|
|
|
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
2014-05-15 01:58:44 +02:00
|
|
|
customData.mDoorState = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Door::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const
|
|
|
|
{
|
2015-12-18 00:07:13 +01:00
|
|
|
if (!state.mHasCustomState)
|
|
|
|
return;
|
2020-03-17 14:15:19 +04:00
|
|
|
|
2014-05-15 01:58:44 +02:00
|
|
|
ensureCustomData(ptr);
|
2015-11-29 14:13:14 +01:00
|
|
|
DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
2020-03-17 14:15:19 +04:00
|
|
|
const ESM::DoorState& doorState = state.asDoorState();
|
|
|
|
customData.mDoorState = MWWorld::DoorState(doorState.mDoorState);
|
2014-05-15 01:58:44 +02:00
|
|
|
}
|
|
|
|
|
2015-12-18 00:18:06 +01:00
|
|
|
void Door::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const
|
2014-05-15 01:58:44 +02:00
|
|
|
{
|
2015-12-18 00:07:13 +01:00
|
|
|
if (!ptr.getRefData().getCustomData())
|
|
|
|
{
|
|
|
|
state.mHasCustomState = false;
|
|
|
|
return;
|
|
|
|
}
|
2014-05-15 01:58:44 +02:00
|
|
|
|
2020-03-17 14:15:19 +04:00
|
|
|
const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData();
|
|
|
|
ESM::DoorState& doorState = state.asDoorState();
|
|
|
|
doorState.mDoorState = int(customData.mDoorState);
|
2014-05-15 01:58:44 +02:00
|
|
|
}
|
|
|
|
|
2010-08-03 15:24:44 +02:00
|
|
|
}
|