mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
Merge branch 'mapped' into 'master'
Track map position using MWWorld::Cell See merge request OpenMW/openmw!3932
This commit is contained in:
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…
x
Reference in New Issue
Block a user