Merge branch 'mapped' into 'master'

Track map position using MWWorld::Cell

See merge request OpenMW/openmw!3932
fix-osga-rotate-wildly
psi29a 10 months ago
commit c3a44ca74a

@ -202,9 +202,6 @@ namespace MWBase
virtual bool getFullHelp() const = 0;
virtual void setActiveMap(int x, int y, bool interior) = 0;
///< set the indices of the map texture that should be used
/// sets the visibility of the drowning bar
virtual void setDrowningBarVisibility(bool visible) = 0;

@ -95,6 +95,13 @@ namespace
return std::clamp(
viewingDistanceInCells, Constants::CellGridRadius, Settings::map().mMaxLocalViewingDistance.get());
}
ESM::RefId getCellIdInWorldSpace(const MWWorld::Cell& cell, int x, int y)
{
if (cell.isExterior())
return ESM::Cell::generateIdForCell(true, {}, x, y);
return cell.getId();
}
}
namespace MWGui
@ -170,12 +177,9 @@ namespace MWGui
LocalMapBase::LocalMapBase(
CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled)
: mLocalMapRender(localMapRender)
, mCurX(0)
, mCurY(0)
, mInterior(false)
, mActiveCell(nullptr)
, mLocalMap(nullptr)
, mCompass(nullptr)
, mChanged(true)
, mFogOfWarToggled(true)
, mFogOfWarEnabled(fogOfWarEnabled)
, mNumCells(1)
@ -231,12 +235,6 @@ namespace MWGui
}
}
void LocalMapBase::setCellPrefix(const std::string& prefix)
{
mPrefix = prefix;
mChanged = true;
}
bool LocalMapBase::toggleFogOfWar()
{
mFogOfWarToggled = !mFogOfWarToggled;
@ -262,8 +260,8 @@ namespace MWGui
{
// normalized cell coordinates
auto mapWidgetSize = getWidgetSize();
return MyGUI::IntPoint(std::round(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize),
std::round(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize));
return MyGUI::IntPoint(std::round((nX + mCellDistance + cellX - mActiveCell->getGridX()) * mapWidgetSize),
std::round((nY + mCellDistance - cellY + mActiveCell->getGridY()) * mapWidgetSize));
}
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const
@ -272,7 +270,7 @@ namespace MWGui
// normalized cell coordinates
float nX, nY;
if (!mInterior)
if (mActiveCell->isExterior())
{
ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(worldX, worldY);
cellIndex.x() = cellPos.mX;
@ -336,7 +334,7 @@ namespace MWGui
std::vector<MyGUI::Widget*>& LocalMapBase::currentDoorMarkersWidgets()
{
return mInterior ? mInteriorDoorMarkerWidgets : mExteriorDoorMarkerWidgets;
return mActiveCell->isExterior() ? mExteriorDoorMarkerWidgets : mInteriorDoorMarkerWidgets;
}
void LocalMapBase::updateCustomMarkers()
@ -344,12 +342,14 @@ namespace MWGui
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
MyGUI::Gui::getInstance().destroyWidget(widget);
mCustomMarkerWidgets.clear();
if (!mActiveCell)
return;
for (int dX = -mCellDistance; dX <= mCellDistance; ++dX)
{
for (int dY = -mCellDistance; dY <= mCellDistance; ++dY)
{
ESM::RefId cellRefId = ESM::Cell::generateIdForCell(!mInterior, mPrefix, mCurX + dX, mCurY + dY);
ESM::RefId cellRefId
= getCellIdInWorldSpace(*mActiveCell, mActiveCell->getGridX() + dX, mActiveCell->getGridY() + dY);
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellRefId);
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second;
@ -377,16 +377,25 @@ namespace MWGui
redraw();
}
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
void LocalMapBase::setActiveCell(const MWWorld::Cell& cell)
{
if (x == mCurX && y == mCurY && mInterior == interior && !mChanged)
if (&cell == mActiveCell)
return; // don't do anything if we're still in the same cell
if (!interior && !(x == mCurX && y == mCurY))
const int x = cell.getGridX();
const int y = cell.getGridY();
if (cell.isExterior())
{
const MyGUI::IntRect intersection
= { std::max(x, mCurX) - mCellDistance, std::max(y, mCurY) - mCellDistance,
std::min(x, mCurX) + mCellDistance, std::min(y, mCurY) + mCellDistance };
int curX = 0;
int curY = 0;
if (mActiveCell)
{
curX = mActiveCell->getGridX();
curY = mActiveCell->getGridY();
}
const MyGUI::IntRect intersection = { std::max(x, curX) - mCellDistance, std::max(y, curY) - mCellDistance,
std::min(x, curX) + mCellDistance, std::min(y, curY) + mCellDistance };
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
const MyGUI::IntRect currentView = createRect({ x, y }, mCellDistance);
@ -407,17 +416,14 @@ namespace MWGui
for (auto& widget : mDoorMarkersToRecycle)
widget->setVisible(false);
for (auto const& cell : mMaps)
for (auto const& entry : mMaps)
{
if (mHasALastActiveCell && !intersection.inside({ cell.mCellX, cell.mCellY }))
mLocalMapRender->removeExteriorCell(cell.mCellX, cell.mCellY);
if (mHasALastActiveCell && !intersection.inside({ entry.mCellX, entry.mCellY }))
mLocalMapRender->removeExteriorCell(entry.mCellX, entry.mCellY);
}
}
mCurX = x;
mCurY = y;
mInterior = interior;
mChanged = false;
mActiveCell = &cell;
for (int mx = 0; mx < mNumCells; ++mx)
{
@ -441,7 +447,7 @@ namespace MWGui
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
widget->setCoord(getMarkerCoordinates(widget, 8));
if (!mInterior)
if (mActiveCell->isExterior())
mHasALastActiveCell = true;
updateMagicMarkers();
@ -580,7 +586,7 @@ namespace MWGui
if (!entry.mMapTexture)
{
if (!mInterior)
if (mActiveCell->isExterior())
requestMapRender(&MWBase::Environment::get().getWorldModel()->getExterior(
ESM::ExteriorCellLocation(entry.mCellX, entry.mCellY, ESM::Cell::sDefaultWorldspaceId)));
@ -626,12 +632,12 @@ namespace MWGui
mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
mInteriorDoorMarkerWidgets.clear();
if (mInterior)
if (!mActiveCell->isExterior())
{
for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets)
widget->setVisible(false);
MWWorld::CellStore& cell = worldModel->getInterior(mPrefix);
MWWorld::CellStore& cell = worldModel->getInterior(mActiveCell->getNameId());
world->getDoorMarkers(cell, doors);
}
else
@ -678,7 +684,7 @@ namespace MWGui
}
currentDoorMarkersWidgets().push_back(markerWidget);
if (!mInterior)
if (mActiveCell->isExterior())
mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget);
}
@ -701,8 +707,7 @@ namespace MWGui
MWWorld::CellStore* markedCell = nullptr;
ESM::Position markedPosition;
MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition);
if (markedCell && markedCell->isExterior() == !mInterior
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->getNameId(), mPrefix)))
if (markedCell && markedCell->getCell()->getWorldSpace() == mActiveCell->getWorldSpace())
{
MarkerUserData markerPos(mLocalMapRender);
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
@ -870,11 +875,11 @@ namespace MWGui
int y = (int(widgetPos.top / float(mapWidgetSize)) - mCellDistance) * -1;
float nX = widgetPos.left / float(mapWidgetSize) - int(widgetPos.left / float(mapWidgetSize));
float nY = widgetPos.top / float(mapWidgetSize) - int(widgetPos.top / float(mapWidgetSize));
x += mCurX;
y += mCurY;
x += mActiveCell->getGridX();
y += mActiveCell->getGridY();
osg::Vec2f worldPos;
if (mInterior)
if (!mActiveCell->isExterior())
{
worldPos = mLocalMapRender->interiorMapToWorldPosition(nX, nY, x, y);
}
@ -886,7 +891,7 @@ namespace MWGui
mEditingMarker.mWorldX = worldPos.x();
mEditingMarker.mWorldY = worldPos.y();
ESM::RefId clickedId = ESM::Cell::generateIdForCell(!mInterior, LocalMapBase::mPrefix, x, y);
ESM::RefId clickedId = getCellIdInWorldSpace(*mActiveCell, x, y);
mEditingMarker.mCell = clickedId;
@ -977,7 +982,7 @@ namespace MWGui
resizeGlobalMap();
float x = mCurPos.x(), y = mCurPos.y();
if (mInterior)
if (!mActiveCell->isExterior())
{
auto pos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
x = pos.x();
@ -1020,7 +1025,7 @@ namespace MWGui
resizeGlobalMap();
}
MapWindow::~MapWindow() {}
MapWindow::~MapWindow() = default;
void MapWindow::setCellName(const std::string& cellName)
{
@ -1289,7 +1294,7 @@ namespace MWGui
mMarkers.clear();
mGlobalMapRender->clear();
mChanged = true;
mActiveCell = nullptr;
for (auto& widgetPair : mGlobalMapMarkers)
MyGUI::Gui::getInstance().destroyWidget(widgetPair.first.widget);

@ -27,6 +27,7 @@ namespace ESM
namespace MWWorld
{
class Cell;
class CellStore;
}
@ -77,8 +78,7 @@ namespace MWGui
virtual ~LocalMapBase();
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius);
void setCellPrefix(const std::string& prefix);
void setActiveCell(const int x, const int y, bool interior = false);
void setActiveCell(const MWWorld::Cell& cell);
void requestMapRender(const MWWorld::CellStore* cell);
void setPlayerDir(const float x, const float y);
void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
@ -115,15 +115,12 @@ namespace MWGui
float mLocalMapZoom = 1.f;
MWRender::LocalMap* mLocalMapRender;
int mCurX, mCurY; // the position of the active cell on the global map (in cell coords)
const MWWorld::Cell* mActiveCell;
bool mHasALastActiveCell = false;
osg::Vec2f mCurPos; // the position of the player in the world (in cell coords)
bool mInterior;
MyGUI::ScrollView* mLocalMap;
MyGUI::ImageBox* mCompass;
std::string mPrefix;
bool mChanged;
bool mFogOfWarToggled;
bool mFogOfWarEnabled;

@ -844,7 +844,7 @@ namespace MWGui
if (!player.getCell()->isExterior())
{
setActiveMap(x, y, true);
setActiveMap(*player.getCell()->getCell());
}
// else: need to know the current grid center, call setActiveMap from changeCell
@ -982,29 +982,23 @@ namespace MWGui
mMap->addVisitedLocation(name, cellCommon->getGridX(), cellCommon->getGridY());
mMap->cellExplored(cellCommon->getGridX(), cellCommon->getGridY());
setActiveMap(cellCommon->getGridX(), cellCommon->getGridY(), false);
}
else
{
mMap->setCellPrefix(std::string(cellCommon->getNameId()));
mHud->setCellPrefix(std::string(cellCommon->getNameId()));
osg::Vec3f worldPos;
if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos))
worldPos = MWBase::Environment::get().getWorld()->getPlayer().getLastKnownExteriorPosition();
else
MWBase::Environment::get().getWorld()->getPlayer().setLastKnownExteriorPosition(worldPos);
mMap->setGlobalMapPlayerPosition(worldPos.x(), worldPos.y());
setActiveMap(0, 0, true);
}
setActiveMap(*cellCommon);
}
void WindowManager::setActiveMap(int x, int y, bool interior)
void WindowManager::setActiveMap(const MWWorld::Cell& cell)
{
mMap->setActiveCell(x, y, interior);
mHud->setActiveCell(x, y, interior);
mMap->setActiveCell(cell);
mHud->setActiveCell(cell);
}
void WindowManager::setDrowningBarVisibility(bool visible)

@ -50,6 +50,7 @@ namespace MyGUI
namespace MWWorld
{
class Cell;
class ESMStore;
}
@ -216,9 +217,6 @@ namespace MWGui
bool toggleFullHelp() override; ///< show extra info in item tooltips (owner, script)
bool getFullHelp() const override;
void setActiveMap(int x, int y, bool interior) override;
///< set the indices of the map texture that should be used
/// sets the visibility of the drowning bar
void setDrowningBarVisibility(bool visible) override;
@ -589,6 +587,9 @@ namespace MWGui
void setCullMask(uint32_t mask) override;
uint32_t getCullMask() override;
void setActiveMap(const MWWorld::Cell& cell);
///< set the indices of the map texture that should be used
Files::ConfigurationManager& mCfgMgr;
};
}

@ -100,6 +100,8 @@ namespace MWWorld
mWaterHeight = -1.f;
mHasWater = true;
}
else
mGridPos = {};
}
ESM::RefId Cell::getWorldSpace() const

Loading…
Cancel
Save