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

Implemented View Earth / View Air spells

This commit is contained in:
Ivan Savenko 2023-02-21 14:38:08 +02:00
parent ec6f19ea18
commit 11e4d84749
24 changed files with 243 additions and 157 deletions

View File

@ -489,7 +489,7 @@ void AIGateway::showMarketWindow(const IMarket * market, const CGHeroInstance *
NET_EVENT_HANDLER;
}
void AIGateway::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions)
void AIGateway::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain)
{
//TODO: AI support for ViewXXX spell
LOG_TRACE(logAi);

View File

@ -165,7 +165,7 @@ public:
void buildChanged(const CGTownInstance * town, BuildingID buildingID, int what) override;
void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override;
void showMarketWindow(const IMarket * market, const CGHeroInstance * visitor) override;
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState) override;
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;

View File

@ -572,7 +572,7 @@ void VCAI::showMarketWindow(const IMarket * market, const CGHeroInstance * visit
NET_EVENT_HANDLER;
}
void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions)
void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain)
{
//TODO: AI support for ViewXXX spell
LOG_TRACE(logAi);

View File

@ -198,7 +198,7 @@ public:
void buildChanged(const CGTownInstance * town, BuildingID buildingID, int what) override;
void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override;
void showMarketWindow(const IMarket * market, const CGHeroInstance * visitor) override;
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
void battleEnd(const BattleResult * br) override;

View File

@ -1829,7 +1829,7 @@ void CPlayerInterface::showPuzzleMap()
void CPlayerInterface::viewWorldMap()
{
adventureInt->changeMode(EAdvMapMode::WORLD_VIEW);
adventureInt->openWorldView();
}
void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellID)
@ -1843,14 +1843,6 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
paths.erasePath(caster);
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
if(spellID == SpellID::VIEW_EARTH)
{
//TODO: implement on server side
const auto level = caster->getSpellSchoolLevel(spell);
adventureInt->worldViewOptions.showAllTerrain = (level > 2);
}
auto castSoundPath = spell->getCastSound();
if(!castSoundPath.empty())
CCS->soundh->playSound(castSoundPath);
@ -2369,14 +2361,10 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
setMovementStatus(false);
}
void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectPositions)
void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
//TODO: showWorldViewEx
std::copy(objectPositions.begin(), objectPositions.end(), std::back_inserter(adventureInt->worldViewOptions.iconPositions));
viewWorldMap();
adventureInt->openWorldView(objectPositions, showTerrain );
}
void CPlayerInterface::updateAmbientSounds(bool resetAll)

View File

@ -210,7 +210,7 @@ public:
void showComp(const Component &comp, std::string message) override; //display component in the advmapint infobox
void saveGame(BinarySerializer & h, const int version) override; //saving
void loadGame(BinaryDeserializer & h, const int version) override; //loading
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
//for battles
void actionFinished(const BattleAction& action) override;//occurs AFTER action taken by active stack or by the hero

View File

@ -883,7 +883,7 @@ void ApplyClientNetPackVisitor::visitAdvmapSpellCast(AdvmapSpellCast & pack)
void ApplyClientNetPackVisitor::visitShowWorldViewEx(ShowWorldViewEx & pack)
{
callOnlyThatInterface(cl, pack.player, &CGameInterface::showWorldViewEx, pack.objectPositions);
callOnlyThatInterface(cl, pack.player, &CGameInterface::showWorldViewEx, pack.objectPositions, pack.showTerrain);
}
void ApplyClientNetPackVisitor::visitOpenWindow(OpenWindow & pack)

View File

