mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Add special cell for objects created via Lua scripts and not yet added into the world
This commit is contained in:
parent
1d73780621
commit
d830ae37b1
4 changed files with 25 additions and 6 deletions
|
@ -21,8 +21,8 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/scene.hpp"
|
||||
#include "../mwworld/store.hpp"
|
||||
#include "../mwworld/worldmodel.hpp"
|
||||
|
||||
#include "luaevents.hpp"
|
||||
#include "luamanagerimp.hpp"
|
||||
|
@ -226,13 +226,11 @@ namespace MWLua
|
|||
api["activeActors"] = GObjectList{ worldView->getActorsInScene() };
|
||||
api["players"] = GObjectList{ worldView->getPlayers() };
|
||||
api["createObject"] = [](std::string_view recordId, sol::optional<int> count) -> GObject {
|
||||
// Doesn't matter which cell to use because the new object will be in disabled state.
|
||||
MWWorld::CellStore* cell = MWBase::Environment::get().getWorldScene()->getCurrentCell();
|
||||
|
||||
MWWorld::ManualRef mref(*MWBase::Environment::get().getESMStore(), ESM::RefId::deserializeText(recordId));
|
||||
const MWWorld::Ptr& ptr = mref.getPtr();
|
||||
ptr.getRefData().disable();
|
||||
MWWorld::Ptr newPtr = ptr.getClass().copyToCell(ptr, *cell, count.value_or(1));
|
||||
MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getDraftCell();
|
||||
MWWorld::Ptr newPtr = ptr.getClass().copyToCell(ptr, cell, count.value_or(1));
|
||||
return GObject(newPtr);
|
||||
};
|
||||
api["getObjectByFormId"] = [](std::string_view formIdStr) -> GObject {
|
||||
|
|
|
@ -182,7 +182,8 @@ namespace MWLua
|
|||
[](const ObjectT& o) -> std::string { return o.ptr().getCellRef().getRefId().serializeText(); });
|
||||
objectT["cell"] = sol::readonly_property([](const ObjectT& o) -> sol::optional<Cell<ObjectT>> {
|
||||
const MWWorld::Ptr& ptr = o.ptr();
|
||||
if (ptr.isInCell())
|
||||
MWWorld::WorldModel* wm = MWBase::Environment::get().getWorldModel();
|
||||
if (ptr.isInCell() && ptr.getCell() != &wm->getDraftCell())
|
||||
return Cell<ObjectT>{ ptr.getCell() };
|
||||
else
|
||||
return sol::nullopt;
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace MWWorld
|
|||
{
|
||||
namespace
|
||||
{
|
||||
const ESM::RefId draftCellId = ESM::RefId::index(ESM::REC_CSTA, 0);
|
||||
|
||||
template <class T>
|
||||
CellStore& emplaceCellStore(ESM::RefId id, const T& cell, ESMStore& store, ESM::ReadersCache& readers,
|
||||
std::unordered_map<ESM::RefId, CellStore>& cells)
|
||||
|
@ -159,6 +161,7 @@ MWWorld::WorldModel::WorldModel(MWWorld::ESMStore& store, ESM::ReadersCache& rea
|
|||
, mReaders(readers)
|
||||
, mIdCache(Settings::cells().mPointersCacheSize, { ESM::RefId(), nullptr })
|
||||
{
|
||||
mDraftCell.mId = draftCellId;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
|
@ -229,6 +232,13 @@ namespace MWWorld
|
|||
if (it != mCells.end())
|
||||
return &it->second;
|
||||
|
||||
if (id == draftCellId)
|
||||
{
|
||||
CellStore& cellStore = emplaceCellStore(id, Cell(mDraftCell), mStore, mReaders, mCells);
|
||||
cellStore.load();
|
||||
return &cellStore;
|
||||
}
|
||||
|
||||
if (const auto* exteriorId = id.getIf<ESM::ESM3ExteriorCellRefId>())
|
||||
return &getExterior(
|
||||
ESM::ExteriorCellLocation(exteriorId->getX(), exteriorId->getY(), ESM::Cell::sDefaultWorldspaceId),
|
||||
|
@ -261,6 +271,11 @@ namespace MWWorld
|
|||
return *result;
|
||||
}
|
||||
|
||||
CellStore& WorldModel::getDraftCell() const
|
||||
{
|
||||
return getCell(draftCellId);
|
||||
}
|
||||
|
||||
CellStore* WorldModel::findCell(std::string_view name, bool forceLoad) const
|
||||
{
|
||||
if (CellStore* const cellStore = findInterior(name, forceLoad))
|
||||
|
|
|
@ -53,6 +53,10 @@ namespace MWWorld
|
|||
|
||||
CellStore& getCell(ESM::RefId Id, bool forceLoad = true) const;
|
||||
|
||||
// Returns a special cell that is never active. Can be used for creating objects
|
||||
// without adding them to the scene.
|
||||
CellStore& getDraftCell() const;
|
||||
|
||||
CellStore* findInterior(std::string_view name, bool forceLoad = true) const;
|
||||
|
||||
CellStore& getInterior(std::string_view name, bool forceLoad = true) const;
|
||||
|
@ -103,6 +107,7 @@ namespace MWWorld
|
|||
mutable std::unordered_map<ESM::RefId, CellStore> mCells;
|
||||
mutable std::map<std::string, CellStore*, Misc::StringUtils::CiComp> mInteriors;
|
||||
mutable std::map<ESM::ExteriorCellLocation, CellStore*> mExteriors;
|
||||
ESM::Cell mDraftCell;
|
||||
std::vector<std::pair<ESM::RefId, CellStore*>> mIdCache;
|
||||
std::size_t mIdCacheIndex = 0;
|
||||
PtrRegistry mPtrRegistry;
|
||||
|
|
Loading…
Reference in a new issue