1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merge pull request #5117 from IvanSavenko/teleporter_ui

Added new right-click popup to teleporters
This commit is contained in:
Ivan Savenko 2024-12-21 16:17:15 +02:00 committed by GitHub
commit 2272707175
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 121 additions and 10 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

View File

@ -71,16 +71,18 @@ void CMinimapInstance::redrawMinimap()
minimap->drawPoint(Point(x, y), getTileColor(int3(x, y, level)));
}
CMinimapInstance::CMinimapInstance(CMinimap *Parent, int Level):
parent(Parent),
CMinimapInstance::CMinimapInstance(const Point & position, const Point & dimensions, int Level):
minimap(new Canvas(Point(LOCPLINT->cb->getMapSize().x, LOCPLINT->cb->getMapSize().y), CanvasScalingPolicy::IGNORE)),
level(Level)
{
pos.w = parent->pos.w;
pos.h = parent->pos.h;
pos += position;
pos.w = dimensions.x;
pos.h = dimensions.y;
redrawMinimap();
}
CMinimapInstance::~CMinimapInstance() = default;
void CMinimapInstance::showAll(Canvas & to)
{
to.drawScaled(*minimap, pos.topLeft(), pos.dimensions());
@ -203,7 +205,7 @@ void CMinimap::update()
return;
OBJECT_CONSTRUCTION;
minimap = std::make_shared<CMinimapInstance>(this, level);
minimap = std::make_shared<CMinimapInstance>(Point(0,0), pos.dimensions(), level);
redraw();
}

View File