@ -236,7 +236,7 @@ CAdvMapInt::CAdvMapInt():
activeMapPanel = panelMain;
changeMode(EAdvMapMode::NORMAL);
exitWorldView();
underground->block(!CGI->mh->getMap()->twoLevel);
questlog->block(!CGI->mh->getMap()->quests.size());
@ -252,7 +252,7 @@ void CAdvMapInt::fshowOverview()
void CAdvMapInt::fworldViewBack()
{
changeMode(EAdvMapMode::NORMAL);
exitWorldView();
auto hero = curHero();
if (hero)
@ -262,17 +262,17 @@ void CAdvMapInt::fworldViewBack()
void CAdvMapInt::fworldViewScale1x()
{
// TODO set corresponding scale button to "selected" mode
changeMode(EAdvMapMode::WORLD_VIEW, 7); // 7 pixels per tile
openWorldView(7);
}
void CAdvMapInt::fworldViewScale2x()
{
changeMode(EAdvMapMode::WORLD_VIEW, 11); // 11 pixels per tile
openWorldView(11);
}
void CAdvMapInt::fworldViewScale4x()
{
changeMode(EAdvMapMode::WORLD_VIEW, 16); // 16 pixels per tile
openWorldView(16);
}
void CAdvMapInt::fswitchLevel()
@ -666,7 +666,7 @@ void CAdvMapInt::centerOn(const CGObjectInstance * obj, bool fade)
void CAdvMapInt::keyReleased(const SDL_Keycode &key)
{
if (mode == EAdvMapMode::WORLD_VIEW)
if (mode != EAdvMapMode::NORMAL)
return;
switch (key)
@ -694,7 +694,7 @@ void CAdvMapInt::keyReleased(const SDL_Keycode &key)
void CAdvMapInt::keyPressed(const SDL_Keycode & key)
{
if (mode == EAdvMapMode::WORLD_VIEW)
if (mode != EAdvMapMode::NORMAL)
return;
const CGHeroInstance *h = curHero(); //selected hero
@ -1460,62 +1460,49 @@ void CAdvMapInt::quickCombatUnlock()
activate();
}
void CAdvMapInt::changeMode(EAdvMapMode newMode)
void CAdvMapInt::exitWorldView()
{
changeMode(newMode, 11);
mode = EAdvMapMode::NORMAL;
panelMain->activate();
panelWorldView->deactivate();
activeMapPanel = panelMain;
townList->activate();
heroList->activate();
infoBar->activate();
redraw();
terrain->setTileSize(32);
terrain->setTerrainVisibility(false);
terrain->setOverlayVisibility({});
}
void CAdvMapInt::changeMode(EAdvMapMode newMode, int tileSize)
void CAdvMapInt::openWorldView(int tileSize)
{
if (mode != newMode)
{
mode = newMode;
mode = EAdvMapMode::WORLD_VIEW;
panelMain->deactivate();
panelWorldView->activate();
switch (mode)
{
case EAdvMapMode::NORMAL:
panelMain->activate();
panelWorldView->deactivate();
activeMapPanel = panelMain;
activeMapPanel = panelWorldView;
townList->activate();
heroList->activate();
infoBar->activate();
townList->deactivate();
heroList->deactivate();
infoBar->showSelection(); // to prevent new day animation interfering world view mode
infoBar->deactivate();
worldViewOptions.clear();
break;
case EAdvMapMode::WORLD_VIEW:
panelMain->deactivate();
panelWorldView->activate();
activeMapPanel = panelWorldView;
townList->deactivate();
heroList->deactivate();
infoBar->showSelection(); // to prevent new day animation interfering world view mode
infoBar->deactivate();
break;
}
redraw();
}
if(mode == EAdvMapMode::NORMAL)
terrain->setTileSize(32);
if(mode == EAdvMapMode::WORLD_VIEW)
terrain->setTileSize(tileSize);
redraw();
terrain->setTileSize(tileSize);
}
CAdvMapInt::WorldViewOptions::WorldViewOptions()
void CAdvMapInt::openWorldView()
{
clear();
openWorldView(11);
}
void CAdvMapInt::WorldViewOptions::clear()
void CAdvMapInt::openWorldView(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain)
{
showAllTerrain = false;
iconPositions.clear();
openWorldView(11);
terrain->setTerrainVisibility(showTerrain);
terrain->setOverlayVisibility(objectPositions);
}

View File

@ -61,21 +61,12 @@ private:
enum EDirections {LEFT=1, RIGHT=2, UP=4, DOWN=8};
enum EGameStates {NA, INGAME, WAITING};
struct WorldViewOptions
{
bool showAllTerrain; //for expert viewEarth
std::vector<ObjectPosInfo> iconPositions;
WorldViewOptions();
void clear();
};
bool swipeEnabled;
bool swipeMovementRequested;
Point swipeTargetPosition;
EGameStates state;
EAdvMapMode mode;
WorldViewOptions worldViewOptions;
/// Currently selected object, can be town, hero or null
const CArmedInstance *selection;
@ -211,9 +202,17 @@ public:
/// returs visible section of game map, in tiles
Rect terrainAreaTiles() const;
/// changes current adventure map mode; used to switch between default view and world view; scale is ignored if EAdvMapMode == NORMAL
void changeMode(EAdvMapMode newMode);
void changeMode(EAdvMapMode newMode, int tileSize);
/// exits currently opened world view mode and returns to normal map
void exitWorldView();
/// opens world view at default scale
void openWorldView();
/// opens world view at specific scale
void openWorldView(int tileSize);
/// opens world view with specific info, e.g. after View Earth/Air is shown
void openWorldView(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain);
};
extern std::shared_ptr<CAdvMapInt> adventureInt;

View File

@ -29,7 +29,7 @@ CAdventureOptions::CAdventureOptions()
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
viewWorld = std::make_shared<CButton>(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, SDLK_v);
viewWorld->addCallback(std::bind(&CPlayerInterface::viewWorldMap, LOCPLINT));
viewWorld->addCallback( [] { LOCPLINT->viewWorldMap(); });
exit = std::make_shared<CButton>(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&CAdventureOptions::close, this), SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE);

