2013-04-10 00:32:05 -04:00
|
|
|
#ifndef MWGUI_MAPWINDOW_H
|
|
|
|
#define MWGUI_MAPWINDOW_H
|
|
|
|
|
2022-01-22 22:44:02 +01:00
|
|
|
#include <cstdint>
|
2019-02-25 18:47:42 +03:00
|
|
|
#include <memory>
|
2014-02-03 11:20:55 +01:00
|
|
|
|
2021-11-08 01:45:41 +01:00
|
|
|
#include <osg/Vec2f>
|
|
|
|
|
2022-04-08 22:04:32 +02:00
|
|
|
#include <MyGUI_ITexture.h>
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
#include "windowpinnablebase.hpp"
|
|
|
|
|
2022-01-22 15:58:41 +01:00
|
|
|
#include <components/esm3/custommarkerstate.hpp>
|
2020-11-03 08:08:50 +01:00
|
|
|
#include <components/misc/constants.hpp>
|
2015-01-19 00:35:19 +01:00
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
namespace MWRender
|
|
|
|
{
|
|
|
|
class GlobalMap;
|
2015-05-26 16:40:44 +02:00
|
|
|
class LocalMap;
|
2013-04-10 00:32:05 -04:00
|
|
|
}
|
|
|
|
|
2014-01-25 18:20:17 +01:00
|
|
|
namespace ESM
|
|
|
|
{
|
|
|
|
class ESMReader;
|
|
|
|
class ESMWriter;
|
|
|
|
}
|
|
|
|
|
2016-02-05 00:39:52 +01:00
|
|
|
namespace MWWorld
|
|
|
|
{
|
|
|
|
class CellStore;
|
|
|
|
}
|
|
|
|
|
2013-08-27 15:48:13 +02:00
|
|
|
namespace Loading
|
|
|
|
{
|
|
|
|
class Listener;
|
|
|
|
}
|
|
|
|
|
2017-02-14 03:55:29 +01:00
|
|
|
namespace SceneUtil
|
|
|
|
{
|
|
|
|
class WorkQueue;
|
|
|
|
}
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
namespace MWGui
|
|
|
|
{
|
2014-08-17 05:45:35 +02:00
|
|
|
|
|
|
|
class CustomMarkerCollection
|
|
|
|
{
|
|
|
|
public:
|
2015-01-19 00:35:19 +01:00
|
|
|
void addMarker(const ESM::CustomMarker& marker, bool triggerEvent = true);
|
|
|
|
void deleteMarker(const ESM::CustomMarker& marker);
|
|
|
|
void updateMarker(const ESM::CustomMarker& marker, const std::string& newNote);
|
2014-08-17 05:45:35 +02:00
|
|
|
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
size_t size() const;
|
|
|
|
|
2023-02-19 17:42:37 +01:00
|
|
|
typedef std::multimap<ESM::RefId, ESM::CustomMarker> ContainerType;
|
2015-07-17 20:49:10 +02:00
|
|
|
|
|
|
|
typedef std::pair<ContainerType::const_iterator, ContainerType::const_iterator> RangeType;
|
|
|
|
|
|
|
|
ContainerType::const_iterator begin() const;
|
|
|
|
ContainerType::const_iterator end() const;
|
|
|
|
|
2023-02-19 17:42:37 +01:00
|
|
|
RangeType getMarkers(const ESM::RefId& cellId) const;
|
2014-08-17 05:45:35 +02:00
|
|
|
|
2023-07-15 15:02:27 +02:00
|
|
|
typedef MyGUI::delegates::MultiDelegate<> EventHandle_Void;
|
2014-08-17 05:45:35 +02:00
|
|
|
EventHandle_Void eventMarkersChanged;
|
|
|
|
|
|
|
|
private:
|
2015-07-17 20:49:10 +02:00
|
|
|
ContainerType mMarkers;
|
2014-08-17 05:45:35 +02:00
|
|
|
};
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
class LocalMapBase
|
|
|
|
{
|
|
|
|
public:
|
2023-08-10 20:49:35 +02:00
|
|
|
LocalMapBase(CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled);
|
2013-06-09 23:08:57 +02:00
|
|
|
virtual ~LocalMapBase();
|
2020-11-03 08:08:50 +01:00
|
|
|
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius);
|
2013-04-10 00:32:05 -04:00
|
|
|
|
|
|
|
void setCellPrefix(const std::string& prefix);
|
|
|
|
void setActiveCell(const int x, const int y, bool interior = false);
|
2016-02-05 00:39:52 +01:00
|
|
|
void requestMapRender(const MWWorld::CellStore* cell);
|
2013-04-10 00:32:05 -04:00
|
|
|
void setPlayerDir(const float x, const float y);
|
2014-10-02 16:30:23 +02:00
|
|
|
void setPlayerPos(int cellX, int cellY, const float nx, const float ny);
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2014-06-17 16:27:33 +02:00
|
|
|
void onFrame(float dt);
|
|
|
|
|
2014-05-16 09:21:08 +02:00
|
|
|
bool toggleFogOfWar();
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2015-01-31 17:50:19 +01:00
|
|
|
struct MarkerUserData
|
2013-04-10 00:32:05 -04:00
|
|
|
{
|
2015-05-26 16:40:44 +02:00
|
|
|
MarkerUserData(MWRender::LocalMap* map)
|
|
|
|
: mLocalMapRender(map)
|
2015-07-01 03:42:04 +02:00
|
|
|
, cellX(0)
|
|
|
|
, cellY(0)
|
|
|
|
, nX(0.f)
|
|
|
|
, nY(0.f)
|
2015-05-26 16:40:44 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isPositionExplored() const;
|
|
|
|
|
|
|
|
MWRender::LocalMap* mLocalMapRender;
|
2013-04-10 00:32:05 -04:00
|
|
|
int cellX;
|
|
|
|
int cellY;
|
|
|
|
float nX;
|
|
|
|
float nY;
|
2015-01-31 17:50:19 +01:00
|
|
|
std::vector<std::string> notes;
|
|
|
|
std::string caption;
|
2013-04-10 00:32:05 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
2020-11-26 16:32:50 +01:00
|
|
|
void updateLocalMap();
|
|
|
|
|
|
|
|
float mLocalMapZoom = 1.f;
|
2015-05-26 16:40:44 +02:00
|
|
|
MWRender::LocalMap* mLocalMapRender;
|
|
|
|
|
2020-11-26 16:32:50 +01:00
|
|
|
int mCurX, mCurY; // the position of the active cell on the global map (in cell coords)
|
2020-11-03 08:08:50 +01:00
|
|
|
bool mHasALastActiveCell = false;
|
2020-11-26 16:32:50 +01:00
|
|
|
osg::Vec2f mCurPos; // the position of the player in the world (in cell coords)
|
2020-11-03 08:08:50 +01:00
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
bool mInterior;
|
|
|
|
MyGUI::ScrollView* mLocalMap;
|
|
|
|
MyGUI::ImageBox* mCompass;
|
|
|
|
std::string mPrefix;
|
|
|
|
bool mChanged;
|
2016-01-07 01:08:30 +01:00
|
|
|
bool mFogOfWarToggled;
|
2023-08-10 20:49:35 +02:00
|
|
|
bool mFogOfWarEnabled;
|
2014-12-23 02:33:14 +01:00
|
|
|
|
2016-02-05 01:18:44 +01:00
|
|
|
int mNumCells; // for convenience, mCellDistance * 2 + 1
|
|
|
|
int mCellDistance;
|
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
// Stores markers that were placed by a player. May be shared between multiple map views.
|
|
|
|
CustomMarkerCollection& mCustomMarkers;
|
|
|
|
|
2019-02-20 13:37:00 +00:00
|
|
|
struct MapEntry
|
|
|
|
{
|
|
|
|
MapEntry(MyGUI::ImageBox* mapWidget, MyGUI::ImageBox* fogWidget)
|
2019-02-20 13:37:00 +00:00
|
|
|
: mMapWidget(mapWidget)
|
|
|
|
, mFogWidget(fogWidget)
|
|
|
|
, mCellX(0)
|
|
|
|
, mCellY(0)
|
|
|
|
{
|
|
|
|
}
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2019-02-20 13:37:00 +00:00
|
|
|
MyGUI::ImageBox* mMapWidget;
|
|
|
|
MyGUI::ImageBox* mFogWidget;
|
2022-04-08 22:04:32 +02:00
|
|
|
std::unique_ptr<MyGUI::ITexture> mMapTexture;
|
|
|
|
std::unique_ptr<MyGUI::ITexture> mFogTexture;
|
2019-02-20 13:37:00 +00:00
|
|
|
int mCellX;
|
|
|
|
int mCellY;
|
2019-02-20 13:37:00 +00:00
|
|
|
};
|
|
|
|
std::vector<MapEntry> mMaps;
|
2015-05-26 16:40:44 +02:00
|
|
|
|
2014-05-10 01:06:08 +02:00
|
|
|
// Keep track of created marker widgets, just to easily remove them later.
|
2020-11-03 08:08:50 +01:00
|
|
|
std::vector<MyGUI::Widget*> mExteriorDoorMarkerWidgets;
|
|
|
|
std::map<std::pair<int, int>, std::vector<MyGUI::Widget*>> mExteriorDoorsByCell;
|
|
|
|
std::vector<MyGUI::Widget*> mInteriorDoorMarkerWidgets;
|
2014-08-17 05:45:35 +02:00
|
|
|
std::vector<MyGUI::Widget*> mMagicMarkerWidgets;
|
|
|
|
std::vector<MyGUI::Widget*> mCustomMarkerWidgets;
|
2020-11-03 08:08:50 +01:00
|
|
|
std::vector<MyGUI::Widget*> mDoorMarkersToRecycle;
|
|
|
|
|
|
|
|
std::vector<MyGUI::Widget*>& currentDoorMarkersWidgets();
|
2014-05-10 01:06:08 +02:00
|
|
|
|
2015-07-18 00:14:11 +02:00
|
|
|
virtual void updateCustomMarkers();
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
void applyFogOfWar();
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2020-11-09 14:06:50 +01:00
|
|
|
MyGUI::IntPoint getPosition(int cellX, int cellY, float nx, float ny) const;
|
|
|
|
MyGUI::IntPoint getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const;
|
|
|
|
MyGUI::IntCoord getMarkerCoordinates(
|
|
|
|
float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const;
|
|
|
|
MyGUI::Widget* createDoorMarker(
|
|
|
|
const std::string& name, const MyGUI::VectorString& notes, float x, float y) const;
|
2020-11-26 16:32:50 +01:00
|
|
|
MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const;
|
2014-01-01 22:37:52 +01:00
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
virtual void notifyPlayerUpdate() {}
|
2020-11-26 16:32:50 +01:00
|
|
|
virtual void centerView();
|
2013-04-10 00:32:05 -04:00
|
|
|
virtual void notifyMapChanged() {}
|
|
|
|
|
2014-09-26 14:27:52 +02:00
|
|
|
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
|
|
|
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
2014-08-17 05:45:35 +02:00
|
|
|
|
2019-02-20 13:37:00 +00:00
|
|
|
void updateRequiredMaps();
|
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
void updateMagicMarkers();
|
2014-01-01 22:37:52 +01:00
|
|
|
void addDetectionMarkers(int type);
|
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
void redraw();
|
2020-11-09 14:06:50 +01:00
|
|
|
float getWidgetSize() const;
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2014-06-17 16:27:33 +02:00
|
|
|
float mMarkerUpdateTimer;
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
float mLastDirectionX;
|
|
|
|
float mLastDirectionY;
|
2016-08-12 03:14:36 +02:00
|
|
|
|
2021-08-12 22:06:21 +02:00
|
|
|
bool mNeedDoorMarkersUpdate;
|
|
|
|
|
2016-08-12 03:14:36 +02:00
|
|
|
private:
|
|
|
|
void updateDoorMarkers();
|
2013-04-10 00:32:05 -04:00
|
|
|
};
|
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
class EditNoteDialog : public MWGui::WindowModal
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
EditNoteDialog();
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void onOpen() override;
|
2014-08-17 05:45:35 +02:00
|
|
|
|
|
|
|
void showDeleteButton(bool show);
|
|
|
|
bool getDeleteButtonShown();
|
|
|
|
void setText(const std::string& text);
|
|
|
|
std::string getText();
|
|
|
|
|
2023-07-15 15:02:27 +02:00
|
|
|
typedef MyGUI::delegates::MultiDelegate<> EventHandle_Void;
|
2014-08-17 05:45:35 +02:00
|
|
|
|
|
|
|
EventHandle_Void eventDeleteClicked;
|
|
|
|
EventHandle_Void eventOkClicked;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void onCancelButtonClicked(MyGUI::Widget* sender);
|
|
|
|
void onOkButtonClicked(MyGUI::Widget* sender);
|
|
|
|
void onDeleteButtonClicked(MyGUI::Widget* sender);
|
|
|
|
|
|
|
|
MyGUI::TextBox* mTextEdit;
|
|
|
|
MyGUI::Button* mOkButton;
|
|
|
|
MyGUI::Button* mCancelButton;
|
|
|
|
MyGUI::Button* mDeleteButton;
|
|
|
|
};
|
|
|
|
|
2014-01-26 14:47:01 +01:00
|
|
|
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop
|
2013-04-10 00:32:05 -04:00
|
|
|
{
|
|
|
|
public:
|
2017-02-14 03:55:29 +01:00
|
|
|
MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender,
|
|
|
|
SceneUtil::WorkQueue* workQueue);
|
2013-04-10 00:32:05 -04:00
|
|
|
virtual ~MapWindow();
|
|
|
|
|
|
|
|
void setCellName(const std::string& cellName);
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void setAlpha(float alpha) override;
|
|
|
|
void setVisible(bool visible) override;
|
2014-09-13 07:59:29 +02:00
|
|
|
|
2017-02-14 03:55:29 +01:00
|
|
|
void renderGlobalMap();
|
2013-08-27 15:48:13 +02:00
|
|
|
|
2015-08-06 23:29:19 +02:00
|
|
|
/// adds the marker to the global map
|
|
|
|
/// @param name The ESM::Cell::mName
|
2014-05-11 15:17:25 +02:00
|
|
|
void addVisitedLocation(const std::string& name, int x, int y);
|
|
|
|
|
|
|
|
// reveals this cell's map on the global map
|
2013-04-10 00:32:05 -04:00
|
|
|
void cellExplored(int x, int y);
|
|
|
|
|
2013-12-31 18:35:46 +01:00
|
|
|
void setGlobalMapPlayerPosition(float worldX, float worldY);
|
2014-09-12 18:26:38 -04:00
|
|
|
void setGlobalMapPlayerDir(const float x, const float y);
|
2013-12-31 18:35:46 +01:00
|
|
|
|
2017-02-14 03:55:29 +01:00
|
|
|
void ensureGlobalMapLoaded();
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void onOpen() override;
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void onFrame(float dt) override;
|
2014-01-26 14:47:01 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void updateCustomMarkers() override;
|
2015-07-18 00:14:11 +02:00
|
|
|
|
2014-01-25 13:34:56 +01:00
|
|
|
/// Clear all savegame-specific data
|
2020-10-16 22:18:54 +04:00
|
|
|
void clear() override;
|
2014-01-25 13:34:56 +01:00
|
|
|
|
2014-04-28 11:29:57 +02:00
|
|
|
void write(ESM::ESMWriter& writer, Loading::Listener& progress);
|
2015-01-22 19:04:59 +01:00
|
|
|
void readRecord(ESM::ESMReader& reader, uint32_t type);
|
2014-01-25 18:20:17 +01:00
|
|
|
|
2022-02-13 20:45:05 +01:00
|
|
|
void asyncPrepareSaveMap();
|
|
|
|
|
2023-07-09 08:42:09 +02:00
|
|
|
std::string_view getWindowIdForLua() const override { return "Map"; }
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
private:
|
|
|
|
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
|
|
|
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
|
|
|
void onWorldButtonClicked(MyGUI::Widget* _sender);
|
2014-08-17 05:45:35 +02:00
|
|
|
void onMapDoubleClicked(MyGUI::Widget* sender);
|
2020-11-21 16:37:42 +01:00
|
|
|
void onMapZoomed(MyGUI::Widget* sender, int rel);
|
|
|
|
void zoomOnCursor(float speedDiff);
|
|
|
|
void updateGlobalMap();
|
2014-09-26 14:27:52 +02:00
|
|
|
void onCustomMarkerDoubleClicked(MyGUI::Widget* sender);
|
2014-08-17 05:45:35 +02:00
|
|
|
void onNoteEditOk();
|
|
|
|
void onNoteEditDelete();
|
2014-09-07 03:18:01 +02:00
|
|
|
void onNoteEditDeleteConfirm();
|
2014-08-17 05:45:35 +02:00
|
|
|
void onNoteDoubleClicked(MyGUI::Widget* sender);
|
2014-09-12 15:06:37 -04:00
|
|
|
void onChangeScrollWindowCoord(MyGUI::Widget* sender);
|
2013-04-10 00:32:05 -04:00
|
|
|
void globalMapUpdatePlayer();
|
2015-07-18 00:14:11 +02:00
|
|
|
void setGlobalMapMarkerTooltip(MyGUI::Widget* widget, int x, int y);
|
2020-11-29 22:03:54 +01:00
|
|
|
float getMarkerSize(size_t agregatedWeight) const;
|
2020-11-21 16:37:42 +01:00
|
|
|
void resizeGlobalMap();
|
|
|
|
void worldPosToGlobalMapImageSpace(float x, float z, float& imageX, float& imageY) const;
|
2020-11-29 22:03:54 +01:00
|
|
|
MyGUI::IntCoord createMarkerCoords(float x, float y, float agregatedWeight) const;
|
|
|
|
MyGUI::Widget* createMarker(const std::string& name, float x, float y, float agregatedWeight);
|
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
MyGUI::ScrollView* mGlobalMap;
|
2017-04-28 17:30:26 +02:00
|
|
|
std::unique_ptr<MyGUI::ITexture> mGlobalMapTexture;
|
|
|
|
std::unique_ptr<MyGUI::ITexture> mGlobalMapOverlayTexture;
|
2013-04-10 00:32:05 -04:00
|
|
|
MyGUI::ImageBox* mGlobalMapImage;
|
|
|
|
MyGUI::ImageBox* mGlobalMapOverlay;
|
|
|
|
MyGUI::ImageBox* mPlayerArrowLocal;
|
|
|
|
MyGUI::ImageBox* mPlayerArrowGlobal;
|
|
|
|
MyGUI::Button* mButton;
|
|
|
|
MyGUI::IntPoint mLastDragPos;
|
|
|
|
|
2014-09-12 15:06:37 -04:00
|
|
|
MyGUI::IntCoord mLastScrollWindowCoordinates;
|
|
|
|
|
2014-05-10 01:06:08 +02:00
|
|
|
// Markers on global map
|
|
|
|
typedef std::pair<int, int> CellId;
|
2014-09-26 16:51:48 +02:00
|
|
|
std::set<CellId> mMarkers;
|
2014-05-10 01:06:08 +02:00
|
|
|
|
2013-04-10 00:32:05 -04:00
|
|
|
MyGUI::Button* mEventBoxGlobal;
|
|
|
|
MyGUI::Button* mEventBoxLocal;
|
|
|
|
|
2020-11-21 16:37:42 +01:00
|
|
|
float mGlobalMapZoom = 1.0f;
|
2022-02-13 20:45:05 +01:00
|
|
|
std::unique_ptr<MWRender::GlobalMap> mGlobalMapRender;
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2020-11-29 22:03:54 +01:00
|
|
|
struct MapMarkerType
|
|
|
|
{
|
|
|
|
osg::Vec2f position;
|
|
|
|
MyGUI::Widget* widget = nullptr;
|
|
|
|
|
|
|
|
bool operator<(const MapMarkerType& right) const { return widget < right.widget; }
|
|
|
|
};
|
|
|
|
|
|
|
|
std::map<std::string, MapMarkerType> mGlobalMapMarkersByName;
|
|
|
|
std::map<MapMarkerType, std::vector<MapMarkerType>> mGlobalMapMarkers;
|
2015-05-28 18:44:34 +02:00
|
|
|
|
2014-08-17 05:45:35 +02:00
|
|
|
EditNoteDialog mEditNoteDialog;
|
2015-01-19 00:35:19 +01:00
|
|
|
ESM::CustomMarker mEditingMarker;
|
2014-08-17 05:45:35 +02:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void onPinToggled() override;
|
|
|
|
void onTitleDoubleClicked() override;
|
2014-09-26 14:27:52 +02:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void doorMarkerCreated(MyGUI::Widget* marker) override;
|
|
|
|
void customMarkerCreated(MyGUI::Widget* marker) override;
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void notifyPlayerUpdate() override;
|
2013-04-10 00:32:05 -04:00
|
|
|
|
2020-11-26 16:32:50 +01:00
|
|
|
void centerView() override;
|
2013-04-10 00:32:05 -04:00
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|