@ -20,7 +20,6 @@ class CMinimap;
class CMinimapInstance : public CIntObject
{
CMinimap * parent;
std::unique_ptr<Canvas> minimap;
int level;
@ -29,7 +28,8 @@ class CMinimapInstance : public CIntObject
void redrawMinimap();
public:
CMinimapInstance(CMinimap * parent, int level);
CMinimapInstance(const Point & position, const Point & dimensions, int level);
~CMinimapInstance();
void showAll(Canvas & to) override;
void refreshTile(const int3 & pos);

View File

@ -15,12 +15,14 @@
#include "../PlayerLocalState.h"
#include "../adventureMap/AdventureMapInterface.h"
#include "../adventureMap/CMinimap.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../gui/Shortcut.h"
#include "../gui/WindowHandler.h"
#include "../widgets/Buttons.h"
#include "../widgets/CComponent.h"
#include "../widgets/GraphicalPrimitiveCanvas.h"
#include "../widgets/Images.h"
#include "../widgets/MiscWidgets.h"
#include "../widgets/TextControls.h"
@ -331,6 +333,83 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGCreature * creature)
fitToScreen(10);
}
TeleporterPopup::TeleporterPopup(const Point & position, const CGTeleport * teleporter)
: CWindowObject(BORDERED | RCLICK_POPUP)
{
OBJECT_CONSTRUCTION;
pos.w = 322;
pos.h = 200;
Rect areaSurface(11, 41, 144, 144);
Rect areaUnderground(167, 41, 144, 144);
Rect borderSurface(10, 40, 147, 147);
Rect borderUnderground(166, 40, 147, 147);
bool singleLevelMap = LOCPLINT->cb->getMapSize().y == 0;
if (singleLevelMap)
{
areaSurface.x += 144;
borderSurface.x += 144;
}
filledBackground = std::make_shared<FilledTexturePlayerColored>(Rect(0, 0, pos.w, pos.h));
backgroundSurface = std::make_shared<TransparentFilledRectangle>(borderSurface, Colors::TRANSPARENCY, Colors::YELLOW);
surface = std::make_shared<CMinimapInstance>(areaSurface.topLeft(), areaSurface.dimensions(), 0);
if (!singleLevelMap)
{
backgroundUnderground = std::make_shared<TransparentFilledRectangle>(borderUnderground, Colors::TRANSPARENCY, Colors::YELLOW);
undergroud = std::make_shared<CMinimapInstance>(areaUnderground.topLeft(), areaUnderground.dimensions(), 1);
}
labelTitle = std::make_shared<CLabel>(pos.w / 2, 20, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, teleporter->getPopupText(LOCPLINT->playerID));
const auto & entrances = teleporter->getAllEntrances();
const auto & exits = teleporter->getAllExits();
std::set<ObjectInstanceID> allTeleporters;
allTeleporters.insert(entrances.begin(), entrances.end());
allTeleporters.insert(exits.begin(), exits.end());
for (const auto exit : allTeleporters)
{
const auto * exitObject = LOCPLINT->cb->getObj(exit, false);
if (!exitObject)
continue;
int3 position = exitObject->visitablePos();
int positionX = 144 * position.x / LOCPLINT->cb->getMapSize().x;
int positionY = 144 * position.y / LOCPLINT->cb->getMapSize().y;
Point iconPosition(positionX, positionY);
iconPosition -= Point(8,8); // compensate for 16x16 icon half-size
if (position.z == 0)
iconPosition += areaSurface.topLeft();
else
iconPosition += areaUnderground.topLeft();
ImagePath image;
if (!vstd::contains(entrances, exit))
image = ImagePath::builtin("portalExit");
else if (!vstd::contains(exits, exit))
image = ImagePath::builtin("portalEntrance");
else
image = ImagePath::builtin("portalBidirectional");
iconsOverlay.push_back(std::make_shared<CPicture>(image, iconPosition));
}
center(position);
}
std::shared_ptr<WindowBase>
CRClickPopup::createCustomInfoWindow(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
{
@ -354,6 +433,12 @@ CRClickPopup::createCustomInfoWindow(Point position, const CGObjectInstance * sp
case Obj::GARRISON:
case Obj::GARRISON2:
return std::make_shared<CInfoBoxPopup>(position, dynamic_cast<const CGGarrison *>(specific));
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
case Obj::MONOLITH_ONE_WAY_EXIT:
case Obj::MONOLITH_TWO_WAY:
case Obj::SUBTERRANEAN_GATE:
case Obj::WHIRLPOOL:
return std::make_shared<TeleporterPopup>(position, dynamic_cast<const CGTeleport *>(specific));
default:
return std::shared_ptr<WindowBase>();
}

View File

@ -20,6 +20,7 @@ class CGTownInstance;
class CGHeroInstance;
class CGGarrison;
class CGCreature;
class CGTeleport;
VCMI_LIB_NAMESPACE_END
@ -29,6 +30,10 @@ class CSelectableComponent;
class CTextBox;
class CButton;
class CFilledTexture;
class FilledTexturePlayerColored;
class TransparentFilledRectangle;
class CMinimapInstance;
class CLabel;
/// text + comp. + ok button
class CInfoWindow : public WindowBase
@ -110,3 +115,21 @@ public:
void madeChoiceAndClose();
CSelWindow(const std::string & text, PlayerColor player, int charperline, const std::vector<std::shared_ptr<CSelectableComponent>> & comps, const std::vector<std::pair<AnimationPath,CFunctionList<void()> > > &Buttons, QueryID askID);
};
class TeleporterPopup : public CWindowObject
{
std::shared_ptr<FilledTexturePlayerColored> filledBackground;
std::shared_ptr<TransparentFilledRectangle> backgroundSurface;
std::shared_ptr<TransparentFilledRectangle> backgroundUnderground;
std::shared_ptr<CMinimapInstance> surface;
std::shared_ptr<CMinimapInstance> undergroud;
std::shared_ptr<CLabel> labelTitle;
std::vector<std::shared_ptr<CPicture>> iconsOverlay;
public:
TeleporterPopup(const Point & position, const CGTeleport * teleporter);
};

View File

@ -215,14 +215,12 @@ class DLL_LINKAGE CGTeleport : public CGObjectInstance
bool isChannelEntrance(const ObjectInstanceID & id) const;
bool isChannelExit(const ObjectInstanceID & id) const;
std::vector<ObjectInstanceID> getAllEntrances(bool excludeCurrent = false) const;
protected:
enum EType {UNKNOWN, ENTRANCE, EXIT, BOTH};
EType type = EType::UNKNOWN;
ObjectInstanceID getRandomExit(const CGHeroInstance * h) const;
std::vector<ObjectInstanceID> getAllExits(bool excludeCurrent = false) const;
public:
using CGObjectInstance::CGObjectInstance;
@ -232,6 +230,9 @@ public:
bool isEntrance() const;
bool isExit() const;
std::vector<ObjectInstanceID> getAllEntrances(bool excludeCurrent = false) const;
std::vector<ObjectInstanceID> getAllExits(bool excludeCurrent = false) const;
virtual void teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer, TTeleportExitsList exits) const = 0;
static bool isTeleport(const CGObjectInstance * dst);