View File

@ -240,3 +240,14 @@ void CTerrainRect::setTileSize(int sizePixels)
{
renderer->getController()->setTileSize(Point(sizePixels, sizePixels));
}
void CTerrainRect::setTerrainVisibility(bool showAllTerrain)
{
renderer->getController()->setTerrainVisibility(showAllTerrain);
}
void CTerrainRect::setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions)
{
renderer->getController()->setOverlayVisibility(objectPositions);
}

View File

@ -14,6 +14,7 @@
VCMI_LIB_NAMESPACE_BEGIN
struct CGPath;
struct ObjectPosInfo;
VCMI_LIB_NAMESPACE_END
class MapView;
@ -51,6 +52,9 @@ public:
void setLevel(int level);
void setTileSize(int sizePixels);
void setTerrainVisibility(bool showAllTerrain);
void setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions);
Point getViewCenter();
int getLevel();

View File

@ -53,11 +53,14 @@ public:
virtual Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const = 0;
/// returns object animation transparency. IF set to 0, object will not be visible
virtual double objectTransparency(ObjectInstanceID objectID) const = 0;
virtual double objectTransparency(ObjectInstanceID objectID, const int3 &coordinates) const = 0;
/// returns animation frame for selected object
virtual size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const = 0;
/// returns index of image for overlay on specific tile, or numeric_limits::max if none
virtual size_t overlayImageIndex(const int3 & coordinates) const = 0;
/// returns animation frame for terrain
virtual size_t terrainImageIndex(size_t groupSize) const = 0;

View File

