2023-02-20 22:16:50 +02:00
|
|
|
/*
|
|
|
|
* MapViewController.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "StdInc.h"
|
|
|
|
#include "MapViewController.h"
|
|
|
|
|
|
|
|
#include "MapRendererContext.h"
|
2023-02-26 18:17:53 +02:00
|
|
|
#include "MapRendererContextState.h"
|
2023-02-20 22:16:50 +02:00
|
|
|
#include "MapViewModel.h"
|
2023-02-26 18:17:53 +02:00
|
|
|
#include "MapViewCache.h"
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-22 22:06:27 +02:00
|
|
|
#include "../adventureMap/CAdvMapInt.h"
|
2023-02-26 18:17:53 +02:00
|
|
|
#include "../CPlayerInterface.h"
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-20 22:16:50 +02:00
|
|
|
#include "../../lib/CConfigHandler.h"
|
|
|
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
|
|
|
#include "../../lib/mapObjects/MiscObjects.h"
|
2023-02-21 14:38:08 +02:00
|
|
|
#include "../../lib/spells/ViewSpellInt.h"
|
2023-02-26 18:17:53 +02:00
|
|
|
#include "../../lib/CPathfinder.h"
|
2023-02-20 22:16:50 +02:00
|
|
|
|
|
|
|
void MapViewController::setViewCenter(const int3 & position)
|
|
|
|
{
|
|
|
|
assert(context->isInMap(position));
|
2023-02-23 19:46:41 +02:00
|
|
|
setViewCenter(Point(position) * model->getSingleTileSize() + model->getSingleTileSize() / 2, position.z);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::setViewCenter(const Point & position, int level)
|
|
|
|
{
|
2023-02-23 19:46:41 +02:00
|
|
|
Point upperLimit = Point(context->getMapSize()) * model->getSingleTileSize() + model->getSingleTileSize();
|
|
|
|
Point lowerLimit = Point(0,0);
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (worldViewContext)
|
2023-02-23 19:46:41 +02:00
|
|
|
{
|
|
|
|
Point area = model->getPixelsVisibleDimensions();
|
|
|
|
Point mapCenter = upperLimit / 2;
|
|
|
|
|
|
|
|
Point desiredLowerLimit = lowerLimit + area / 2;
|
|
|
|
Point desiredUpperLimit = upperLimit - area / 2;
|
|
|
|
|
|
|
|
Point actualLowerLimit {
|
|
|
|
std::min(desiredLowerLimit.x, mapCenter.x),
|
|
|
|
std::min(desiredLowerLimit.y, mapCenter.y)
|
|
|
|
};
|
|
|
|
|
|
|
|
Point actualUpperLimit {
|
|
|
|
std::max(desiredUpperLimit.x, mapCenter.x),
|
|
|
|
std::max(desiredUpperLimit.y, mapCenter.y)
|
|
|
|
};
|
|
|
|
|
|
|
|
upperLimit = actualUpperLimit;
|
|
|
|
lowerLimit = actualLowerLimit;
|
|
|
|
}
|
|
|
|
|
2023-02-20 22:16:50 +02:00
|
|
|
Point betterPosition = {
|
2023-02-23 19:46:41 +02:00
|
|
|
vstd::clamp(position.x, lowerLimit.x, upperLimit.x),
|
|
|
|
vstd::clamp(position.y, lowerLimit.y, upperLimit.y)
|
2023-02-20 22:16:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
model->setViewCenter(betterPosition);
|
|
|
|
model->setLevel(vstd::clamp(level, 0, context->getMapSize().z));
|
2023-02-23 19:46:41 +02:00
|
|
|
|
|
|
|
if (adventureInt) // may be called before adventureInt is initialized
|
|
|
|
adventureInt->onMapViewMoved(model->getTilesTotalRect(), model->getLevel());
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::setTileSize(const Point & tileSize)
|
|
|
|
{
|
|
|
|
model->setTileSize(tileSize);
|
2023-02-23 19:46:41 +02:00
|
|
|
|
|
|
|
// force update of view center since changing tile size may invalidated it
|
|
|
|
setViewCenter(model->getMapViewCenter(), model->getLevel());
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
MapViewController::MapViewController(std::shared_ptr<MapViewModel> model, std::shared_ptr<MapViewCache> view)
|
|
|
|
: state(new MapRendererContextState())
|
2023-02-20 22:16:50 +02:00
|
|
|
, model(std::move(model))
|
2023-02-26 18:17:53 +02:00
|
|
|
, view(view)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
adventureContext = std::make_shared<MapRendererAdventureContext>(*state);
|
|
|
|
context = adventureContext;
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
2023-02-23 19:46:41 +02:00
|
|
|
std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
|
2023-02-21 19:21:50 +02:00
|
|
|
{
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2023-02-20 22:16:50 +02:00
|
|
|
void MapViewController::update(uint32_t timeDelta)
|
|
|
|
{
|
|
|
|
// confirmed to match H3 for
|
|
|
|
// - hero embarking on boat (500 ms)
|
|
|
|
// - hero disembarking from boat (500 ms)
|
|
|
|
// - TODO: picking up resources
|
|
|
|
// - TODO: killing mosters
|
|
|
|
// - teleporting ( 250 ms)
|
|
|
|
static const double fadeOutDuration = 500;
|
|
|
|
static const double fadeInDuration = 500;
|
2023-02-26 18:17:53 +02:00
|
|
|
//static const double heroTeleportDuration = 250;
|
2023-02-20 22:16:50 +02:00
|
|
|
|
|
|
|
//FIXME: remove code duplication?
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if(movementContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
const auto * object = context->getObject(movementContext->target);
|
2023-02-22 22:06:27 +02:00
|
|
|
const auto * hero = dynamic_cast<const CGHeroInstance*>(object);
|
|
|
|
const auto * boat = dynamic_cast<const CGBoat*>(object);
|
|
|
|
|
|
|
|
assert(boat || hero);
|
|
|
|
|
|
|
|
if (!hero)
|
|
|
|
hero = boat->hero;
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
double heroMoveTime =
|
|
|
|
LOCPLINT->makingTurn ?
|
|
|
|
settings["adventure"]["heroMoveTime"].Float():
|
|
|
|
settings["adventure"]["enemyMoveTime"].Float();
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
movementContext->progress += timeDelta / heroMoveTime;
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
Point positionFrom = Point(hero->convertToVisitablePos(movementContext->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
|
|
|
|
Point positionDest = Point(hero->convertToVisitablePos(movementContext->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
Point positionCurr = vstd::lerp(positionFrom, positionDest, movementContext->progress);
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if(movementContext->progress >= 1.0)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-22 22:06:27 +02:00
|
|
|
setViewCenter(hero->getSightCenter());
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
removeObject(context->getObject(movementContext->target));
|
|
|
|
addObject(context->getObject(movementContext->target));
|
|
|
|
|
|
|
|
activateAdventureContext(movementContext->animationTime);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
2023-02-23 19:46:41 +02:00
|
|
|
else
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
setViewCenter(positionCurr, movementContext->tileDest.z);
|
2023-02-23 19:46:41 +02:00
|
|
|
}
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
//if(teleportContext)
|
|
|
|
//{
|
|
|
|
// teleportContext->progress += timeDelta / heroTeleportDuration;
|
|
|
|
// moveFocusToSelection();
|
|
|
|
// if(teleportContext->progress >= 1.0)
|
|
|
|
// teleportContext.reset();
|
|
|
|
//}
|
|
|
|
|
|
|
|
if(fadingOutContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
fadingOutContext->progress -= timeDelta / fadeOutDuration;
|
|
|
|
|
|
|
|
if(fadingOutContext->progress <= 0.0)
|
|
|
|
{
|
|
|
|
removeObject(context->getObject(fadingOutContext->target));
|
|
|
|
|
|
|
|
activateAdventureContext(fadingOutContext->animationTime);
|
|
|
|
}
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if(fadingInContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
fadingInContext->progress += timeDelta / fadeInDuration;
|
|
|
|
|
|
|
|
if(fadingInContext->progress >= 1.0)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
activateAdventureContext(fadingInContext->animationTime);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (adventureContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
adventureContext->animationTime += timeDelta;
|
|
|
|
adventureContext->settingsSessionSpectate = settings["session"]["spectate"].Bool();
|
|
|
|
adventureContext->settingsAdventureObjectAnimation = settings["adventure"]["objectAnimation"].Bool();
|
|
|
|
adventureContext->settingsAdventureTerrainAnimation = settings["adventure"]["terrainAnimation"].Bool();
|
|
|
|
adventureContext->settingShowGrid = settings["gameTweaks"]["showGrid"].Bool();
|
|
|
|
adventureContext->settingShowVisitable = settings["session"]["showVisitable"].Bool();
|
|
|
|
adventureContext->settingShowBlockable = settings["session"]["showBlockable"].Bool();
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
2023-02-26 18:17:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MapViewController::isEventVisible(const CGObjectInstance * obj)
|
|
|
|
{
|
|
|
|
if (adventureContext == nullptr)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!LOCPLINT->makingTurn && settings["adventure"]["enemyMoveTime"].Float() < 0)
|
|
|
|
return false; // enemy move speed set to "hidden/none"
|
|
|
|
|
|
|
|
if (obj->isVisitable())
|
|
|
|
return context->isVisible(obj->visitablePos());
|
|
|
|
else
|
|
|
|
return context->isVisible(obj->pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MapViewController::isEventVisible(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
if (adventureContext == nullptr)
|
|
|
|
return false;
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (!LOCPLINT->makingTurn && settings["adventure"]["enemyMoveTime"].Float() < 0)
|
|
|
|
return false; // enemy move speed set to "hidden/none"
|
2023-02-22 13:14:11 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (context->isVisible(obj->convertToVisitablePos(from)))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (context->isVisible(obj->convertToVisitablePos(dest)))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::fadeOutObject(const CGObjectInstance * obj)
|
|
|
|
{
|
|
|
|
fadingOutContext = std::make_shared<MapRendererAdventureFadingContext>(*state);
|
|
|
|
fadingOutContext->animationTime = adventureContext->animationTime;
|
|
|
|
adventureContext = fadingOutContext;
|
|
|
|
context = fadingOutContext;
|
|
|
|
|
|
|
|
fadingOutContext->target = obj->id;
|
|
|
|
fadingOutContext->progress = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::fadeInObject(const CGObjectInstance * obj)
|
|
|
|
{
|
|
|
|
fadingInContext = std::make_shared<MapRendererAdventureFadingContext>(*state);
|
|
|
|
fadingInContext->animationTime = adventureContext->animationTime;
|
|
|
|
adventureContext = fadingInContext;
|
|
|
|
context = fadingInContext;
|
|
|
|
|
|
|
|
fadingInContext->target = obj->id;
|
|
|
|
fadingInContext->progress = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::removeObject(const CGObjectInstance * obj)
|
|
|
|
{
|
|
|
|
view->invalidate(context, obj->id);
|
|
|
|
state->removeObject(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::addObject(const CGObjectInstance * obj)
|
|
|
|
{
|
|
|
|
state->addObject(obj);
|
|
|
|
view->invalidate(context, obj->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onBeforeHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
if (isEventVisible(obj, from, dest))
|
|
|
|
{
|
|
|
|
onObjectFadeOut(obj);
|
|
|
|
setViewCenter(obj->getSightCenter());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
removeObject(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onAfterHeroEmbark(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
if (isEventVisible(obj, from, dest))
|
|
|
|
setViewCenter(obj->getSightCenter());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onBeforeHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
if (isEventVisible(obj, from, dest))
|
|
|
|
setViewCenter(obj->getSightCenter());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onAfterHeroDisembark(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
if (isEventVisible(obj, from, dest))
|
|
|
|
{
|
|
|
|
onObjectFadeIn(obj);
|
|
|
|
setViewCenter(obj->getSightCenter());
|
|
|
|
}
|
|
|
|
addObject(obj);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onObjectFadeIn(const CGObjectInstance * obj)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(!hasOngoingAnimations());
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (isEventVisible(obj))
|
|
|
|
fadeInObject(obj);
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
addObject(obj);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onObjectFadeOut(const CGObjectInstance * obj)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(!hasOngoingAnimations());
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (isEventVisible(obj))
|
|
|
|
fadeOutObject(obj);
|
2023-02-22 22:06:27 +02:00
|
|
|
else
|
2023-02-26 18:17:53 +02:00
|
|
|
removeObject(obj);
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onObjectInstantAdd(const CGObjectInstance * obj)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
addObject(obj);
|
2023-02-20 22:16:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
void MapViewController::onObjectInstantRemove(const CGObjectInstance * obj)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
removeObject(obj);
|
2023-02-20 22:16:50 +02:00
|
|
|
};
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
void MapViewController::onBeforeHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(!hasOngoingAnimations());
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (isEventVisible(obj, from, dest))
|
2023-02-22 22:06:27 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
// TODO: generate view with old state
|
|
|
|
setViewCenter(obj->getSightCenter());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onAfterHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
|
|
|
assert(!hasOngoingAnimations());
|
|
|
|
|
|
|
|
if (isEventVisible(obj, from, dest))
|
|
|
|
{
|
|
|
|
// TODO: animation
|
|
|
|
setViewCenter(obj->getSightCenter());
|
2023-02-22 22:06:27 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
removeObject(obj);
|
|
|
|
addObject(obj);
|
2023-02-22 22:06:27 +02:00
|
|
|
}
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(!hasOngoingAnimations());
|
2023-02-20 22:16:50 +02:00
|
|
|
|
|
|
|
const CGObjectInstance * movingObject = obj;
|
|
|
|
if(obj->boat)
|
|
|
|
movingObject = obj->boat;
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
removeObject(movingObject);
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if (!isEventVisible(obj, from, dest))
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
addObject(movingObject);
|
|
|
|
return;
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
2023-02-26 18:17:53 +02:00
|
|
|
|
|
|
|
double movementTime =
|
|
|
|
LOCPLINT->playerID == obj->tempOwner ?
|
|
|
|
settings["adventure"]["heroMoveTime"].Float():
|
|
|
|
settings["adventure"]["enemyMoveTime"].Float();
|
|
|
|
|
|
|
|
if(movementTime > 1)
|
2023-02-20 22:16:50 +02:00
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
movementContext = std::make_shared<MapRendererAdventureMovingContext>(*state);
|
|
|
|
movementContext->animationTime = adventureContext->animationTime;
|
|
|
|
adventureContext = movementContext;
|
|
|
|
context = movementContext;
|
2023-02-22 22:06:27 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
state->addMovingObject(movingObject, from, dest);
|
2023-02-20 22:16:50 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
movementContext->target = movingObject->id;
|
|
|
|
movementContext->tileFrom = from;
|
|
|
|
movementContext->tileDest = dest;
|
|
|
|
movementContext->progress = 0.0;
|
|
|
|
}
|
|
|
|
else // instant movement
|
|
|
|
{
|
|
|
|
addObject(movingObject);
|
|
|
|
setViewCenter(movingObject->visitablePos());
|
|
|
|
}
|
2023-02-20 22:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MapViewController::hasOngoingAnimations()
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
if(movementContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
return true;
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if(fadingOutContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
return true;
|
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
if(fadingInContext)
|
2023-02-20 22:16:50 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2023-02-21 14:38:08 +02:00
|
|
|
|
2023-02-26 18:17:53 +02:00
|
|
|
void MapViewController::activateAdventureContext(uint32_t animationTime)
|
|
|
|
{
|
|
|
|
resetContext();
|
|
|
|
|
|
|
|
adventureContext = std::make_shared<MapRendererAdventureContext>(*state);
|
|
|
|
adventureContext->animationTime = animationTime;
|
|
|
|
context = adventureContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::activateAdventureContext()
|
|
|
|
{
|
|
|
|
activateAdventureContext(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::activateWorldViewContext()
|
|
|
|
{
|
|
|
|
if (worldViewContext)
|
|
|
|
return;
|
|
|
|
|
|
|
|
resetContext();
|
|
|
|
|
|
|
|
worldViewContext = std::make_shared<MapRendererWorldViewContext>(*state);
|
|
|
|
context = worldViewContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::activateSpellViewContext()
|
|
|
|
{
|
|
|
|
if (spellViewContext)
|
|
|
|
return;
|
|
|
|
|
|
|
|
resetContext();
|
|
|
|
|
|
|
|
spellViewContext = std::make_shared<MapRendererSpellViewContext>(*state);
|
|
|
|
worldViewContext = spellViewContext;
|
|
|
|
context = spellViewContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::activatePuzzleMapContext(const int3 & grailPosition)
|
|
|
|
{
|
|
|
|
resetContext();
|
|
|
|
|
|
|
|
puzzleMapContext = std::make_shared<MapRendererPuzzleMapContext>(*state);
|
|
|
|
context = puzzleMapContext;
|
|
|
|
|
|
|
|
CGPathNode fakeNode;
|
|
|
|
fakeNode.coord = grailPosition;
|
|
|
|
|
|
|
|
puzzleMapContext->grailPos = std::make_unique<CGPath>();
|
|
|
|
|
|
|
|
// create two nodes since 1st one is normally not visible
|
|
|
|
puzzleMapContext->grailPos->nodes.push_back(fakeNode);
|
|
|
|
puzzleMapContext->grailPos->nodes.push_back(fakeNode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::resetContext()
|
|
|
|
{
|
|
|
|
adventureContext.reset();
|
|
|
|
movementContext.reset();
|
|
|
|
fadingOutContext.reset();
|
|
|
|
fadingInContext.reset();
|
|
|
|
worldViewContext.reset();
|
|
|
|
spellViewContext.reset();
|
|
|
|
puzzleMapContext.reset();
|
|
|
|
}
|
|
|
|
|
2023-02-21 14:38:08 +02:00
|
|
|
void MapViewController::setTerrainVisibility(bool showAllTerrain)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(spellViewContext);
|
|
|
|
spellViewContext->showAllTerrain = showAllTerrain;
|
2023-02-21 14:38:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapViewController::setOverlayVisibility(const std::vector<ObjectPosInfo> & objectPositions)
|
|
|
|
{
|
2023-02-26 18:17:53 +02:00
|
|
|
assert(spellViewContext);
|
|
|
|
spellViewContext->additionalOverlayIcons = objectPositions;
|
2023-02-21 14:38:08 +02:00
|
|
|
}
|
|
|
|
|