You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
360 lines
9.9 KiB
C++
360 lines
9.9 KiB
C++
#ifndef MWGUI_MAPWINDOW_H
|
|
#define MWGUI_MAPWINDOW_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "windowpinnablebase.hpp"
|
|
|
|
#include <components/esm/cellid.hpp>
|
|
|
|
#include <components/esm/custommarkerstate.hpp>
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Declare GUIController here so we can use it for delegates
|
|
*/
|
|
namespace mwmp
|
|
{
|
|
class GUIController;
|
|
}
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
namespace MWRender
|
|
{
|
|
class GlobalMap;
|
|
class LocalMap;
|
|
}
|
|
|
|
namespace ESM
|
|
{
|
|
class ESMReader;
|
|
class ESMWriter;
|
|
}
|
|
|
|
namespace MWWorld
|
|
{
|
|
class CellStore;
|
|
}
|
|
|
|
namespace Loading
|
|
{
|
|
class Listener;
|
|
}
|
|
|
|
namespace SceneUtil
|
|
{
|
|
class WorkQueue;
|
|
}
|
|
|
|
namespace MWGui
|
|
{
|
|
|
|
class CustomMarkerCollection
|
|
{
|
|
public:
|
|
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);
|
|
|
|
void clear();
|
|
|
|
size_t size() const;
|
|
|
|
typedef std::multimap<ESM::CellId, ESM::CustomMarker> ContainerType;
|
|
|
|
typedef std::pair<ContainerType::const_iterator, ContainerType::const_iterator> RangeType;
|
|
|
|
ContainerType::const_iterator begin() const;
|
|
ContainerType::const_iterator end() const;
|
|
|
|
RangeType getMarkers(const ESM::CellId& cellId) const;
|
|
|
|
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
|
EventHandle_Void eventMarkersChanged;
|
|
|
|
private:
|
|
ContainerType mMarkers;
|
|
};
|
|
|
|
class LocalMapBase
|
|
{
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Allow the use of GUIController by declaring it as a friend class
|
|
*/
|
|
friend class mwmp::GUIController;
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
public:
|
|
LocalMapBase(CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled = true);
|
|
virtual ~LocalMapBase();
|
|
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int mapWidgetSize, int cellDistance);
|
|
|
|
void setCellPrefix(const std::string& prefix);
|
|
void setActiveCell(const int x, const int y, bool interior=false);
|
|
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);
|
|
|
|
void onFrame(float dt);
|
|
|
|
bool toggleFogOfWar();
|
|
|
|
struct MarkerUserData
|
|
{
|
|
MarkerUserData(MWRender::LocalMap* map)
|
|
: mLocalMapRender(map)
|
|
, cellX(0)
|
|
, cellY(0)
|
|
, nX(0.f)
|
|
, nY(0.f)
|
|
{
|
|
}
|
|
|
|
bool isPositionExplored() const;
|
|
|
|
MWRender::LocalMap* mLocalMapRender;
|
|
int cellX;
|
|
int cellY;
|
|
float nX;
|
|
float nY;
|
|
std::vector<std::string> notes;
|
|
std::string caption;
|
|
};
|
|
|
|
protected:
|
|
MWRender::LocalMap* mLocalMapRender;
|
|
|
|
int mCurX, mCurY;
|
|
bool mInterior;
|
|
MyGUI::ScrollView* mLocalMap;
|
|
MyGUI::ImageBox* mCompass;
|
|
std::string mPrefix;
|
|
bool mChanged;
|
|
bool mFogOfWarToggled;
|
|
bool mFogOfWarEnabled;
|
|
|
|
int mMapWidgetSize;
|
|
|
|
int mNumCells; // for convenience, mCellDistance * 2 + 1
|
|
int mCellDistance;
|
|
|
|
// Stores markers that were placed by a player. May be shared between multiple map views.
|
|
CustomMarkerCollection& mCustomMarkers;
|
|
|
|
std::vector<MyGUI::ImageBox*> mMapWidgets;
|
|
std::vector<MyGUI::ImageBox*> mFogWidgets;
|
|
|
|
typedef std::vector<std::shared_ptr<MyGUI::ITexture> > TextureVector;
|
|
TextureVector mMapTextures;
|
|
TextureVector mFogTextures;
|
|
|
|
// Keep track of created marker widgets, just to easily remove them later.
|
|
std::vector<MyGUI::Widget*> mDoorMarkerWidgets;
|
|
std::vector<MyGUI::Widget*> mMagicMarkerWidgets;
|
|
std::vector<MyGUI::Widget*> mCustomMarkerWidgets;
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Add a new group of Widgets for player markers
|
|
*/
|
|
std::vector<MyGUI::Widget*> mPlayerMarkerWidgets;
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
virtual void updateCustomMarkers();
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send the LocalMapBase to our GUIController when updating player markers
|
|
*/
|
|
virtual void updatePlayerMarkers();
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
void applyFogOfWar();
|
|
|
|
MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerUserData& markerPos);
|
|
|
|
virtual void notifyPlayerUpdate() {}
|
|
virtual void notifyMapChanged() {}
|
|
|
|
virtual void customMarkerCreated(MyGUI::Widget* marker) {}
|
|
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
|
|
|
|
void updateMagicMarkers();
|
|
void addDetectionMarkers(int type);
|
|
|
|
void redraw();
|
|
|
|
float mMarkerUpdateTimer;
|
|
|
|
float mLastDirectionX;
|
|
float mLastDirectionY;
|
|
|
|
private:
|
|
void updateDoorMarkers();
|
|
bool mNeedDoorMarkersUpdate;
|
|
};
|
|
|
|
class EditNoteDialog : public MWGui::WindowModal
|
|
{
|
|
public:
|
|
EditNoteDialog();
|
|
|
|
virtual void onOpen();
|
|
|
|
void showDeleteButton(bool show);
|
|
bool getDeleteButtonShown();
|
|
void setText(const std::string& text);
|
|
std::string getText();
|
|
|
|
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
|
|
|
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;
|
|
};
|
|
|
|
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop
|
|
{
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Allow the use of GUIController by declaring it as a friend class
|
|
*/
|
|
friend class mwmp::GUIController;
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
public:
|
|
MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue);
|
|
virtual ~MapWindow();
|
|
|
|
void setCellName(const std::string& cellName);
|
|
|
|
virtual void setAlpha(float alpha);
|
|
void setVisible(bool visible);
|
|
|
|
void renderGlobalMap();
|
|
|
|
/// adds the marker to the global map
|
|
/// @param name The ESM::Cell::mName
|
|
void addVisitedLocation(const std::string& name, int x, int y);
|
|
|
|
// reveals this cell's map on the global map
|
|
void cellExplored(int x, int y);
|
|
|
|
void setGlobalMapPlayerPosition (float worldX, float worldY);
|
|
void setGlobalMapPlayerDir(const float x, const float y);
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Allow the setting of the image data for a global map tile from elsewhere
|
|
in the code
|
|
*/
|
|
void setGlobalMapImage(int cellX, int cellY, const std::vector<char>& imageData);
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
void ensureGlobalMapLoaded();
|
|
|
|
virtual void onOpen();
|
|
|
|
void onFrame(float dt);
|
|
|
|
virtual void updateCustomMarkers();
|
|
|
|
/*
|
|
Start of tes3mp addition
|
|
|
|
Send the MapWindow to our GUIController when updating player markers
|
|
*/
|
|
virtual void updatePlayerMarkers();
|
|
/*
|
|
End of tes3mp addition
|
|
*/
|
|
|
|
/// Clear all savegame-specific data
|
|
void clear();
|
|
|
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
|
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
|
|
|
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);
|
|
void onMapDoubleClicked(MyGUI::Widget* sender);
|
|
void onCustomMarkerDoubleClicked(MyGUI::Widget* sender);
|
|
void onNoteEditOk();
|
|
void onNoteEditDelete();
|
|
void onNoteEditDeleteConfirm();
|
|
void onNoteDoubleClicked(MyGUI::Widget* sender);
|
|
void onChangeScrollWindowCoord(MyGUI::Widget* sender);
|
|
void globalMapUpdatePlayer();
|
|
void setGlobalMapMarkerTooltip(MyGUI::Widget* widget, int x, int y);
|
|
|
|
MyGUI::ScrollView* mGlobalMap;
|
|
std::unique_ptr<MyGUI::ITexture> mGlobalMapTexture;
|
|
std::unique_ptr<MyGUI::ITexture> mGlobalMapOverlayTexture;
|
|
MyGUI::ImageBox* mGlobalMapImage;
|
|
MyGUI::ImageBox* mGlobalMapOverlay;
|
|
MyGUI::ImageBox* mPlayerArrowLocal;
|
|
MyGUI::ImageBox* mPlayerArrowGlobal;
|
|
MyGUI::Button* mButton;
|
|
MyGUI::IntPoint mLastDragPos;
|
|
bool mGlobal;
|
|
|
|
MyGUI::IntCoord mLastScrollWindowCoordinates;
|
|
|
|
// Markers on global map
|
|
typedef std::pair<int, int> CellId;
|
|
std::set<CellId> mMarkers;
|
|
|
|
// Cells that should be explored in the next frame (i.e. their map revealed on the global map)
|
|
// We can't do this immediately, because the map update is not immediate either (see mNeedMapUpdate in scene.cpp)
|
|
std::vector<CellId> mQueuedToExplore;
|
|
|
|
MyGUI::Button* mEventBoxGlobal;
|
|
MyGUI::Button* mEventBoxLocal;
|
|
|
|
MWRender::GlobalMap* mGlobalMapRender;
|
|
|
|
std::map<std::pair<int, int>, MyGUI::Widget*> mGlobalMapMarkers;
|
|
|
|
EditNoteDialog mEditNoteDialog;
|
|
ESM::CustomMarker mEditingMarker;
|
|
|
|
virtual void onPinToggled();
|
|
virtual void onTitleDoubleClicked();
|
|
|
|
virtual void doorMarkerCreated(MyGUI::Widget* marker);
|
|
virtual void customMarkerCreated(MyGUI::Widget *marker);
|
|
|
|
virtual void notifyPlayerUpdate();
|
|
|
|
};
|
|
}
|
|
#endif
|