@ -444,7 +444,7 @@ void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas
if(!image)
return;
auto transparency = static_cast<uint8_t>(std::round(255 * context.objectTransparency(object->id)));
auto transparency = static_cast<uint8_t>(std::round(255 * context.objectTransparency(object->id, coordinates)));
if (transparency == 0)
return;
@ -507,7 +507,7 @@ void MapRendererDebug::renderTile(const IMapRendererContext & context, Canvas &
{
const auto * object = context.getObject(objectID);
if (context.objectTransparency(objectID) > 0)
if (context.objectTransparency(objectID, coordinates) > 0)
{
visitable |= object->visitableAt(coordinates.x, coordinates.y);
blockable |= object->blockingAt(coordinates.x, coordinates.y);

View File

@ -66,6 +66,8 @@ const CGObjectInstance * MapRendererContext::getObject(ObjectInstanceID objectID
bool MapRendererContext::isVisible(const int3 & coordinates) const
{
if (showAllTerrain)
return LOCPLINT->cb->isInTheMap(coordinates);
return LOCPLINT->cb->isVisible(coordinates) || settings["session"]["spectate"].Bool();
}
@ -253,11 +255,11 @@ Point MapRendererContext::objectImageOffset(ObjectInstanceID objectID, const int
return Point(offsetTiles) * Point(32, 32);
}
double MapRendererContext::objectTransparency(ObjectInstanceID objectID) const
double MapRendererContext::objectTransparency(ObjectInstanceID objectID, const int3 & coordinates) const
{
const CGObjectInstance * object = getObject(objectID);
if(object && object->ID == Obj::HERO)
if(object->ID == Obj::HERO)
{
const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
@ -268,6 +270,12 @@ double MapRendererContext::objectTransparency(ObjectInstanceID objectID) const
return 0;
}
if(showAllTerrain)
{
if(object->isVisitable() && !LOCPLINT->cb->isVisible(coordinates))
return 0;
}
if(fadeOutAnimation && objectID == fadeOutAnimation->target)
return 1.0 - fadeOutAnimation->progress;
@ -276,3 +284,69 @@ double MapRendererContext::objectTransparency(ObjectInstanceID objectID) const
return 1.0;
}
size_t MapRendererContext::selectOverlayImageForObject(const ObjectPosInfo & object) const
{
size_t ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
if(object.owner.isValidPlayer())
ownerIndex = object.owner.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
switch(object.id)
{
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
case Obj::MONOLITH_ONE_WAY_EXIT:
case Obj::MONOLITH_TWO_WAY:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::TELEPORT);
case Obj::SUBTERRANEAN_GATE:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::GATE);
case Obj::ARTIFACT:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::ARTIFACT);
case Obj::TOWN:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::TOWN);
case Obj::HERO:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::HERO);
case Obj::MINE:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::MINE_WOOD) + object.subId;
case Obj::RESOURCE:
return ownerIndex + static_cast<size_t>(EWorldViewIcon::RES_WOOD) + object.subId;
}
return std::numeric_limits<size_t>::max();
}
size_t MapRendererContext::overlayImageIndex(const int3 & coordinates) const
{
for(const auto & entry : additionalOverlayIcons)
{
if(entry.pos != coordinates)
continue;
size_t iconIndex = selectOverlayImageForObject(entry);
if(iconIndex != std::numeric_limits<size_t>::max())
return iconIndex;
}
if(!isVisible(coordinates))
return std::numeric_limits<size_t>::max();
for(const auto & objectID : getObjects(coordinates))
{
const auto * object = getObject(objectID);
if(!object->visitableAt(coordinates.x, coordinates.y))
continue;
ObjectPosInfo info;
info.pos = coordinates;
info.id = object->ID;
info.subId = object->subID;
info.owner = object->tempOwner;
size_t iconIndex = selectOverlayImageForObject(info);
if(iconIndex != std::numeric_limits<size_t>::max())
return iconIndex;
}
return std::numeric_limits<size_t>::max();
}

View File

@ -14,6 +14,10 @@
#include "../lib/int3.h"
#include "../lib/GameConstants.h"
VCMI_LIB_NAMESPACE_BEGIN
struct ObjectPosInfo;
VCMI_LIB_NAMESPACE_END
class MapObjectsSorter
{
const IMapRendererContext & context;
@ -39,6 +43,33 @@ struct FadingAnimationState
double progress;
};
// from VwSymbol.def
enum class EWorldViewIcon
{
TOWN = 0,
HERO = 1,
ARTIFACT = 2,
TELEPORT = 3,
GATE = 4,
MINE_WOOD = 5,
MINE_MERCURY = 6,
MINE_STONE = 7,
MINE_SULFUR = 8,
MINE_CRYSTAL = 9,
MINE_GEM = 10,
MINE_GOLD = 11,
RES_WOOD = 12,
RES_MERCURY = 13,
RES_STONE = 14,
RES_SULFUR = 15,
RES_CRYSTAL = 16,
RES_GEM = 17,
RES_GOLD = 18,
ICONS_PER_PLAYER = 19,
ICONS_TOTAL = 19 * 9 // 8 players + neutral set at the end
};
class MapRendererContext : public IMapRendererContext
{
friend class MapViewController;
@ -54,7 +85,12 @@ class MapRendererContext : public IMapRendererContext
boost::optional<FadingAnimationState> fadeOutAnimation;
boost::optional<FadingAnimationState> fadeInAnimation;
std::vector<ObjectPosInfo> additionalOverlayIcons;
bool worldViewModeActive = false;
bool showAllTerrain = false;
size_t selectOverlayImageForObject(const ObjectPosInfo & objectID) const;
public:
MapRendererContext();
@ -74,9 +110,10 @@ public:
size_t objectGroupIndex(ObjectInstanceID objectID) const override;
Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const override;
double objectTransparency(ObjectInstanceID objectID) const override;
double objectTransparency(ObjectInstanceID objectID, const int3 &coordinates) const override;
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
size_t terrainImageIndex(size_t groupSize) const override;
size_t overlayImageIndex(const int3 & coordinates) const override;
// Point getTileSize() const override;
bool showOverlay() const override;

View File

@ -26,13 +26,12 @@ MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
: model(model)
, mapRenderer(new MapRenderer())
, iconsStorage(new CAnimation("VwSymbol"))
, intermediate(new Canvas(Point(32,32)))
, intermediate(new Canvas(Point(32, 32)))
, terrain(new Canvas(model->getCacheDimensionsPixels()))
{
iconsStorage->preload();
for (size_t i = 0; i < iconsStorage->size(); ++i)
for(size_t i = 0; i < iconsStorage->size(); ++i)
iconsStorage->getImage(i)->setBlitMode(EImageBlitMode::COLORKEY);
}
Canvas MapViewCache::getTile(const int3 & coordinates)
@ -42,40 +41,10 @@ Canvas MapViewCache::getTile(const int3 & coordinates)
std::shared_ptr<IImage> MapViewCache::getOverlayImageForTile(const std::shared_ptr<MapRendererContext> & context, const int3 & coordinates)
{
if (!context->isVisible(coordinates))
return nullptr;
size_t imageIndex = context->overlayImageIndex(coordinates);
for(const auto & objectID : context->getObjects(coordinates))
{
const auto * object = context->getObject(objectID);
if (!object->visitableAt(coordinates.x, coordinates.y))
continue;
size_t ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
if (object->tempOwner.isValidPlayer())
ownerIndex = object->tempOwner.getNum() * static_cast<size_t>(EWorldViewIcon::ICONS_PER_PLAYER);
switch (object->ID)
{
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
case Obj::MONOLITH_ONE_WAY_EXIT:
case Obj::MONOLITH_TWO_WAY:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::TELEPORT));
case Obj::SUBTERRANEAN_GATE:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::GATE));
case Obj::ARTIFACT:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::ARTIFACT));
case Obj::TOWN:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::TOWN));
case Obj::HERO:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::HERO));
case Obj::MINE:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::MINE_WOOD) + object->subID);
case Obj::RESOURCE:
return iconsStorage->getImage(ownerIndex + static_cast<size_t>(EWorldViewIcon::RES_WOOD) + object->subID);
}
}
if(imageIndex < iconsStorage->size())
return iconsStorage->getImage(imageIndex);
return nullptr;
}
@ -115,9 +84,17 @@ void MapViewCache::render(const std::shared_ptr<MapRendererContext> & context, C
Canvas source = getTile(tile);
Rect targetRect = model->getTargetTileArea(tile);
target.draw(source, targetRect.topLeft());
}
}
if (context->showOverlay())
if (context->showOverlay())
{
for(int y = dimensions.top(); y < dimensions.bottom(); ++y)
{
for(int x = dimensions.left(); x < dimensions.right(); ++x)
{
int3 tile(x, y, model->getLevel());
Rect targetRect = model->getTargetTileArea(tile);
auto overlay = getOverlayImageForTile(context, tile);
if (overlay)

View File

@ -21,33 +21,6 @@ class MapRendererContext;
//class MapViewController;
class MapViewModel;
// from VwSymbol.def
enum class EWorldViewIcon
{
TOWN = 0,
HERO = 1,
ARTIFACT = 2,
TELEPORT = 3,
GATE = 4,
MINE_WOOD = 5,
MINE_MERCURY = 6,
MINE_STONE = 7,
MINE_SULFUR = 8,
MINE_CRYSTAL = 9,
MINE_GEM = 10,
MINE_GOLD = 11,
RES_WOOD = 12,
RES_MERCURY = 13,
RES_STONE = 14,
RES_SULFUR = 15,
RES_CRYSTAL = 16,
RES_GEM = 17,
RES_GOLD = 18,
ICONS_PER_PLAYER = 19,
ICONS_TOTAL = 19 * 9 // 8 players + neutral set at the end
};
/// Class responsible for rendering of entire map view
/// uses rendering parameters provided by owner class
class MapViewCache

View File

@ -17,6 +17,7 @@
#include "../../lib/CConfigHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/MiscObjects.h"
#include "../../lib/spells/ViewSpellInt.h"
void MapViewController::setViewCenter(const int3 & position)
{
@ -185,3 +186,14 @@ bool MapViewController::hasOngoingAnimations()
return false;
}
void MapViewController::setTerrainVisibility(bool showAllTerrain)
{
context->showAllTerrain = showAllTerrain;
}
void MapViewController::setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions)
{
context->additionalOverlayIcons = objectPositions;
}

View File

@ -13,7 +13,9 @@
VCMI_LIB_NAMESPACE_BEGIN
class Point;
struct ObjectPosInfo;
VCMI_LIB_NAMESPACE_END
class MapViewModel;
class MapRendererContext;
@ -42,4 +44,8 @@ public:
void setViewCenter(const Point & position, int level);
void setTileSize(const Point & tileSize);
void update(uint32_t timeDelta);
void setTerrainVisibility(bool showAllTerrain);
void setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions);
};

View File

@ -107,7 +107,7 @@ public:
virtual void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) = 0;
virtual void finish(){}; //if for some reason we want to end
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions){};
virtual void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain){};
virtual boost::optional<BattleAction> makeSurrenderRetreatDecision(const BattleStateInfoForRetreat & battleState)
{

View File

@ -1908,12 +1908,14 @@ protected:
struct DLL_LINKAGE ShowWorldViewEx : public CPackForClient
{
PlayerColor player;
bool showTerrain; // TODO: send terrain state
std::vector<ObjectPosInfo> objectPositions;
template <typename Handler> void serialize(Handler & h, const int version)
{
h & player;
h & showTerrain;
h & objectPositions;
}

View File

@ -585,6 +585,7 @@ ESpellCastResult ViewMechanics::applyAdventureEffects(SpellCastEnvironment * env
pack.objectPositions.push_back(posInfo);
}
}
pack.showTerrain = showTerrain(spellLevel);
env->apply(&pack);
@ -602,6 +603,11 @@ bool ViewAirMechanics::filterObject(const CGObjectInstance * obj, const int32_t
return (obj->ID == Obj::ARTIFACT) || (spellLevel > 1 && obj->ID == Obj::HERO) || (spellLevel > 2 && obj->ID == Obj::TOWN);
}
bool ViewAirMechanics::showTerrain(const int32_t spellLevel) const
{
return false;
}
///ViewEarthMechanics
ViewEarthMechanics::ViewEarthMechanics(const CSpell * s):
ViewMechanics(s)
@ -613,5 +619,9 @@ bool ViewEarthMechanics::filterObject(const CGObjectInstance * obj, const int32_
return (obj->ID == Obj::RESOURCE) || (spellLevel > 1 && obj->ID == Obj::MINE);
}
bool ViewEarthMechanics::showTerrain(const int32_t spellLevel) const
{
return spellLevel > 2;
}
VCMI_LIB_NAMESPACE_END

View File

@ -82,6 +82,7 @@ public:
protected:
ESpellCastResult applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const override;
virtual bool filterObject(const CGObjectInstance * obj, const int32_t spellLevel) const = 0;
virtual bool showTerrain(const int32_t spellLevel) const = 0;
};
class DLL_LINKAGE ViewAirMechanics : public ViewMechanics
@ -90,6 +91,7 @@ public:
ViewAirMechanics(const CSpell * s);
protected:
bool filterObject(const CGObjectInstance * obj, const int32_t spellLevel) const override;
bool showTerrain(const int32_t spellLevel) const override;
};
class DLL_LINKAGE ViewEarthMechanics : public ViewMechanics
@ -98,6 +100,7 @@ public:
ViewEarthMechanics(const CSpell * s);
protected:
bool filterObject(const CGObjectInstance * obj, const int32_t spellLevel) const override;
bool showTerrain(const int32_t spellLevel) const override;
};