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:
parent
ec6f19ea18
commit
11e4d84749
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user