mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 08:45:33 +00:00
Avoids a lot a special cases for ESM3 vs ESM4 cells.
This commit is contained in:
parent
f3d5f6345e
commit
084207af64
19 changed files with 137 additions and 101 deletions
|
@ -357,13 +357,11 @@ namespace MWMechanics
|
|||
case AiCombatStorage::FleeState_Idle:
|
||||
{
|
||||
float triggerDist = getMaxAttackDistance(target);
|
||||
auto cellVariant = storage.mCell->getCell();
|
||||
if (!cellVariant->isEsm4() && storage.mLOS
|
||||
&& (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist))
|
||||
const MWWorld::Cell* cellVariant = storage.mCell->getCell();
|
||||
if (storage.mLOS && (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist))
|
||||
{
|
||||
const ESM::Pathgrid* pathgrid
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(
|
||||
cellVariant->getEsm3());
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cellVariant);
|
||||
|
||||
bool runFallback = true;
|
||||
|
||||
|
|
|
@ -411,14 +411,11 @@ bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const
|
|||
|
||||
bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position)
|
||||
{
|
||||
if (getPlayer().getCell()->getCell()->isEsm4())
|
||||
return false;
|
||||
|
||||
const ESM::Cell* playerCell(&getPlayer().getCell()->getCell()->getEsm3());
|
||||
const MWWorld::Cell* playerCell = getPlayer().getCell()->getCell();
|
||||
if (playerCell->isExterior())
|
||||
{
|
||||
// get actor's distance from origin of center cell
|
||||
Misc::CoordinateConverter(playerCell).toLocal(position);
|
||||
Misc::CoordinateConverter(*playerCell).toLocal(position);
|
||||
|
||||
// currently assumes 3 x 3 grid for exterior cells, with player at center cell.
|
||||
// AI shuts down actors before they reach edges of 3 x 3 grid.
|
||||
|
|
|
@ -271,9 +271,9 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
// Initialization to discover & store allowed node points for this actor.
|
||||
if (!actor.getCell()->getCell()->isEsm4() && storage.mPopulateAvailableNodes)
|
||||
if (storage.mPopulateAvailableNodes)
|
||||
{
|
||||
getAllowedNodes(actor, &actor.getCell()->getCell()->getEsm3(), storage);
|
||||
getAllowedNodes(actor, actor.getCell()->getCell(), storage);
|
||||
}
|
||||
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
|
@ -721,8 +721,8 @@ namespace MWMechanics
|
|||
return;
|
||||
|
||||
AiWanderStorage& storage = state.get<AiWanderStorage>();
|
||||
if (!actor.getCell()->getCell()->isEsm4() && storage.mPopulateAvailableNodes)
|
||||
getAllowedNodes(actor, &actor.getCell()->getCell()->getEsm3(), storage);
|
||||
if (storage.mPopulateAvailableNodes)
|
||||
getAllowedNodes(actor, actor.getCell()->getCell(), storage);
|
||||
|
||||
if (storage.mAllowedNodes.empty())
|
||||
return;
|
||||
|
@ -800,12 +800,8 @@ namespace MWMechanics
|
|||
void AiWander::getNeighbouringNodes(
|
||||
ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points)
|
||||
{
|
||||
if (currentCell->getCell()->isEsm4())
|
||||
return;
|
||||
auto cell3 = currentCell->getCell()->getEsm3();
|
||||
|
||||
const ESM::Pathgrid* pathgrid
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(cell3);
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*currentCell->getCell());
|
||||
|
||||
if (pathgrid == nullptr || pathgrid->mPoints.empty())
|
||||
return;
|
||||
|
@ -815,7 +811,7 @@ namespace MWMechanics
|
|||
getPathGridGraph(currentCell).getNeighbouringPoints(index, points);
|
||||
}
|
||||
|
||||
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell, AiWanderStorage& storage)
|
||||
void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const MWWorld::Cell* cell, AiWanderStorage& storage)
|
||||
{
|
||||
// infrequently used, therefore no benefit in caching it as a member
|
||||
const ESM::Pathgrid* pathgrid
|
||||
|
@ -839,7 +835,7 @@ namespace MWMechanics
|
|||
if (mDistance && storage.mCanWanderAlongPathGrid && !actor.getClass().isPureWaterCreature(actor))
|
||||
{
|
||||
// get NPC's position in local (i.e. cell) coordinates
|
||||
auto converter = Misc::CoordinateConverter(cell);
|
||||
auto converter = Misc::CoordinateConverter(*cell);
|
||||
const osg::Vec3f npcPos = converter.toLocalVec3(mInitialActorPosition);
|
||||
|
||||
// Find closest pathgrid point
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace Misc
|
|||
class CoordinateConverter;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Cell;
|
||||
}
|
||||
namespace MWMechanics
|
||||
{
|
||||
/// \brief This class holds the variables AiWander needs which are deleted if the package becomes inactive.
|
||||
|
@ -147,7 +151,7 @@ namespace MWMechanics
|
|||
void getNeighbouringNodes(
|
||||
ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points);
|
||||
|
||||
void getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell, AiWanderStorage& storage);
|
||||
void getAllowedNodes(const MWWorld::Ptr& actor, const MWWorld::Cell* cell, AiWanderStorage& storage);
|
||||
|
||||
void trimAllowedNodes(std::vector<ESM::Pathgrid::Point>& nodes, const PathFinder& pathfinder);
|
||||
|
||||
|
|
|
@ -104,9 +104,7 @@ namespace MWMechanics
|
|||
if (mIsGraphConstructed)
|
||||
return true;
|
||||
|
||||
if (cell->getCell()->isEsm4())
|
||||
return false;
|
||||
mCell = &cell->getCell()->getEsm3();
|
||||
mCell = cell->getCell();
|
||||
|
||||
mPathgrid = MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*mCell);
|
||||
if (!mPathgrid)
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace ESM
|
|||
namespace MWWorld
|
||||
{
|
||||
class CellStore;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
|
@ -41,7 +42,7 @@ namespace MWMechanics
|
|||
std::deque<ESM::Pathgrid::Point> aStarSearch(const int start, const int end) const;
|
||||
|
||||
private:
|
||||
const ESM::Cell* mCell;
|
||||
const MWWorld::Cell* mCell;
|
||||
const ESM::Pathgrid* mPathgrid;
|
||||
|
||||
struct ConnectedPoint // edge
|
||||
|
|
|
@ -102,9 +102,8 @@ namespace MWRender
|
|||
void Pathgrid::enableCellPathgrid(const MWWorld::CellStore* store)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
if (store->getCell()->isEsm4())
|
||||
return;
|
||||
const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(store->getCell()->getEsm3());
|
||||
|
||||
const ESM::Pathgrid* pathgrid = world->getStore().get<ESM::Pathgrid>().search(*store->getCell());
|
||||
if (!pathgrid)
|
||||
return;
|
||||
|
||||
|
|
|
@ -781,10 +781,8 @@ namespace MWSound
|
|||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::ConstPtr player = world->getPlayerPtr();
|
||||
if (player.getCell()->getCell()->isEsm4())
|
||||
return;
|
||||
|
||||
const ESM::Cell* curcell = &player.getCell()->getCell()->getEsm3();
|
||||
const MWWorld::Cell* curcell = player.getCell()->getCell();
|
||||
const auto update = mWaterSoundUpdater.update(player, *world);
|
||||
|
||||
WaterSoundAction action;
|
||||
|
@ -813,7 +811,7 @@ namespace MWSound
|
|||
}
|
||||
|
||||
std::pair<SoundManager::WaterSoundAction, Sound_Buffer*> SoundManager::getWaterSoundAction(
|
||||
const WaterSoundUpdate& update, const ESM::Cell* cell) const
|
||||
const WaterSoundUpdate& update, const MWWorld::Cell* cell) const
|
||||
{
|
||||
if (mNearWaterSound)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,11 @@ namespace ESM
|
|||
struct Cell;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace MWSound
|
||||
{
|
||||
class Sound_Output;
|
||||
|
@ -107,7 +112,7 @@ namespace MWSound
|
|||
|
||||
float mTimePassed;
|
||||
|
||||
const ESM::Cell* mLastCell;
|
||||
const MWWorld::Cell* mLastCell;
|
||||
|
||||
Sound* mCurrentRegionSound;
|
||||
|
||||
|
@ -143,7 +148,7 @@ namespace MWSound
|
|||
};
|
||||
|
||||
std::pair<WaterSoundAction, Sound_Buffer*> getWaterSoundAction(
|
||||
const WaterSoundUpdate& update, const ESM::Cell* cell) const;
|
||||
const WaterSoundUpdate& update, const MWWorld::Cell* cell) const;
|
||||
|
||||
SoundManager(const SoundManager& rhs);
|
||||
SoundManager& operator=(const SoundManager& rhs);
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace MWWorld
|
|||
.mDirectionalColor = cell.mLighting.directional,
|
||||
.mFogColor = cell.mLighting.fogColor,
|
||||
.mFogDensity = cell.mLighting.fogPower,}
|
||||
,mWaterHeight(cell.mWaterHeight)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -45,11 +46,16 @@ namespace MWWorld
|
|||
.mFogColor = cell.mAmbi.mFog,
|
||||
.mFogDensity = cell.mAmbi.mFogDensity,
|
||||
}
|
||||
,mWaterHeight(cell.mWater)
|
||||
{
|
||||
}
|
||||
|
||||
std::string Cell::getDescription() const
|
||||
{
|
||||
return isEsm4() ? mNameID : getEsm3().getDescription();
|
||||
return ESM::visit(ESM::VisitOverload{
|
||||
[&](const ESM::Cell& cell) { return cell.getDescription(); },
|
||||
[&](const ESM4::Cell& cell) { return cell.mEditorId; },
|
||||
},
|
||||
*this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace MWWorld
|
|||
std::string_view getDisplayName() const { return mDisplayname; }
|
||||
std::string getDescription() const;
|
||||
const MoodData& getMood() const { return mMood; }
|
||||
float getWaterHeight() const { return mWaterHeight; }
|
||||
|
||||
private:
|
||||
bool mIsExterior;
|
||||
|
@ -61,6 +62,8 @@ namespace MWWorld
|
|||
ESM::RefId mRegion;
|
||||
ESM::CellId mCellId;
|
||||
MoodData mMood;
|
||||
|
||||
float mWaterHeight;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
|
||||
namespace MWWorld
|
||||
{
|
||||
// makes it easier to use std visit with a variant
|
||||
template <class... Ts>
|
||||
struct RefVisit : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template <class... Ts>
|
||||
RefVisit(Ts...) -> RefVisit<Ts...>;
|
||||
|
||||
CellRef::CellRef(const ESM::CellRef& ref)
|
||||
: mCellRef(ESM::ReferenceVariant(ref))
|
||||
{
|
||||
|
@ -31,7 +21,7 @@ namespace MWWorld
|
|||
|
||||
const ESM::RefNum& CellRef::getRefNum() const
|
||||
{
|
||||
return std::visit(RefVisit{
|
||||
return std::visit(ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& /*ref*/) -> const ESM::RefNum& { return emptyRefNum; },
|
||||
[&](const ESM::CellRef& ref) -> const ESM::RefNum& { return ref.mRefNum; },
|
||||
},
|
||||
|
@ -59,7 +49,7 @@ namespace MWWorld
|
|||
return ref.mRefNum;
|
||||
};
|
||||
return std::visit(
|
||||
RefVisit{
|
||||
ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) -> const ESM::RefNum& { return emptyRefNum; },
|
||||
esm3Visit,
|
||||
},
|
||||
|
@ -68,7 +58,7 @@ namespace MWWorld
|
|||
|
||||
void CellRef::unsetRefNum()
|
||||
{
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mRefNum = emptyRefNum; },
|
||||
},
|
||||
|
@ -79,7 +69,11 @@ namespace MWWorld
|
|||
|
||||
const std::string& CellRef::getDestCell() const
|
||||
{
|
||||
return mCellRef.isESM4() ? emptyString : mCellRef.getEsm3().mDestCell;
|
||||
return std::visit(ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& /*ref*/) -> const std::string& { return emptyString; },
|
||||
[&](const ESM::CellRef& ref) -> const std::string& { return ref.mDestCell; },
|
||||
},
|
||||
mCellRef.mVariant);
|
||||
}
|
||||
|
||||
void CellRef::setScale(float scale)
|
||||
|
@ -99,7 +93,7 @@ namespace MWWorld
|
|||
|
||||
float CellRef::getEnchantmentCharge() const
|
||||
{
|
||||
return std::visit(RefVisit{
|
||||
return std::visit(ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& /*ref*/) { return 0.f; },
|
||||
[&](const ESM::CellRef& ref) { return ref.mEnchantmentCharge; },
|
||||
},
|
||||
|
@ -128,7 +122,7 @@ namespace MWWorld
|
|||
{
|
||||
mChanged = true;
|
||||
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mEnchantmentCharge = charge; },
|
||||
},
|
||||
|
@ -138,7 +132,7 @@ namespace MWWorld
|
|||
|
||||
void CellRef::setCharge(int charge)
|
||||
{
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mChargeInt = charge; },
|
||||
},
|
||||
|
@ -164,7 +158,7 @@ namespace MWWorld
|
|||
}
|
||||
};
|
||||
std::visit(
|
||||
RefVisit{
|
||||
ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
esm3Visit,
|
||||
},
|
||||
|
@ -173,7 +167,7 @@ namespace MWWorld
|
|||
|
||||
void CellRef::setChargeFloat(float charge)
|
||||
{
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mChargeFloat = charge; },
|
||||
},
|
||||
|
@ -182,7 +176,7 @@ namespace MWWorld
|
|||
|
||||
const std::string& CellRef::getGlobalVariable() const
|
||||
{
|
||||
return std::visit(RefVisit{
|
||||
return std::visit(ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& /*ref*/) -> const std::string& { return emptyString; },
|
||||
[&](const ESM::CellRef& ref) -> const std::string& { return ref.mGlobalVariable; },
|
||||
},
|
||||
|
@ -194,7 +188,7 @@ namespace MWWorld
|
|||
if (!getGlobalVariable().empty())
|
||||
{
|
||||
mChanged = true;
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mGlobalVariable.erase(); },
|
||||
},
|
||||
|
@ -215,7 +209,7 @@ namespace MWWorld
|
|||
{
|
||||
if (owner != getOwner())
|
||||
{
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mOwner = owner; },
|
||||
},
|
||||
|
@ -228,7 +222,7 @@ namespace MWWorld
|
|||
if (soul != getSoul())
|
||||
{
|
||||
mChanged = true;
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mSoul = soul; },
|
||||
},
|
||||
|
@ -241,7 +235,7 @@ namespace MWWorld
|
|||
if (faction != getFaction())
|
||||
{
|
||||
mChanged = true;
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mFaction = faction; },
|
||||
},
|
||||
|
@ -276,7 +270,7 @@ namespace MWWorld
|
|||
if (trap != getTrap())
|
||||
{
|
||||
mChanged = true;
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mTrap = trap; },
|
||||
},
|
||||
|
@ -289,7 +283,7 @@ namespace MWWorld
|
|||
if (value != getGoldValue())
|
||||
{
|
||||
mChanged = true;
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](ESM4::Reference& /*ref*/) {},
|
||||
[&](ESM::CellRef& ref) { ref.mGoldValue = value; },
|
||||
},
|
||||
|
@ -299,7 +293,7 @@ namespace MWWorld
|
|||
|
||||
void CellRef::writeState(ESM::ObjectState& state) const
|
||||
{
|
||||
std::visit(RefVisit{
|
||||
std::visit(ESM::VisitOverload{
|
||||
[&](const ESM4::Reference& /*ref*/) {},
|
||||
[&](const ESM::CellRef& ref) { state.mRef = ref; },
|
||||
},
|
||||
|
|
|
@ -540,8 +540,7 @@ namespace MWWorld
|
|||
{
|
||||
|
||||
std::apply([this](auto&... x) { (CellStoreImp::assignStoreToIndex(*this, x), ...); }, mCellStoreImp->mRefLists);
|
||||
if (!mCellVariant.isEsm4())
|
||||
mWaterLevel = mCellVariant.getEsm3().mWater;
|
||||
mWaterLevel = mCellVariant.getWaterHeight();
|
||||
}
|
||||
|
||||
CellStore::~CellStore() = default;
|
||||
|
@ -703,26 +702,20 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
void CellStore::listRefs()
|
||||
void CellStore::listRefs(const ESM::Cell& cell)
|
||||
{
|
||||
|
||||
if (mCellVariant.isEsm4())
|
||||
return;
|
||||
|
||||
const ESM::Cell& cell3 = mCellVariant.getEsm3();
|
||||
|
||||
if (cell3.mContextList.empty())
|
||||
if (cell.mContextList.empty())
|
||||
return; // this is a dynamically generated cell -> skipping.
|
||||
|
||||
// Load references from all plugins that do something with this cell.
|
||||
for (size_t i = 0; i < cell3.mContextList.size(); i++)
|
||||
for (size_t i = 0; i < cell.mContextList.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Reopen the ESM reader and seek to the right position.
|
||||
const std::size_t index = static_cast<std::size_t>(cell3.mContextList[i].index);
|
||||
const std::size_t index = static_cast<std::size_t>(cell.mContextList[i].index);
|
||||
const ESM::ReadersCache::BusyItem reader = mReaders.get(index);
|
||||
cell3.restore(*reader, i);
|
||||
cell.restore(*reader, i);
|
||||
|
||||
ESM::CellRef ref;
|
||||
|
||||
|
@ -738,8 +731,8 @@ namespace MWWorld
|
|||
|
||||
// Don't list reference if it was moved to a different cell.
|
||||
ESM::MovedCellRefTracker::const_iterator iter
|
||||
= std::find(cell3.mMovedRefs.begin(), cell3.mMovedRefs.end(), ref.mRefNum);
|
||||
if (iter != cell3.mMovedRefs.end())
|
||||
= std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum);
|
||||
if (iter != cell.mMovedRefs.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -755,12 +748,29 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
// List moved references, from separately tracked list.
|
||||
for (const auto& [ref, deleted] : cell3.mLeasedRefs)
|
||||
for (const auto& [ref, deleted] : cell.mLeasedRefs)
|
||||
{
|
||||
if (!deleted)
|
||||
mIds.push_back(ref.mRefID);
|
||||
}
|
||||
}
|
||||
|
||||
void CellStore::listRefs(const ESM4::Cell& cell)
|
||||
{
|
||||
auto& refs = MWBase::Environment::get().getWorld()->getStore().get<ESM4::Reference>();
|
||||
|
||||
for (const auto& ref : refs)
|
||||
{
|
||||
if (ref.mParent == cell.mId)
|
||||
{
|
||||
mIds.push_back(ref.mBaseObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellStore::listRefs()
|
||||
{
|
||||
ESM::visit([&](auto&& cell) { listRefs(cell); }, mCellVariant);
|
||||
std::sort(mIds.begin(), mIds.end());
|
||||
}
|
||||
|
||||
|
@ -834,7 +844,7 @@ namespace MWWorld
|
|||
{
|
||||
std::map<ESM::RefNum, ESM::RefId> refNumToID; // used to detect refID modifications
|
||||
|
||||
ESM::visit([&refNumToID, this](auto&& cell) { this->loadRefs(cell, refNumToID); }, mCellVariant);
|
||||
ESM::visit([&](auto&& cell) { loadRefs(cell, refNumToID); }, mCellVariant);
|
||||
|
||||
updateMergedRefs();
|
||||
}
|
||||
|
@ -930,9 +940,6 @@ namespace MWWorld
|
|||
|
||||
void CellStore::loadState(const ESM::CellState& state)
|
||||
{
|
||||
if (mCellVariant.isEsm4())
|
||||
return;
|
||||
|
||||
mHasState = true;
|
||||
|
||||
if (!mCellVariant.isExterior() && mCellVariant.hasWater())
|
||||
|
|
|
@ -383,6 +383,8 @@ namespace MWWorld
|
|||
|
||||
private:
|
||||
/// Run through references and store IDs
|
||||
void listRefs(const ESM::Cell& cell);
|
||||
void listRefs(const ESM4::Cell& cell);
|
||||
void listRefs();
|
||||
|
||||
void loadRefs(const ESM::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID);
|
||||
|
|
|
@ -354,11 +354,14 @@ namespace MWWorld
|
|||
if (cell->getCell()->hasWater())
|
||||
mNavigator.removeWater(osg::Vec2i(cellX, cellY), navigatorUpdateGuard);
|
||||
|
||||
if (!cell->getCell()->isEsm4())
|
||||
{
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell->getCell()->getEsm3()))
|
||||
mNavigator.removePathgrid(*pathgrid);
|
||||
}
|
||||
ESM::visit(ESM::VisitOverload{
|
||||
[&](const ESM::Cell& cell) {
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell))
|
||||
mNavigator.removePathgrid(*pathgrid);
|
||||
},
|
||||
[&](const ESM4::Cell& cell) {},
|
||||
},
|
||||
*cell->getCell());
|
||||
|
||||
MWBase::Environment::get().getMechanicsManager()->drop(cell);
|
||||
|
||||
|
@ -430,12 +433,14 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
if (!cellVariant.isEsm4())
|
||||
{
|
||||
const ESM::Cell& cell3 = cellVariant.getEsm3();
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell3))
|
||||
mNavigator.addPathgrid(cell3, *pathgrid);
|
||||
}
|
||||
ESM::visit(ESM::VisitOverload{
|
||||
[&](const ESM::Cell& cell) {
|
||||
if (const auto pathgrid = mWorld.getStore().get<ESM::Pathgrid>().search(cell))
|
||||
mNavigator.addPathgrid(cell, *pathgrid);
|
||||
},
|
||||
[&](const ESM4::Cell& cell) {},
|
||||
},
|
||||
*cell->getCell());
|
||||
|
||||
// register local scripts
|
||||
// do this before insertCell, to make sure we don't add scripts from levelled creature spawning twice
|
||||
|
@ -449,7 +454,7 @@ namespace MWWorld
|
|||
mRendering.addCell(cell);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->addCell(cell);
|
||||
bool waterEnabled = (!cellVariant.isEsm4()) && (cellVariant.hasWater() || cell->isExterior());
|
||||
bool waterEnabled = cellVariant.hasWater() || cell->isExterior();
|
||||
float waterLevel = cell->getWaterLevel();
|
||||
mRendering.setWaterEnabled(waterEnabled);
|
||||
if (waterEnabled)
|
||||
|
@ -457,7 +462,7 @@ namespace MWWorld
|
|||
mPhysics->enableWater(waterLevel);
|
||||
mRendering.setWaterHeight(waterLevel);
|
||||
|
||||
if (cellVariant.getEsm3().isExterior())
|
||||
if (cellVariant.isExterior())
|
||||
{
|
||||
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
||||
mNavigator.addWater(
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include <apps/openmw/mwworld/cell.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
// TODO: Switch to C++23 to get a working version of std::unordered_map::erase
|
||||
|
@ -961,6 +963,14 @@ namespace MWWorld
|
|||
else
|
||||
return search(ESM::RefId::stringRefId(cell.mName));
|
||||
}
|
||||
const ESM::Pathgrid* Store<ESM::Pathgrid>::search(const MWWorld::Cell& cellVariant) const
|
||||
{
|
||||
return ESM::visit(ESM::VisitOverload{
|
||||
[&](const ESM::Cell& cell) { return search(cell); },
|
||||
[&](const ESM4::Cell& cell) -> const ESM::Pathgrid* { return nullptr; },
|
||||
},
|
||||
cellVariant);
|
||||
}
|
||||
const ESM::Pathgrid* Store<ESM::Pathgrid>::find(const ESM::Cell& cell) const
|
||||
{
|
||||
if (!(cell.mData.mFlags & ESM::Cell::Interior))
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace Loading
|
|||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Cell;
|
||||
struct RecordId
|
||||
{
|
||||
ESM::RefId mId;
|
||||
|
@ -430,6 +431,7 @@ namespace MWWorld
|
|||
const ESM::Pathgrid* find(int x, int y) const;
|
||||
const ESM::Pathgrid* find(const ESM::RefId& name) const;
|
||||
const ESM::Pathgrid* search(const ESM::Cell& cell) const;
|
||||
const ESM::Pathgrid* search(const MWWorld::Cell& cell) const;
|
||||
const ESM::Pathgrid* find(const ESM::Cell& cell) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -642,11 +642,13 @@ namespace MWWorld
|
|||
if (!cell.isExterior() || !cell.getNameId().empty())
|
||||
return cell.getNameId();
|
||||
|
||||
if (!cell.isEsm4())
|
||||
{
|
||||
return getCellName(&cell.getEsm3());
|
||||
}
|
||||
return mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
|
||||
return ESM::visit(ESM::VisitOverload{
|
||||
[&](const ESM::Cell& cellIn) -> std::string_view { return getCellName(&cellIn); },
|
||||
[&](const ESM4::Cell& cellIn) -> std::string_view {
|
||||
return mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
|
||||
},
|
||||
},
|
||||
cell);
|
||||
}
|
||||
|
||||
std::string_view World::getCellName(const ESM::Cell* cell) const
|
||||
|
|
|
@ -70,5 +70,14 @@ namespace ESM
|
|||
{
|
||||
return std::visit([&](auto*... ptr) { return std::forward<F>(f)(*ptr...); }, std::forward<T>(v).mVariant...);
|
||||
}
|
||||
|
||||
template <class... Ts>
|
||||
struct VisitOverload : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template <class... Ts>
|
||||
VisitOverload(Ts...) -> VisitOverload<Ts...>;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue