1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 12:35:46 +00:00
elsid ce263af393
Use existing functions and objects to call correctMeshPath etc
Remove WindowManager wrappers.

It's not safe to use WindowManager in all places and it's not required.
Environment stores resource system providing VFS required to call these
functions. In the case of ObjectPaging it's available from the member variable.
Also ObjectPaging::createChunk may access WindowManager when it's already
destructed when exiting the game because it's destructed before CellPreloader
finishes all background jobs. Engine::mResourceSystem is destructed after all
other systems so it's safe to use it.
2022-06-29 00:58:49 +02:00

240 lines
7.9 KiB
C++

#include "light.hpp"
#include <MyGUI_TextIterator.h>
#include <components/esm3/loadligh.hpp>
#include <components/esm3/objectstate.hpp>
#include <components/settings/settings.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/failedaction.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwphysics/physicssystem.hpp"
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "classmodel.hpp"
namespace MWClass
{
Light::Light()
: MWWorld::RegisteredClass<Light>(ESM::Light::sRecordId)
{
}
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
// Insert even if model is empty, so that the light is added
renderingInterface.getObjects().insertModel(ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
}
void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->mBase != nullptr);
insertObjectPhysics(ptr, model, rotation, physics);
if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
MWSound::Type::Sfx,
MWSound::PlayMode::Loop);
}
void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const
{
// TODO: add option somewhere to enable collision for placeable objects
if ((ptr.get<ESM::Light>()->mBase->mData.mFlags & ESM::Light::Carry) == 0)
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World);
}
bool Light::useAnim() const
{
return true;
}
std::string Light::getModel(const MWWorld::ConstPtr &ptr) const
{
return getClassModel<ESM::Light>(ptr);
}
std::string Light::getName (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
if (ref->mBase->mModel.empty())
return std::string();
const std::string& name = ref->mBase->mName;
return !name.empty() ? name : ref->mBase->mId;
}
std::unique_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
{
if(!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
return std::make_unique<MWWorld::NullAction>();
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
if(!(ref->mBase->mData.mFlags&ESM::Light::Carry))
return std::make_unique<MWWorld::FailedAction>();
return defaultItemActivate(ptr, actor);
}
std::string Light::getScript (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Light::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
std::vector<int> slots_;
if (ref->mBase->mData.mFlags & ESM::Light::Carry)
slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft));
return std::make_pair (slots_, false);
}
int Light::getValue (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
return ref->mBase->mData.mValue;
}
std::string Light::getUpSoundId (const MWWorld::ConstPtr& ptr) const
{
return std::string("Item Misc Up");
}
std::string Light::getDownSoundId (const MWWorld::ConstPtr& ptr) const
{
return std::string("Item Misc Down");
}
std::string Light::getInventoryIcon (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
return ref->mBase->mIcon;
}
bool Light::hasToolTip (const MWWorld::ConstPtr& ptr) const
{
return showsInInventory(ptr);
}
MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
MWGui::ToolTipInfo info;
info.caption = MyGUI::TextIterator::toTagsString(getName(ptr)) + MWGui::ToolTips::getCountString(count);
info.icon = ref->mBase->mIcon;
std::string text;
// Don't show duration for infinite light sources.
if (Settings::Manager::getBool("show effect duration","Game") && ptr.getClass().getRemainingUsageTime(ptr) != -1)
text += MWGui::ToolTips::getDurationString(ptr.getClass().getRemainingUsageTime(ptr), "\n#{sDuration}");
text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}");
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getCellRefString(ptr.getCellRef());
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
return info;
}
bool Light::showsInInventory (const MWWorld::ConstPtr& ptr) const
{
const ESM::Light* light = ptr.get<ESM::Light>()->mBase;
if (!(light->mData.mFlags & ESM::Light::Carry))
return false;
return Class::showsInInventory(ptr);
}
std::unique_ptr<MWWorld::Action> Light::use (const MWWorld::Ptr& ptr, bool force) const
{
std::unique_ptr<MWWorld::Action> action = std::make_unique<MWWorld::ActionEquip>(ptr, force);
action->setSound(getUpSoundId(ptr));
return action;
}
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
{
ptr.getCellRef().setChargeFloat(duration);
}
float Light::getRemainingUsageTime (const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
if (ptr.getCellRef().getCharge() == -1)
return static_cast<float>(ref->mBase->mData.mTime);
else
return ptr.getCellRef().getChargeFloat();
}
MWWorld::Ptr Light::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
return MWWorld::Ptr(cell.insert(ref), &cell);
}
bool Light::canSell (const MWWorld::ConstPtr& item, int npcServices) const
{
return (npcServices & ESM::NPC::Lights) != 0;
}
float Light::getWeight(const MWWorld::ConstPtr &ptr) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
return ref->mBase->mData.mWeight;
}
std::pair<int, std::string> Light::canBeEquipped(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &npc) const
{
const MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
return std::make_pair(0,"");
return std::make_pair(1,"");
}
std::string Light::getSound(const MWWorld::ConstPtr& ptr) const
{
return ptr.get<ESM::Light>()->mBase->mSound;
}
}