mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 20:23:54 +00:00
[Local map] Use the distance view in the local map
This commit is contained in:
parent
ed04ebe9ff
commit
8c87defddf
6 changed files with 156 additions and 76 deletions
|
@ -85,6 +85,23 @@ namespace
|
||||||
setColour(mHoverColour);
|
setColour(mHoverColour);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MyGUI::IntRect createRect(const MyGUI::IntPoint& center, int radius)
|
||||||
|
{
|
||||||
|
return { center.left - radius, center.top + radius, center.left + radius, center.top - radius };
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLocalViewingDistance()
|
||||||
|
{
|
||||||
|
if (!Settings::Manager::getBool("allow zooming", "Map"))
|
||||||
|
return Constants::CellGridRadius;
|
||||||
|
if (!Settings::Manager::getBool("distant terrain", "Terrain"))
|
||||||
|
return Constants::CellGridRadius;
|
||||||
|
const float localViewingDistanceCoef = Settings::Manager::getFloat("local viewing distance coef", "Map");
|
||||||
|
const int viewingDistance = Settings::Manager::getInt("viewing distance", "Camera");
|
||||||
|
const int localViewingDistanceInCells = (viewingDistance * localViewingDistanceCoef) / double(Constants::CellSizeInUnits);
|
||||||
|
return std::max(Constants::CellGridRadius, localViewingDistanceInCells);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
@ -174,7 +191,6 @@ namespace MWGui
|
||||||
, mMarkerUpdateTimer(0.0f)
|
, mMarkerUpdateTimer(0.0f)
|
||||||
, mLastDirectionX(0.0f)
|
, mLastDirectionX(0.0f)
|
||||||
, mLastDirectionY(0.0f)
|
, mLastDirectionY(0.0f)
|
||||||
, mNeedDoorMarkersUpdate(false)
|
|
||||||
{
|
{
|
||||||
mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
|
mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
|
||||||
}
|
}
|
||||||
|
@ -184,12 +200,12 @@ namespace MWGui
|
||||||
mCustomMarkers.eventMarkersChanged -= MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
|
mCustomMarkers.eventMarkersChanged -= MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass)
|
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance)
|
||||||
{
|
{
|
||||||
mLocalMap = widget;
|
mLocalMap = widget;
|
||||||
mCompass = compass;
|
mCompass = compass;
|
||||||
mMapWidgetSize = std::max(1, Settings::Manager::getInt("local map widget size", "Map"));
|
mMapWidgetSize = std::max(1, Settings::Manager::getInt("local map widget size", "Map"));
|
||||||
mCellDistance = Constants::CellGridRadius;
|
mCellDistance = cellDistance;
|
||||||
mNumCells = mCellDistance * 2 + 1;
|
mNumCells = mCellDistance * 2 + 1;
|
||||||
|
|
||||||
mLocalMap->setCanvasSize(mMapWidgetSize*mNumCells, mMapWidgetSize*mNumCells);
|
mLocalMap->setCanvasSize(mMapWidgetSize*mNumCells, mMapWidgetSize*mNumCells);
|
||||||
|
@ -320,6 +336,11 @@ namespace MWGui
|
||||||
return MyGUI::IntCoord(position.left - markerSize / 2, position.top - markerSize / 2, markerSize, markerSize);
|
return MyGUI::IntCoord(position.left - markerSize / 2, position.top - markerSize / 2, markerSize, markerSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<MyGUI::Widget*>& LocalMapBase::currentDoorMarkersWidgets()
|
||||||
|
{
|
||||||
|
return mInterior ? mInteriorDoorMarkerWidgets : mExteriorDoorMarkerWidgets;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMapBase::updateCustomMarkers()
|
void LocalMapBase::updateCustomMarkers()
|
||||||
{
|
{
|
||||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||||
|
@ -366,6 +387,38 @@ namespace MWGui
|
||||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged)
|
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged)
|
||||||
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
|
||||||
|
|
||||||
|
if (!interior && !(x == mCurX && y == mCurY))
|
||||||
|
{
|
||||||
|
const MyGUI::IntRect intersection = {
|
||||||
|
std::max(x, mCurX) - mCellDistance, std::max(y, mCurY) - mCellDistance,
|
||||||
|
std::min(x, mCurX) + mCellDistance, std::min(y, mCurY) + mCellDistance
|
||||||
|
};
|
||||||
|
|
||||||
|
const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius);
|
||||||
|
const MyGUI::IntRect currentView = createRect({ x, y }, mCellDistance);
|
||||||
|
|
||||||
|
mExteriorDoorMarkerWidgets.clear();
|
||||||
|
for (auto& [coord, doors] : mExteriorDoorsByCell)
|
||||||
|
{
|
||||||
|
if (!mHasALastActiveCell || !currentView.inside({ coord.first, coord.second }) || activeGrid.inside({ coord.first, coord.second }))
|
||||||
|
{
|
||||||
|
mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), doors.begin(), doors.end());
|
||||||
|
doors.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mExteriorDoorMarkerWidgets.insert(mExteriorDoorMarkerWidgets.end(), doors.begin(), doors.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& widget : mDoorMarkersToRecycle)
|
||||||
|
widget->setVisible(false);
|
||||||
|
|
||||||
|
for (auto const& cell : mMaps)
|
||||||
|
{
|
||||||
|
if (mHasALastActiveCell && !intersection.inside({ cell.mCellX, cell.mCellY }))
|
||||||
|
mLocalMapRender->removeExteriorCell(cell.mCellX, cell.mCellY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mCurX = x;
|
mCurX = x;
|
||||||
mCurY = y;
|
mCurY = y;
|
||||||
mInterior = interior;
|
mInterior = interior;
|
||||||
|
@ -386,12 +439,11 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MyGUI::Widget* widget : mDoorMarkerWidgets)
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||||
|
|
||||||
// Delay the door markers update until scripts have been given a chance to run.
|
if (!mInterior)
|
||||||
// If we don't do this, door markers that should be disabled will still appear on the map.
|
mHasALastActiveCell = true;
|
||||||
mNeedDoorMarkersUpdate = true;
|
|
||||||
|
|
||||||
updateMagicMarkers();
|
updateMagicMarkers();
|
||||||
updateCustomMarkers();
|
updateCustomMarkers();
|
||||||
|
@ -490,12 +542,8 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::onFrame(float dt)
|
void LocalMapBase::onFrame(float dt)
|
||||||
{
|
|
||||||
if (mNeedDoorMarkersUpdate)
|
|
||||||
{
|
{
|
||||||
updateDoorMarkers();
|
updateDoorMarkers();
|
||||||
mNeedDoorMarkersUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMarkerUpdateTimer += dt;
|
mMarkerUpdateTimer += dt;
|
||||||
|
|
||||||
|
@ -570,30 +618,29 @@ namespace MWGui
|
||||||
|
|
||||||
void LocalMapBase::updateDoorMarkers()
|
void LocalMapBase::updateDoorMarkers()
|
||||||
{
|
{
|
||||||
// clear all previous door markers
|
std::vector<MWBase::World::DoorMarker> doors;
|
||||||
for (MyGUI::Widget* widget : mDoorMarkerWidgets)
|
|
||||||
MyGUI::Gui::getInstance().destroyWidget(widget);
|
|
||||||
mDoorMarkerWidgets.clear();
|
|
||||||
|
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
// Retrieve the door markers we want to show
|
mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end());
|
||||||
std::vector<MWBase::World::DoorMarker> doors;
|
mInteriorDoorMarkerWidgets.clear();
|
||||||
|
|
||||||
if (mInterior)
|
if (mInterior)
|
||||||
{
|
{
|
||||||
|
for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets)
|
||||||
|
widget->setVisible(false);
|
||||||
|
|
||||||
MWWorld::CellStore* cell = world->getInterior (mPrefix);
|
MWWorld::CellStore* cell = world->getInterior (mPrefix);
|
||||||
world->getDoorMarkers(cell, doors);
|
world->getDoorMarkers(cell, doors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int x = mCurX - mCellDistance; x <= mCurX + mCellDistance; ++x)
|
for (MapEntry& entry : mMaps)
|
||||||
{
|
{
|
||||||
for (int y = mCurY - mCellDistance; y <= mCurY + mCellDistance; ++y)
|
if (!entry.mMapTexture && !widgetCropped(entry.mMapWidget, mLocalMap))
|
||||||
{
|
world->getDoorMarkers(world->getExterior(entry.mCellX, entry.mCellY), doors);
|
||||||
MWWorld::CellStore* cell = world->getExterior (x, y);
|
|
||||||
world->getDoorMarkers(cell, doors);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (doors.empty())
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a widget for each marker
|
// Create a widget for each marker
|
||||||
|
@ -604,11 +651,33 @@ namespace MWGui
|
||||||
for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second; ++iter)
|
for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second; ++iter)
|
||||||
destNotes.push_back(iter->second.mNote);
|
destNotes.push_back(iter->second.mNote);
|
||||||
|
|
||||||
MyGUI::Widget* markerWidget = createDoorMarker(marker.name, destNotes, marker.x, marker.y);
|
MyGUI::Widget* markerWidget = nullptr;
|
||||||
|
MarkerUserData* data;
|
||||||
|
if (mDoorMarkersToRecycle.empty())
|
||||||
|
{
|
||||||
|
markerWidget = createDoorMarker(marker.name, destNotes, marker.x, marker.y);
|
||||||
|
data = markerWidget->getUserData<MarkerUserData>();
|
||||||
doorMarkerCreated(markerWidget);
|
doorMarkerCreated(markerWidget);
|
||||||
|
|
||||||
mDoorMarkerWidgets.push_back(markerWidget);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
markerWidget = (MarkerWidget*)mDoorMarkersToRecycle.back();
|
||||||
|
mDoorMarkersToRecycle.pop_back();
|
||||||
|
|
||||||
|
data = markerWidget->getUserData<MarkerUserData>();
|
||||||
|
data->notes = destNotes;
|
||||||
|
data->caption = marker.name;
|
||||||
|
markerWidget->setCoord(getMarkerCoordinates(marker.x, marker.y, *data, 8));
|
||||||
|
markerWidget->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDoorMarkersWidgets().push_back(markerWidget);
|
||||||
|
if (!mInterior)
|
||||||
|
mExteriorDoorsByCell[{data->cellX, data->cellY}].push_back(markerWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& widget : mDoorMarkersToRecycle)
|
||||||
|
widget->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMapBase::updateMagicMarkers()
|
void LocalMapBase::updateMagicMarkers()
|
||||||
|
@ -656,7 +725,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
MarkerUserData markerPos(mLocalMapRender);
|
MarkerUserData markerPos(mLocalMapRender);
|
||||||
for (MyGUI::Widget* widget : mDoorMarkerWidgets)
|
for (MyGUI::Widget* widget : currentDoorMarkersWidgets())
|
||||||
widget->setCoord(getMarkerCoordinates(widget, 8));
|
widget->setCoord(getMarkerCoordinates(widget, 8));
|
||||||
|
|
||||||
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
for (MyGUI::Widget* widget : mCustomMarkerWidgets)
|
||||||
|
@ -670,7 +739,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue)
|
MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue)
|
||||||
: WindowPinnableBase("openmw_map_window.layout")
|
: WindowPinnableBase("openmw_map_window.layout")
|
||||||
, LocalMapBase(customMarkers, localMapRender)
|
, LocalMapBase(customMarkers, localMapRender)
|
||||||
|
@ -730,7 +798,7 @@ namespace MWGui
|
||||||
mEventBoxLocal->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onMapDoubleClicked);
|
mEventBoxLocal->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onMapDoubleClicked);
|
||||||
mEventBoxLocal->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed);
|
mEventBoxLocal->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed);
|
||||||
|
|
||||||
LocalMapBase::init(mLocalMap, mPlayerArrowLocal);
|
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, getLocalViewingDistance());
|
||||||
|
|
||||||
mGlobalMap->setVisible(mGlobal);
|
mGlobalMap->setVisible(mGlobal);
|
||||||
mLocalMap->setVisible(!mGlobal);
|
mLocalMap->setVisible(!mGlobal);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <components/esm/cellid.hpp>
|
#include <components/esm/cellid.hpp>
|
||||||
|
|
||||||
#include <components/esm/custommarkerstate.hpp>
|
#include <components/esm/custommarkerstate.hpp>
|
||||||
|
#include <components/misc/constants.hpp>
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
@ -72,7 +73,7 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
LocalMapBase(CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled = true);
|
LocalMapBase(CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled = true);
|
||||||
virtual ~LocalMapBase();
|
virtual ~LocalMapBase();
|
||||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass);
|
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius);
|
||||||
|
|
||||||
void setCellPrefix(const std::string& prefix);
|
void setCellPrefix(const std::string& prefix);
|
||||||
void setActiveCell(const int x, const int y, bool interior=false);
|
void setActiveCell(const int x, const int y, bool interior=false);
|
||||||
|
@ -113,7 +114,9 @@ namespace MWGui
|
||||||
MWRender::LocalMap* mLocalMapRender;
|
MWRender::LocalMap* mLocalMapRender;
|
||||||
|
|
||||||
int mCurX, mCurY; //the position of the active cell on the global map (in cell coords)
|
int mCurX, mCurY; //the position of the active cell on the global map (in cell coords)
|
||||||
|
bool mHasALastActiveCell = false;
|
||||||
osg::Vec2f mCurPos; //the position of the player in the world (in cell coords)
|
osg::Vec2f mCurPos; //the position of the player in the world (in cell coords)
|
||||||
|
|
||||||
bool mInterior;
|
bool mInterior;
|
||||||
MyGUI::ScrollView* mLocalMap;
|
MyGUI::ScrollView* mLocalMap;
|
||||||
MyGUI::ImageBox* mCompass;
|
MyGUI::ImageBox* mCompass;
|
||||||
|
@ -145,9 +148,14 @@ namespace MWGui
|
||||||
std::vector<MapEntry> mMaps;
|
std::vector<MapEntry> mMaps;
|
||||||
|
|
||||||
// Keep track of created marker widgets, just to easily remove them later.
|
// Keep track of created marker widgets, just to easily remove them later.
|
||||||
std::vector<MyGUI::Widget*> mDoorMarkerWidgets;
|
std::vector<MyGUI::Widget*> mExteriorDoorMarkerWidgets;
|
||||||
|
std::map<std::pair<int, int>, std::vector<MyGUI::Widget*>> mExteriorDoorsByCell;
|
||||||
|
std::vector<MyGUI::Widget*> mInteriorDoorMarkerWidgets;
|
||||||
std::vector<MyGUI::Widget*> mMagicMarkerWidgets;
|
std::vector<MyGUI::Widget*> mMagicMarkerWidgets;
|
||||||
std::vector<MyGUI::Widget*> mCustomMarkerWidgets;
|
std::vector<MyGUI::Widget*> mCustomMarkerWidgets;
|
||||||
|
std::vector<MyGUI::Widget*> mDoorMarkersToRecycle;
|
||||||
|
|
||||||
|
std::vector<MyGUI::Widget*>& currentDoorMarkersWidgets();
|
||||||
|
|
||||||
virtual void updateCustomMarkers();
|
virtual void updateCustomMarkers();
|
||||||
|
|
||||||
|
@ -181,7 +189,6 @@ namespace MWGui
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateDoorMarkers();
|
void updateDoorMarkers();
|
||||||
bool mNeedDoorMarkersUpdate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditNoteDialog : public MWGui::WindowModal
|
class EditNoteDialog : public MWGui::WindowModal
|
||||||
|
|
|
@ -118,14 +118,15 @@ const osg::Vec2f LocalMap::rotatePoint(const osg::Vec2f& point, const osg::Vec2f
|
||||||
|
|
||||||
void LocalMap::clear()
|
void LocalMap::clear()
|
||||||
{
|
{
|
||||||
mSegments.clear();
|
mExteriorSegments.clear();
|
||||||
|
mInteriorSegments.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::saveFogOfWar(MWWorld::CellStore* cell)
|
void LocalMap::saveFogOfWar(MWWorld::CellStore* cell)
|
||||||
{
|
{
|
||||||
if (!mInterior)
|
if (!mInterior)
|
||||||
{
|
{
|
||||||
const MapSegment& segment = mSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())];
|
const MapSegment& segment = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())];
|
||||||
|
|
||||||
if (segment.mFogOfWarImage && segment.mHasFogState)
|
if (segment.mFogOfWarImage && segment.mHasFogState)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +156,7 @@ void LocalMap::saveFogOfWar(MWWorld::CellStore* cell)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < segments.second; ++y)
|
for (int y = 0; y < segments.second; ++y)
|
||||||
{
|
{
|
||||||
const MapSegment& segment = mSegments[std::make_pair(x,y)];
|
const MapSegment& segment = mInteriorSegments[std::make_pair(x,y)];
|
||||||
|
|
||||||
fog->mFogTextures.emplace_back();
|
fog->mFogTextures.emplace_back();
|
||||||
|
|
||||||
|
@ -249,26 +250,10 @@ void LocalMap::setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int
|
||||||
mRoot->addChild(camera);
|
mRoot->addChild(camera);
|
||||||
mActiveCameras.push_back(camera);
|
mActiveCameras.push_back(camera);
|
||||||
|
|
||||||
MapSegment& segment = mSegments[std::make_pair(x, y)];
|
MapSegment& segment = mInterior? mInteriorSegments[std::make_pair(x, y)] : mExteriorSegments[std::make_pair(x, y)];
|
||||||
segment.mMapTexture = texture;
|
segment.mMapTexture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needUpdate(std::set<std::pair<int, int> >& renderedGrid, std::set<std::pair<int, int> >& currentGrid, int cellX, int cellY)
|
|
||||||
{
|
|
||||||
// if all the cells of the current grid are contained in the rendered grid then we can keep the old render
|
|
||||||
for (int dx=-1;dx<2;dx+=1)
|
|
||||||
{
|
|
||||||
for (int dy=-1;dy<2;dy+=1)
|
|
||||||
{
|
|
||||||
bool haveInRenderedGrid = renderedGrid.find(std::make_pair(cellX+dx,cellY+dy)) != renderedGrid.end();
|
|
||||||
bool haveInCurrentGrid = currentGrid.find(std::make_pair(cellX+dx,cellY+dy)) != currentGrid.end();
|
|
||||||
if (haveInCurrentGrid && !haveInRenderedGrid)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMap::requestMap(const MWWorld::CellStore* cell)
|
void LocalMap::requestMap(const MWWorld::CellStore* cell)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
|
@ -276,13 +261,13 @@ void LocalMap::requestMap(const MWWorld::CellStore* cell)
|
||||||
int cellX = cell->getCell()->getGridX();
|
int cellX = cell->getCell()->getGridX();
|
||||||
int cellY = cell->getCell()->getGridY();
|
int cellY = cell->getCell()->getGridY();
|
||||||
|
|
||||||
MapSegment& segment = mSegments[std::make_pair(cellX, cellY)];
|
MapSegment& segment = mExteriorSegments[std::make_pair(cellX, cellY)];
|
||||||
if (!needUpdate(segment.mGrid, mCurrentGrid, cellX, cellY))
|
if (!segment.needUpdate)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
segment.mGrid = mCurrentGrid;
|
|
||||||
requestExteriorMap(cell);
|
requestExteriorMap(cell);
|
||||||
|
segment.needUpdate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -292,27 +277,27 @@ void LocalMap::requestMap(const MWWorld::CellStore* cell)
|
||||||
void LocalMap::addCell(MWWorld::CellStore *cell)
|
void LocalMap::addCell(MWWorld::CellStore *cell)
|
||||||
{
|
{
|
||||||
if (cell->isExterior())
|
if (cell->isExterior())
|
||||||
mCurrentGrid.emplace(cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())].needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMap::removeExteriorCell(int x, int y)
|
||||||
|
{
|
||||||
|
mExteriorSegments.erase({ x, y });
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::removeCell(MWWorld::CellStore *cell)
|
void LocalMap::removeCell(MWWorld::CellStore *cell)
|
||||||
{
|
{
|
||||||
saveFogOfWar(cell);
|
saveFogOfWar(cell);
|
||||||
|
|
||||||
if (cell->isExterior())
|
if (!cell->isExterior())
|
||||||
{
|
mInteriorSegments.clear();
|
||||||
std::pair<int, int> coords = std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
|
||||||
mSegments.erase(coords);
|
|
||||||
mCurrentGrid.erase(coords);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mSegments.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> LocalMap::getMapTexture(int x, int y)
|
osg::ref_ptr<osg::Texture2D> LocalMap::getMapTexture(int x, int y)
|
||||||
{
|
{
|
||||||
SegmentMap::iterator found = mSegments.find(std::make_pair(x, y));
|
auto& segments(mInterior ? mInteriorSegments : mExteriorSegments);
|
||||||
if (found == mSegments.end())
|
SegmentMap::iterator found = segments.find(std::make_pair(x, y));
|
||||||
|
if (found == segments.end())
|
||||||
return osg::ref_ptr<osg::Texture2D>();
|
return osg::ref_ptr<osg::Texture2D>();
|
||||||
else
|
else
|
||||||
return found->second.mMapTexture;
|
return found->second.mMapTexture;
|
||||||
|
@ -320,8 +305,9 @@ osg::ref_ptr<osg::Texture2D> LocalMap::getMapTexture(int x, int y)
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> LocalMap::getFogOfWarTexture(int x, int y)
|
osg::ref_ptr<osg::Texture2D> LocalMap::getFogOfWarTexture(int x, int y)
|
||||||
{
|
{
|
||||||
SegmentMap::iterator found = mSegments.find(std::make_pair(x, y));
|
auto& segments(mInterior ? mInteriorSegments : mExteriorSegments);
|
||||||
if (found == mSegments.end())
|
SegmentMap::iterator found = segments.find(std::make_pair(x, y));
|
||||||
|
if (found == segments.end())
|
||||||
return osg::ref_ptr<osg::Texture2D>();
|
return osg::ref_ptr<osg::Texture2D>();
|
||||||
else
|
else
|
||||||
return found->second.mFogOfWarTexture;
|
return found->second.mFogOfWarTexture;
|
||||||
|
@ -371,7 +357,7 @@ void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell)
|
||||||
osg::Vec3d(0,1,0), zmin, zmax);
|
osg::Vec3d(0,1,0), zmin, zmax);
|
||||||
setupRenderToTexture(camera, cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
setupRenderToTexture(camera, cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||||
|
|
||||||
MapSegment& segment = mSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())];
|
MapSegment& segment = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())];
|
||||||
if (!segment.mFogOfWarImage)
|
if (!segment.mFogOfWarImage)
|
||||||
{
|
{
|
||||||
if (cell->getFog())
|
if (cell->getFog())
|
||||||
|
@ -512,7 +498,7 @@ void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell)
|
||||||
setupRenderToTexture(camera, x, y);
|
setupRenderToTexture(camera, x, y);
|
||||||
|
|
||||||
auto coords = std::make_pair(x,y);
|
auto coords = std::make_pair(x,y);
|
||||||
MapSegment& segment = mSegments[coords];
|
MapSegment& segment = mInteriorSegments[coords];
|
||||||
if (!segment.mFogOfWarImage)
|
if (!segment.mFogOfWarImage)
|
||||||
{
|
{
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
|
@ -558,7 +544,8 @@ osg::Vec2f LocalMap::interiorMapToWorldPosition (float nX, float nY, int x, int
|
||||||
|
|
||||||
bool LocalMap::isPositionExplored (float nX, float nY, int x, int y)
|
bool LocalMap::isPositionExplored (float nX, float nY, int x, int y)
|
||||||
{
|
{
|
||||||
const MapSegment& segment = mSegments[std::make_pair(x, y)];
|
auto& segments(mInterior ? mInteriorSegments : mExteriorSegments);
|
||||||
|
const MapSegment& segment = segments[std::make_pair(x, y)];
|
||||||
if (!segment.mFogOfWarImage)
|
if (!segment.mFogOfWarImage)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -630,7 +617,8 @@ void LocalMap::updatePlayer (const osg::Vec3f& position, const osg::Quat& orient
|
||||||
int texX = x + mx;
|
int texX = x + mx;
|
||||||
int texY = y + my*-1;
|
int texY = y + my*-1;
|
||||||
|
|
||||||
MapSegment& segment = mSegments[std::make_pair(texX, texY)];
|
auto& segments(mInterior ? mInteriorSegments : mExteriorSegments);
|
||||||
|
MapSegment& segment = segments[std::make_pair(texX, texY)];
|
||||||
|
|
||||||
if (!segment.mFogOfWarImage || !segment.mMapTexture)
|
if (!segment.mFogOfWarImage || !segment.mMapTexture)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace MWRender
|
||||||
void requestMap (const MWWorld::CellStore* cell);
|
void requestMap (const MWWorld::CellStore* cell);
|
||||||
|
|
||||||
void addCell(MWWorld::CellStore* cell);
|
void addCell(MWWorld::CellStore* cell);
|
||||||
|
void removeExteriorCell(int x, int y);
|
||||||
|
|
||||||
void removeCell (MWWorld::CellStore* cell);
|
void removeCell (MWWorld::CellStore* cell);
|
||||||
|
|
||||||
|
@ -126,13 +127,14 @@ namespace MWRender
|
||||||
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
osg::ref_ptr<osg::Texture2D> mFogOfWarTexture;
|
||||||
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
osg::ref_ptr<osg::Image> mFogOfWarImage;
|
||||||
|
|
||||||
Grid mGrid; // the grid that was active at the time of rendering this segment
|
bool needUpdate = true;
|
||||||
|
|
||||||
bool mHasFogState;
|
bool mHasFogState;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
|
typedef std::map<std::pair<int, int>, MapSegment> SegmentMap;
|
||||||
SegmentMap mSegments;
|
SegmentMap mExteriorSegments;
|
||||||
|
SegmentMap mInteriorSegments;
|
||||||
|
|
||||||
int mMapResolution;
|
int mMapResolution;
|
||||||
|
|
||||||
|
|
|
@ -114,3 +114,15 @@ allow zooming
|
||||||
If this setting is true the user can zoom in/out on local and global map with the mouse wheel.
|
If this setting is true the user can zoom in/out on local and global map with the mouse wheel.
|
||||||
|
|
||||||
This setting can be controlled in Advanced tab of the launcher.
|
This setting can be controlled in Advanced tab of the launcher.
|
||||||
|
|
||||||
|
local viewing distance coef
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
:Type: float
|
||||||
|
:Range: > 0 and <= 1
|
||||||
|
:Default: 0.5
|
||||||
|
|
||||||
|
This setting controls viewing distance on local map. It is the coefficient of the viewing distance viewable on the local map if 'distant terrain' is enabled otherwise you will see the default value (a 3x3 square centered on the player).
|
||||||
|
If view distance is changed in settings menu during the game, then viewable distance on the local map is not updated.
|
||||||
|
|
||||||
|
This setting can not be configured except by editing the settings configuration file.
|
||||||
|
|
|
@ -202,6 +202,9 @@ global = false
|
||||||
# If true, allow zoom on local and global maps
|
# If true, allow zoom on local and global maps
|
||||||
allow zooming = false
|
allow zooming = false
|
||||||
|
|
||||||
|
# The local view distance coefficient (1.0 is full view distance if distant terrain is enabled)
|
||||||
|
local viewing distance coef = 0.5
|
||||||
|
|
||||||
[GUI]
|
[GUI]
|
||||||
|
|
||||||
# Scales GUI window and widget size. (<1.0 is smaller, >1.0 is larger).
|
# Scales GUI window and widget size. (<1.0 is smaller, >1.0 is larger).
|
||||||
|
|
Loading…
Reference in a new issue