Skip to content

Commit a6097d0

Browse files
committed
Merge branch 'exteriorcoc' into 'master'
Improve COC exterior destination choice consistency See merge request OpenMW/openmw!5026
2 parents b917b14 + 9cecc92 commit a6097d0

File tree

3 files changed

+29
-86
lines changed

3 files changed

+29
-86
lines changed

apps/openmw/mwworld/store.cpp

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -639,20 +639,9 @@ namespace MWWorld
639639
for (const auto& [_, cell] : mDynamicInt)
640640
mCells.erase(cell->mId);
641641
mDynamicInt.clear();
642-
setUp();
643-
}
644-
645-
void Store<ESM::Cell>::setUp()
646-
{
647-
mSharedInt.clear();
648-
mSharedInt.reserve(mInt.size());
649-
for (auto& [_, cell] : mInt)
650-
mSharedInt.push_back(cell);
651642

652-
mSharedExt.clear();
653-
mSharedExt.reserve(mExt.size());
654-
for (auto& [_, cell] : mExt)
655-
mSharedExt.push_back(cell);
643+
mSharedInt.erase(mSharedInt.begin() + mInt.size(), mSharedInt.end());
644+
mSharedExt.erase(mSharedExt.begin() + mExt.size(), mSharedExt.end());
656645
}
657646
RecordId Store<ESM::Cell>::load(ESM::ESMReader& esm)
658647
{
@@ -685,7 +674,10 @@ namespace MWWorld
685674
{
686675
cell.loadCell(esm, true);
687676
if (newCell)
677+
{
688678
mInt[cell.mName] = &cell;
679+
mSharedInt.push_back(&cell);
680+
}
689681
}
690682
else
691683
{
@@ -698,7 +690,10 @@ namespace MWWorld
698690
// push the new references on the list of references to manage
699691
cell.postLoad(esm);
700692
if (newCell)
693+
{
701694
mExt[std::make_pair(cell.mData.mX, cell.mData.mY)] = &cell;
695+
mSharedExt.push_back(&cell);
696+
}
702697
else
703698
{
704699
// merge lists of leased references, use newer data in case of conflict
@@ -749,38 +744,6 @@ namespace MWWorld
749744
{
750745
return iterator(mSharedExt.end());
751746
}
752-
const ESM::Cell* Store<ESM::Cell>::searchExtByName(std::string_view name) const
753-
{
754-
const ESM::Cell* cell = nullptr;
755-
for (const ESM::Cell* sharedCell : mSharedExt)
756-
{
757-
if (Misc::StringUtils::ciEqual(sharedCell->mName, name))
758-
{
759-
if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX)
760-
|| (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY))
761-
{
762-
cell = sharedCell;
763-
}
764-
}
765-
}
766-
return cell;
767-
}
768-
const ESM::Cell* Store<ESM::Cell>::searchExtByRegion(const ESM::RefId& id) const
769-
{
770-
const ESM::Cell* cell = nullptr;
771-
for (const ESM::Cell* sharedCell : mSharedExt)
772-
{
773-
if (sharedCell->mRegion == id)
774-
{
775-
if (cell == nullptr || (sharedCell->mData.mX > cell->mData.mX)
776-
|| (sharedCell->mData.mX == cell->mData.mX && sharedCell->mData.mY > cell->mData.mY))
777-
{
778-
cell = sharedCell;
779-
}
780-
}
781-
}
782-
return cell;
783-
}
784747
size_t Store<ESM::Cell>::getSize() const
785748
{
786749
return mSharedInt.size() + mSharedExt.size();

apps/openmw/mwworld/store.hpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -360,27 +360,10 @@ namespace MWWorld
360360
template <>
361361
class Store<ESM::Cell> : public DynamicStore
362362
{
363-
struct DynamicExtCmp
364-
{
365-
bool operator()(const std::pair<int, int>& left, const std::pair<int, int>& right) const
366-
{
367-
if (left.first == right.first && left.second == right.second)
368-
return false;
369-
370-
if (left.first == right.first)
371-
return left.second > right.second;
372-
373-
// Exterior cells are listed in descending, row-major order,
374-
// this is a workaround for an ambiguous chargen_plank reference in the vanilla game.
375-
// there is one at -22,16 and one at -2,-9, the latter should be used.
376-
return left.first > right.first;
377-
}
378-
};
379-
380363
typedef std::unordered_map<std::string, ESM::Cell*, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual>
381364
DynamicInt;
382365

383-
typedef std::map<std::pair<int, int>, ESM::Cell*, DynamicExtCmp> DynamicExt;
366+
typedef std::map<std::pair<int, int>, ESM::Cell*> DynamicExt;
384367

385368
std::unordered_map<ESM::RefId, ESM::Cell> mCells;
386369

@@ -410,7 +393,6 @@ namespace MWWorld
410393
const ESM::Cell* find(int x, int y) const;
411394

412395
void clearDynamic() override;
413-
void setUp() override;
414396

415397
RecordId load(ESM::ESMReader& esm) override;
416398

@@ -419,12 +401,6 @@ namespace MWWorld
419401
iterator extBegin() const;
420402
iterator extEnd() const;
421403

422-
// Return the northernmost cell in the easternmost column.
423-
const ESM::Cell* searchExtByName(std::string_view id) const;
424-
425-
// Return the northernmost cell in the easternmost column.
426-
const ESM::Cell* searchExtByRegion(const ESM::RefId& id) const;
427-
428404
size_t getSize() const override;
429405
size_t getExtSize() const;
430406
size_t getIntSize() const;

apps/openmw/mwworld/worldmodel.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -298,25 +298,29 @@ namespace MWWorld
298298
return cellStore;
299299

300300
// try named exteriors
301-
const ESM::Cell* cell = mStore.get<ESM::Cell>().searchExtByName(name);
301+
const ESM::Cell* cell = nullptr;
302+
const Store<ESM::Cell>& cells = mStore.get<ESM::Cell>();
303+
const Store<ESM::GameSetting>& gmsts = mStore.get<ESM::GameSetting>();
304+
const Store<ESM::Region>& regions = mStore.get<ESM::Region>();
305+
static const std::string& defaultName = gmsts.find("sDefaultCellname")->mValue.getString();
302306

303-
if (cell == nullptr)
307+
for (auto it = cells.extBegin(); it != cells.extEnd(); ++it)
304308
{
305-
// treat "Wilderness" like an empty string
306-
static const std::string& defaultName
307-
= mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
308-
if (Misc::StringUtils::ciEqual(name, defaultName))
309-
cell = mStore.get<ESM::Cell>().searchExtByName({});
310-
}
309+
std::string_view resolvedName = defaultName;
310+
if (!it->mName.empty())
311+
resolvedName = it->mName;
312+
else if (!it->mRegion.empty())
313+
{
314+
const ESM::Region* region = regions.search(it->mRegion);
315+
if (region != nullptr)
316+
resolvedName = !region->mName.empty() ? region->mName : region->mId.getRefIdString();
317+
}
311318

312-
if (cell == nullptr)
313-
{
314-
// now check for regions
315-
const Store<ESM::Region>& regions = mStore.get<ESM::Region>();
316-
const auto region = std::find_if(regions.begin(), regions.end(),
317-
[&](const ESM::Region& v) { return Misc::StringUtils::ciEqual(name, v.mName); });
318-
if (region != regions.end())
319-
cell = mStore.get<ESM::Cell>().searchExtByRegion(region->mId);
319+
if (Misc::StringUtils::ciEqual(resolvedName, name))
320+
{
321+
cell = &(*it);
322+
break;
323+
}
320324
}
321325

322326
if (cell != nullptr)

0 commit comments

Comments
 (0)