mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-22 11:23:27 -04:00
Draw and recycle door markers consistently
This commit is contained in:
parent
082b9a5461
commit
6e45e562a8
@ -319,11 +319,12 @@ namespace MWGui
|
|||||||
mLocalMap->setViewOffset(viewOffset);
|
mLocalMap->setViewOffset(viewOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const
|
void LocalMapBase::updateMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const
|
||||||
{
|
{
|
||||||
MarkerUserData& markerPos(*widget->getUserData<MarkerUserData>());
|
MarkerUserData& markerPos(*widget->getUserData<MarkerUserData>());
|
||||||
auto position = getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY);
|
auto position = getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY);
|
||||||
return MyGUI::IntCoord(position.left - markerSize / 2, position.top - markerSize / 2, markerSize, markerSize);
|
MyGUI::IntCoord coord(position.left - markerSize / 2, position.top - markerSize / 2, markerSize, markerSize);
|
||||||
|
widget->setCoord(coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MarkerWidget*>& LocalMapBase::currentDoorMarkersWidgets()
|
std::vector<MarkerWidget*>& LocalMapBase::currentDoorMarkersWidgets()
|
||||||
@ -379,6 +380,13 @@ namespace MWGui
|
|||||||
if (&cell == mActiveCell)
|
if (&cell == mActiveCell)
|
||||||
return; // don't do anything if we're still in the same cell
|
return; // don't do anything if we're still in the same cell
|
||||||
|
|
||||||
|
// Remove all interior door markers
|
||||||
|
mDoorMarkersToRecycle.insert(
|
||||||
|
mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
|
||||||
|
for (MarkerWidget* widget : mInteriorDoorMarkerWidgets)
|
||||||
|
widget->setVisible(false);
|
||||||
|
mInteriorDoorMarkerWidgets.clear();
|
||||||
|
|
||||||
const int x = cell.getGridX();
|
const int x = cell.getGridX();
|
||||||
const int y = cell.getGridY();
|
const int y = cell.getGridY();
|
||||||
|
|
||||||
@ -386,26 +394,47 @@ namespace MWGui
|
|||||||
|
|
||||||
if (cell.isExterior())
|
if (cell.isExterior())
|
||||||
{
|
{
|
||||||
|
std::optional<MyGUI::IntRect> previousActiveGrid;
|
||||||
|
if (mActiveCell && mActiveCell->isExterior())
|
||||||
|
previousActiveGrid
|
||||||
|
= createRect({ mActiveCell->getGridX(), mActiveCell->getGridY() }, Constants::CellGridRadius);
|
||||||
mGrid = createRect({ x, y }, mExtCellDistance);
|
mGrid = createRect({ x, y }, mExtCellDistance);
|
||||||
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
|
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
|
||||||
|
|
||||||
mExteriorDoorMarkerWidgets.clear();
|
mExteriorDoorMarkerWidgets.clear();
|
||||||
for (auto& [coord, doors] : mExteriorDoorsByCell)
|
for (auto it = mExteriorDoorsByCell.begin(); it != mExteriorDoorsByCell.end();)
|
||||||
{
|
{
|
||||||
if (!mGrid.inside({ coord.first, coord.second }) || activeGrid.inside({ coord.first, coord.second }))
|
const auto& [coord, doors] = *it;
|
||||||
|
const MyGUI::IntPoint pos(coord.first, coord.second);
|
||||||
|
// Remove markers that fall outside the rendered map and ones that are new to the active grid.
|
||||||
|
// Scripts can enable/disable doors, requiring us to update the markers. Morrowind.exe only updates
|
||||||
|
// markers when a cell is added to the active grid.
|
||||||
|
if (!mGrid.inside(pos)
|
||||||
|
|| (previousActiveGrid && !previousActiveGrid->inside(pos) && activeGrid.inside(pos)))
|
||||||
{
|
{
|
||||||
mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), doors.begin(), doors.end());
|
mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), doors.begin(), doors.end());
|
||||||
doors.clear();
|
for (MarkerWidget* widget : doors)
|
||||||
|
widget->setVisible(false);
|
||||||
|
it = mExteriorDoorsByCell.erase(it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mExteriorDoorMarkerWidgets.insert(mExteriorDoorMarkerWidgets.end(), doors.begin(), doors.end());
|
mExteriorDoorMarkerWidgets.insert(mExteriorDoorMarkerWidgets.end(), doors.begin(), doors.end());
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& widget : mDoorMarkersToRecycle)
|
|
||||||
widget->setVisible(false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mGrid = mLocalMapRender->getInteriorGrid();
|
mGrid = mLocalMapRender->getInteriorGrid();
|
||||||
|
// Remove all exterior door markers
|
||||||
|
mDoorMarkersToRecycle.insert(
|
||||||
|
mDoorMarkersToRecycle.end(), mExteriorDoorMarkerWidgets.begin(), mExteriorDoorMarkerWidgets.end());
|
||||||
|
for (MarkerWidget* widget : mExteriorDoorMarkerWidgets)
|
||||||
|
widget->setVisible(false);
|
||||||
|
mExteriorDoorMarkerWidgets.clear();
|
||||||
|
mExteriorDoorsByCell.clear();
|
||||||
|
}
|
||||||
|
|
||||||
mActiveCell = &cell;
|
mActiveCell = &cell;
|
||||||
|
|
||||||
@ -449,7 +478,7 @@ namespace MWGui
|
|||||||
mNeedDoorMarkersUpdate = true;
|
mNeedDoorMarkersUpdate = true;
|
||||||
|
|
||||||
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
updateMarkerCoordinates(widget, 8);
|
||||||
|
|
||||||
updateMagicMarkers();
|
updateMagicMarkers();
|
||||||
updateCustomMarkers();
|
updateCustomMarkers();
|
||||||
@ -609,6 +638,9 @@ namespace MWGui
|
|||||||
entry.mFogTexture = std::make_unique<MyGUIPlatform::OSGTexture>(std::string(), nullptr);
|
entry.mFogTexture = std::make_unique<MyGUIPlatform::OSGTexture>(std::string(), nullptr);
|
||||||
}
|
}
|
||||||
needRedraw = true;
|
needRedraw = true;
|
||||||
|
// Newly uncovered chunk, make sure to draw door markers right away instead of waiting for a cell
|
||||||
|
// transition
|
||||||
|
mNeedDoorMarkersUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needRedraw)
|
if (needRedraw)
|
||||||
@ -621,16 +653,8 @@ namespace MWGui
|
|||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
MWWorld::WorldModel* worldModel = MWBase::Environment::get().getWorldModel();
|
MWWorld::WorldModel* worldModel = MWBase::Environment::get().getWorldModel();
|
||||||
|
|
||||||
const bool recycledMarkers = !mInteriorDoorMarkerWidgets.empty();
|
|
||||||
mDoorMarkersToRecycle.insert(
|
|
||||||
mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
|
|
||||||
mInteriorDoorMarkerWidgets.clear();
|
|
||||||
|
|
||||||
if (!mActiveCell->isExterior())
|
if (!mActiveCell->isExterior())
|
||||||
{
|
{
|
||||||
for (MarkerWidget* widget : mExteriorDoorMarkerWidgets)
|
|
||||||
widget->setVisible(false);
|
|
||||||
|
|
||||||
MWWorld::CellStore& cell = worldModel->getInterior(mActiveCell->getNameId());
|
MWWorld::CellStore& cell = worldModel->getInterior(mActiveCell->getNameId());
|
||||||
world->getDoorMarkers(cell, doors);
|
world->getDoorMarkers(cell, doors);
|
||||||
}
|
}
|
||||||
@ -638,13 +662,13 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
for (MapEntry& entry : mMaps)
|
for (MapEntry& entry : mMaps)
|
||||||
{
|
{
|
||||||
if (!entry.mMapTexture && entry.mMapWidget->getVisible() && !widgetCropped(entry.mMapWidget, mLocalMap))
|
if (!entry.mMapWidget->getVisible() || widgetCropped(entry.mMapWidget, mLocalMap))
|
||||||
world->getDoorMarkers(worldModel->getExterior(ESM::ExteriorCellLocation(
|
continue;
|
||||||
entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)),
|
if (mExteriorDoorsByCell.contains({ entry.mCellX, entry.mCellY }))
|
||||||
doors);
|
continue;
|
||||||
|
ESM::ExteriorCellLocation id(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId);
|
||||||
|
world->getDoorMarkers(worldModel->getExterior(id), doors);
|
||||||
}
|
}
|
||||||
if (doors.empty() && !recycledMarkers)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a widget for each marker
|
// Create a widget for each marker
|
||||||
@ -652,8 +676,7 @@ namespace MWGui
|
|||||||
{
|
{
|
||||||
std::vector<std::string> destNotes;
|
std::vector<std::string> destNotes;
|
||||||
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest);
|
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest);
|
||||||
for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second;
|
for (auto iter = markers.first; iter != markers.second; ++iter)
|
||||||
++iter)
|
|
||||||
destNotes.push_back(iter->second.mNote);
|
destNotes.push_back(iter->second.mNote);
|
||||||
|
|
||||||
MarkerWidget* markerWidget = nullptr;
|
MarkerWidget* markerWidget = nullptr;
|
||||||
@ -682,8 +705,8 @@ namespace MWGui
|
|||||||
mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget);
|
mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& widget : mDoorMarkersToRecycle)
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setVisible(false);
|
updateMarkerCoordinates(widget, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::updateMagicMarkers()
|
void LocalMapBase::updateMagicMarkers()
|
||||||
@ -732,7 +755,7 @@ namespace MWGui
|
|||||||
|
|
||||||
MarkerUserData markerPos(mLocalMapRender);
|
MarkerUserData markerPos(mLocalMapRender);
|
||||||
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
updateMarkerCoordinates(widget, 8);
|
||||||
|
|
||||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||||
{
|
{
|
||||||
@ -741,7 +764,7 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (MyGUI::Widget* widget : mMagicMarkerWidgets)
|
for (MyGUI::Widget* widget : mMagicMarkerWidgets)
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
updateMarkerCoordinates(widget, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
|
@ -165,11 +165,10 @@ namespace MWGui
|
|||||||
MyGUI::IntCoord getMarkerCoordinates(
|
MyGUI::IntCoord getMarkerCoordinates(
|
||||||
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const;
|
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const;
|
||||||
MarkerWidget* createDoorMarker(const std::string& name, float x, float y) const;
|
MarkerWidget* createDoorMarker(const std::string& name, float x, float y) const;
|
||||||
MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const;
|
void updateMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const;
|
||||||
|
|
||||||
virtual void notifyPlayerUpdate() {}
|
virtual void notifyPlayerUpdate() {}
|
||||||
virtual void centerView();
|
virtual void centerView();
|
||||||
virtual void notifyMapChanged() {}
|
|
||||||
|
|
||||||
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
||||||
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user