1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 17:19:56 +00:00
openmw-tes3mp/apps/openmw/mwclass/door.cpp

274 lines
8.7 KiB
C++
Raw Normal View History

2010-08-03 13:24:44 +00:00
#include "door.hpp"
#include <components/esm/loaddoor.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
2010-08-03 15:11:41 +00:00
#include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp"
2012-11-17 17:17:08 +00:00
#include "../mwworld/failedaction.hpp"
#include "../mwworld/actionteleport.hpp"
2013-04-28 12:59:15 +00:00
#include "../mwworld/actiondoor.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/actiontrap.hpp"
2010-08-03 15:11:41 +00:00
#include "../mwgui/tooltips.hpp"
2011-11-12 20:58:22 +00:00
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
2010-08-03 13:24:44 +00:00
namespace MWClass
{
2011-11-12 04:01:12 +00:00
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{
2012-07-24 16:22:11 +00:00
const std::string model = getModel(ptr);
if (!model.empty()) {
2013-08-07 10:51:57 +00:00
renderingInterface.getObjects().insertModel(ptr, model);
}
}
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
2011-11-12 04:01:12 +00:00
{
2012-07-24 16:22:11 +00:00
const std::string model = getModel(ptr);
if(!model.empty())
physics.addObject(ptr);
2012-07-24 16:22:11 +00:00
}
2012-07-27 10:00:10 +00:00
2012-07-24 16:22:11 +00:00
std::string Door::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
2011-11-12 04:01:12 +00:00
ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
assert(ref->mBase != NULL);
2011-11-12 04:01:12 +00:00
2012-11-05 12:07:59 +00:00
const std::string &model = ref->mBase->mModel;
2012-07-24 16:22:11 +00:00
if (!model.empty()) {
return "meshes\\" + model;
2011-11-12 04:01:12 +00:00
}
2012-07-24 16:22:11 +00:00
return "";
2011-11-12 04:01:12 +00:00
}
2010-08-03 15:11:41 +00:00
std::string Door::getName (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
2010-08-03 15:11:41 +00:00
ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->mRef.mDestCell;
2012-11-05 12:07:59 +00:00
return ref->mBase->mName;
2010-08-03 15:11:41 +00:00
}
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
{
MWWorld::LiveCellRef<ESM::Door> *ref = ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
const std::string &openSound = ref->mBase->mOpenSound;
2013-04-28 12:59:15 +00:00
const std::string &closeSound = ref->mBase->mCloseSound;
2012-02-27 07:39:35 +00:00
const std::string lockedSound = "LockedDoor";
2012-02-27 14:59:45 +00:00
const std::string trapActivationSound = "Disarm Trap Fail";
2012-02-27 07:39:35 +00:00
MWWorld::ContainerStore &invStore = get(actor).getContainerStore(actor);
2012-09-17 07:37:50 +00:00
bool needKey = ptr.getCellRef().mLockLevel>0;
bool hasKey = false;
std::string keyName;
2012-11-02 20:43:07 +00:00
// make key id lowercase
std::string keyId = ptr.getCellRef().mKey;
2013-01-09 19:51:52 +00:00
Misc::StringUtils::toLower(keyId);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{
2012-11-02 20:43:07 +00:00
std::string refId = it->getCellRef().mRefID;
2013-01-09 19:51:52 +00:00
Misc::StringUtils::toLower(refId);
if (refId == keyId)
{
hasKey = true;
keyName = get(*it).getName(*it);
}
}
if (needKey && hasKey)
2012-02-27 14:59:45 +00:00
{
if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
2012-09-17 07:37:50 +00:00
ptr.getCellRef().mLockLevel = 0;
// using a key disarms the trap
2012-09-17 07:37:50 +00:00
ptr.getCellRef().mTrap = "";
2012-02-27 14:59:45 +00:00
}
if (!needKey || hasKey)
{
2012-09-17 07:37:50 +00:00
if(!ptr.getCellRef().mTrap.empty())
{
// Trap activation
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().mTrap, ptr));
action->setSound(trapActivationSound);
return action;
}
2012-11-05 12:07:59 +00:00
if (ref->mRef.mTeleport)
{
// teleport door
/// \todo remove this if clause once ActionTeleport can also support other actors
if (MWBase::Environment::get().getWorld()->getPlayerPtr()==actor)
{
2012-11-05 12:07:59 +00:00
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest));
action->setSound(openSound);
return action;
}
else
{
// another NPC or a creature is using the door
2012-11-19 20:04:49 +00:00
return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction);
}
}
else
{
// animated door
2013-04-28 12:59:15 +00:00
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionDoor(ptr));
2013-04-29 09:00:15 +00:00
if (MWBase::Environment::get().getWorld()->getOpenOrCloseDoor(ptr))
{
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr,
closeSound, 0.5);
float offset = ptr.getRefData().getLocalRotation().rot[2]/ 3.14159265 * 2.0;
action->setSoundOffset(offset);
2013-04-28 12:59:15 +00:00
action->setSound(openSound);
}
2013-04-28 12:59:15 +00:00
else
{
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr,
openSound, 0.5);
float offset = 1.0 - ptr.getRefData().getLocalRotation().rot[2]/ 3.14159265 * 2.0;
//most if not all door have closing bang somewhere in the middle of the sound,
//so we divide offset by two
action->setSoundOffset(offset * 0.5);
2013-04-28 12:59:15 +00:00
action->setSound(closeSound);
}
return action;
}
}
else
{
// locked, and we can't open.
2012-11-19 20:04:49 +00:00
boost::shared_ptr<MWWorld::Action> action(new MWWorld::FailedAction);
action->setSound(lockedSound);
return action;
}
}
void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{
if (lockLevel<0)
lockLevel = 0;
2012-09-17 07:37:50 +00:00
ptr.getCellRef().mLockLevel = lockLevel;
}
void Door::unlock (const MWWorld::Ptr& ptr) const
{
2012-09-17 07:37:50 +00:00
ptr.getCellRef().mLockLevel = 0;
}
std::string Door::getScript (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
return ref->mBase->mScript;
}
2010-08-03 13:24:44 +00:00
void Door::registerSelf()
{
boost::shared_ptr<Class> instance (new Door);
registerClass (typeid (ESM::Door).name(), instance);
}
bool Door::hasToolTip (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
MWGui::ToolTipInfo info;
2012-11-05 12:07:59 +00:00
info.caption = ref->mBase->mName;
std::string text;
2012-11-05 12:07:59 +00:00
if (ref->mRef.mTeleport)
{
2012-09-22 19:35:57 +00:00
text += "\n#{sTo}";
2012-12-23 19:23:24 +00:00
text += "\n" + getDestination(*ref);
}
2012-11-05 12:07:59 +00:00
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
2012-09-22 19:35:57 +00:00
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
2012-11-05 12:07:59 +00:00
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
2012-12-23 19:23:24 +00:00
std::string Door::getDestination (const MWWorld::LiveCellRef<ESM::Door>& door)
{
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest;
if (door.mRef.mDestCell != "")
{
// door leads to an interior, use interior name as tooltip
dest = door.mRef.mDestCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "")
dest = cell->mName;
else
{
const ESM::Region* region =
store.get<ESM::Region>().find(cell->mRegion);
//name as is, not a token
return region->mName;
}
}
return "#{sCell=" + dest + "}";
}
MWWorld::Ptr
Door::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
2012-11-05 12:07:59 +00:00
return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell);
}
2010-08-03 13:24:44 +00:00
}