diff --git a/ChangeLog.md b/ChangeLog.md index 11e9942eb..3845f9ed2 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,7 @@ # 1.2.0 -> 1.2.1 ### GENERAL: +* Implemented spell range overlay for Dimension Door and Scuttle Boat * Fixed movement cost penalty from terrain * Fixed empty Black Market on game start * Fixed bad morale happening after waiting diff --git a/Mods/vcmi/Data/debug/cached.png b/Mods/vcmi/Data/debug/cached.png deleted file mode 100644 index 7f7dbefae..000000000 Binary files a/Mods/vcmi/Data/debug/cached.png and /dev/null differ diff --git a/Mods/vcmi/Data/debug/spellRange.png b/Mods/vcmi/Data/debug/spellRange.png new file mode 100644 index 000000000..4618c58c0 Binary files /dev/null and b/Mods/vcmi/Data/debug/spellRange.png differ diff --git a/client/adventureMap/CAdvMapInt.cpp b/client/adventureMap/CAdvMapInt.cpp index e9f1d7b4a..b1f2ca435 100644 --- a/client/adventureMap/CAdvMapInt.cpp +++ b/client/adventureMap/CAdvMapInt.cpp @@ -1076,8 +1076,11 @@ void CAdvMapInt::onTileLeftClicked(const int3 &mapPos) const CGObjectInstance *topBlocking = getActiveObject(mapPos); int3 selPos = selection->getSightCenter(); - if(spellBeingCasted && isInScreenRange(selPos, mapPos)) + if(spellBeingCasted) { + if (!isInScreenRange(selPos, mapPos)) + return; + const TerrainTile *heroTile = LOCPLINT->cb->getTile(selPos); switch(spellBeingCasted->id) @@ -1179,11 +1182,15 @@ void CAdvMapInt::onTileHovered(const int3 &mapPos) switch(spellBeingCasted->id) { case SpellID::SCUTTLE_BOAT: - if(objAtTile && objAtTile->ID == Obj::BOAT) + { + int3 hpos = selection->getSightCenter(); + + if(objAtTile && objAtTile->ID == Obj::BOAT && isInScreenRange(hpos, mapPos)) CCS->curh->set(Cursor::Map::SCUTTLE_BOAT); else CCS->curh->set(Cursor::Map::POINTER); return; + } case SpellID::DIMENSION_DOOR: { const TerrainTile * t = LOCPLINT->cb->getTile(mapPos, false); @@ -1342,6 +1349,8 @@ void CAdvMapInt::enterCastingMode(const CSpell * sp) { assert(sp->id == SpellID::SCUTTLE_BOAT || sp->id == SpellID::DIMENSION_DOOR); spellBeingCasted = sp; + Settings config = settings.write["session"]["showSpellRange"]; + config->Bool() = true; deactivate(); terrain->activate(); @@ -1356,6 +1365,9 @@ void CAdvMapInt::leaveCastingMode(bool cast, int3 dest) terrain->deactivate(); activate(); + Settings config = settings.write["session"]["showSpellRange"]; + config->Bool() = false; + if(cast) LOCPLINT->cb->castSpell(curHero(), id, dest); else diff --git a/client/mapView/IMapRendererContext.h b/client/mapView/IMapRendererContext.h index 4f5cf7917..049204c08 100644 --- a/client/mapView/IMapRendererContext.h +++ b/client/mapView/IMapRendererContext.h @@ -86,4 +86,8 @@ public: virtual bool showGrid() const = 0; virtual bool showVisitable() const = 0; virtual bool showBlocked() const = 0; + + /// if true, spell range for teleport / scuttle boat will be visible + virtual bool showSpellRange(const int3 & position) const = 0; + }; diff --git a/client/mapView/MapRenderer.cpp b/client/mapView/MapRenderer.cpp index 86d67dcff..9b89e4937 100644 --- a/client/mapView/MapRenderer.cpp +++ b/client/mapView/MapRenderer.cpp @@ -584,15 +584,16 @@ uint8_t MapRendererObjects::checksum(IMapRendererContext & context, const int3 & return 0xff-1; } -MapRendererDebug::MapRendererDebug() +MapRendererOverlay::MapRendererOverlay() : imageGrid(IImage::createFromFile("debug/grid", EImageBlitMode::ALPHA)) , imageBlocked(IImage::createFromFile("debug/blocked", EImageBlitMode::ALPHA)) , imageVisitable(IImage::createFromFile("debug/visitable", EImageBlitMode::ALPHA)) + , imageSpellRange(IImage::createFromFile("debug/spellRange", EImageBlitMode::ALPHA)) { } -void MapRendererDebug::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates) +void MapRendererOverlay::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates) { if(context.showGrid()) target.draw(imageGrid, Point(0,0)); @@ -618,9 +619,12 @@ void MapRendererDebug::renderTile(IMapRendererContext & context, Canvas & target if (context.showVisitable() && visitable) target.draw(imageVisitable, Point(0,0)); } + + if (context.showSpellRange(coordinates)) + target.draw(imageSpellRange, Point(0,0)); } -uint8_t MapRendererDebug::checksum(IMapRendererContext & context, const int3 & coordinates) +uint8_t MapRendererOverlay::checksum(IMapRendererContext & context, const int3 & coordinates) { uint8_t result = 0; @@ -633,6 +637,9 @@ uint8_t MapRendererDebug::checksum(IMapRendererContext & context, const int3 & c if (context.showGrid()) result += 4; + if (context.showSpellRange(coordinates)) + result += 8; + return result; } @@ -766,7 +773,7 @@ MapRenderer::TileChecksum MapRenderer::getTileChecksum(IMapRendererContext & con result[3] = rendererRoad.checksum(context, coordinates); result[4] = rendererObjects.checksum(context, coordinates); result[5] = rendererPath.checksum(context, coordinates); - result[6] = rendererDebug.checksum(context, coordinates); + result[6] = rendererOverlay.checksum(context, coordinates); if(!context.isVisible(coordinates)) result[7] = rendererFow.checksum(context, coordinates); @@ -800,7 +807,7 @@ void MapRenderer::renderTile(IMapRendererContext & context, Canvas & target, con rendererObjects.renderTile(context, target, coordinates); rendererPath.renderTile(context, target, coordinates); - rendererDebug.renderTile(context, target, coordinates); + rendererOverlay.renderTile(context, target, coordinates); if(!context.isVisible(coordinates)) rendererFow.renderTile(context, target, coordinates); diff --git a/client/mapView/MapRenderer.h b/client/mapView/MapRenderer.h index c1fb78d86..2ee036f88 100644 --- a/client/mapView/MapRenderer.h +++ b/client/mapView/MapRenderer.h @@ -129,21 +129,12 @@ public: void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates); }; -class MapRendererDebug +class MapRendererOverlay { std::shared_ptr imageGrid; std::shared_ptr imageVisitable; std::shared_ptr imageBlocked; -public: - MapRendererDebug(); - - uint8_t checksum(IMapRendererContext & context, const int3 & coordinates); - void renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates); -}; - -class MapRendererOverlay -{ - std::unique_ptr iconsStorage; + std::shared_ptr imageSpellRange; public: MapRendererOverlay(); @@ -160,7 +151,7 @@ class MapRenderer MapRendererFow rendererFow; MapRendererObjects rendererObjects; MapRendererPath rendererPath; - MapRendererDebug rendererDebug; + MapRendererOverlay rendererOverlay; public: using TileChecksum = std::array; diff --git a/client/mapView/MapRendererContext.cpp b/client/mapView/MapRendererContext.cpp index 4e3c95d5b..d885b02f6 100644 --- a/client/mapView/MapRendererContext.cpp +++ b/client/mapView/MapRendererContext.cpp @@ -22,6 +22,7 @@ #include "../../lib/CPathfinder.h" #include "../../lib/Point.h" #include "../../lib/mapObjects/CGHeroInstance.h" +#include "../../lib/spells/CSpellHandler.h" #include "../../lib/mapping/CMap.h" MapRendererBaseContext::MapRendererBaseContext(const MapRendererContextState & viewState) @@ -199,6 +200,11 @@ bool MapRendererBaseContext::showBlocked() const return false; } +bool MapRendererBaseContext::showSpellRange(const int3 & position) const +{ + return false; +} + MapRendererAdventureContext::MapRendererAdventureContext(const MapRendererContextState & viewState) : MapRendererBaseContext(viewState) { @@ -266,6 +272,16 @@ bool MapRendererAdventureContext::showBlocked() const return settingShowBlocked; } +bool MapRendererAdventureContext::showSpellRange(const int3 & position) const +{ + if (!settingSpellRange) + return false; + + auto hero = adventureInt->curHero(); + + return !isInScreenRange(hero->getSightCenter(), position); +} + MapRendererAdventureTransitionContext::MapRendererAdventureTransitionContext(const MapRendererContextState & viewState) : MapRendererAdventureContext(viewState) { diff --git a/client/mapView/MapRendererContext.h b/client/mapView/MapRendererContext.h index 0a299fbac..ee8061535 100644 --- a/client/mapView/MapRendererContext.h +++ b/client/mapView/MapRendererContext.h @@ -58,6 +58,7 @@ public: bool showGrid() const override; bool showVisitable() const override; bool showBlocked() const override; + bool showSpellRange(const int3 & position) const override; }; class MapRendererAdventureContext : public MapRendererBaseContext @@ -67,6 +68,7 @@ public: bool settingShowGrid = false; bool settingShowVisitable = false; bool settingShowBlocked = false; + bool settingSpellRange= false; bool settingsAdventureObjectAnimation = true; bool settingsAdventureTerrainAnimation = true; @@ -80,6 +82,8 @@ public: bool showGrid() const override; bool showVisitable() const override; bool showBlocked() const override; + + bool showSpellRange(const int3 & position) const override; }; class MapRendererAdventureTransitionContext : public MapRendererAdventureContext diff --git a/client/mapView/MapViewController.cpp b/client/mapView/MapViewController.cpp index 2f0fd06bd..ced9e1d80 100644 --- a/client/mapView/MapViewController.cpp +++ b/client/mapView/MapViewController.cpp @@ -154,6 +154,7 @@ void MapViewController::updateBefore(uint32_t timeDelta) adventureContext->settingShowGrid = settings["gameTweaks"]["showGrid"].Bool(); adventureContext->settingShowVisitable = settings["session"]["showVisitable"].Bool(); adventureContext->settingShowBlocked = settings["session"]["showBlocked"].Bool(); + adventureContext->settingSpellRange = settings["session"]["showSpellRange"].Bool(); } }