diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index c2997135f..462939819 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1501,6 +1501,8 @@ void CPlayerInterface::objectRemoved(const CGObjectInstance * obj) waitWhileDialog(); CCS->soundh->playSound(obj->getRemovalSound().get()); } + CGI->mh->waitForOngoingAnimations(); + if(obj->ID == Obj::HERO && obj->tempOwner == playerID) { const CGHeroInstance * h = static_cast(obj); diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 20e2e4c4d..aad6d47e9 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -572,16 +572,12 @@ void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack) logNetwork->error("Something wrong with hero recruited!"); } - bool needsPrinting = true; if(callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroCreated, h)) { if(const CGTownInstance *t = gs.getTown(pack.tid)) - { callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroInGarrisonChange, t); - needsPrinting = false; - } } - if(needsPrinting && CGI->mh) + if(CGI->mh) CGI->mh->onObjectInstantAdd(h); } diff --git a/client/mapRenderer/MapViewController.cpp b/client/mapRenderer/MapViewController.cpp index f4ff084e2..8933d35a1 100644 --- a/client/mapRenderer/MapViewController.cpp +++ b/client/mapRenderer/MapViewController.cpp @@ -14,6 +14,8 @@ #include "MapRendererContext.h" #include "MapViewModel.h" +#include "../adventureMap/CAdvMapInt.h" + #include "../../lib/CConfigHandler.h" #include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/MiscObjects.h" @@ -52,6 +54,14 @@ std::shared_ptr MapViewController::getContext() const return context; } +void MapViewController::moveFocusToSelection() +{ + const auto * army = adventureInt->curArmy(); + + if (army) + setViewCenter(army->getSightCenter()); +} + void MapViewController::update(uint32_t timeDelta) { // confirmed to match H3 for @@ -68,13 +78,22 @@ void MapViewController::update(uint32_t timeDelta) if(context->movementAnimation) { + const auto * object = context->getObject(context->movementAnimation->target); + const auto * hero = dynamic_cast(object); + const auto * boat = dynamic_cast(object); + + assert(boat || hero); + + if (!hero) + hero = boat->hero; + // TODO: enemyMoveTime double heroMoveTime = settings["adventure"]["heroMoveTime"].Float(); context->movementAnimation->progress += timeDelta / heroMoveTime; - Point positionFrom = Point(context->movementAnimation->tileFrom) * model->getSingleTileSize(); - Point positionDest = Point(context->movementAnimation->tileDest) * model->getSingleTileSize(); + Point positionFrom = Point(hero->convertToVisitablePos(context->movementAnimation->tileFrom)) * model->getSingleTileSize(); + Point positionDest = Point(hero->convertToVisitablePos(context->movementAnimation->tileDest)) * model->getSingleTileSize(); Point positionCurr = vstd::lerp(positionFrom, positionDest, context->movementAnimation->progress); @@ -82,7 +101,7 @@ void MapViewController::update(uint32_t timeDelta) if(context->movementAnimation->progress >= 1.0) { - setViewCenter(context->movementAnimation->tileDest); + setViewCenter(hero->getSightCenter()); context->removeObject(context->getObject(context->movementAnimation->target)); context->addObject(context->getObject(context->movementAnimation->target)); @@ -93,6 +112,7 @@ void MapViewController::update(uint32_t timeDelta) if(context->teleportAnimation) { context->teleportAnimation->progress += timeDelta / heroTeleportDuration; + moveFocusToSelection(); if(context->teleportAnimation->progress >= 1.0) context->teleportAnimation.reset(); } @@ -100,6 +120,7 @@ void MapViewController::update(uint32_t timeDelta) if(context->fadeOutAnimation) { context->fadeOutAnimation->progress += timeDelta / fadeOutDuration; + moveFocusToSelection(); if(context->fadeOutAnimation->progress >= 1.0) { context->removeObject(context->getObject(context->fadeOutAnimation->target)); @@ -110,6 +131,7 @@ void MapViewController::update(uint32_t timeDelta) if(context->fadeInAnimation) { context->fadeInAnimation->progress += timeDelta / fadeInDuration; + moveFocusToSelection(); if(context->fadeInAnimation->progress >= 1.0) context->fadeInAnimation.reset(); } @@ -127,15 +149,25 @@ void MapViewController::update(uint32_t timeDelta) void MapViewController::onObjectFadeIn(const CGObjectInstance * obj) { + bool actionVisible = context->isVisible(obj->pos); + assert(!context->fadeInAnimation); - context->fadeInAnimation = FadingAnimationState{obj->id, 0.0}; + + if (actionVisible) + context->fadeInAnimation = FadingAnimationState{obj->id, 0.0}; context->addObject(obj); } void MapViewController::onObjectFadeOut(const CGObjectInstance * obj) { + bool actionVisible = context->isVisible(obj->pos); + assert(!context->fadeOutAnimation); - context->fadeOutAnimation = FadingAnimationState{obj->id, 0.0}; + + if (actionVisible) + context->fadeOutAnimation = FadingAnimationState{obj->id, 0.0}; + else + context->removeObject(obj); } void MapViewController::onObjectInstantAdd(const CGObjectInstance * obj) @@ -151,12 +183,23 @@ void MapViewController::onObjectInstantRemove(const CGObjectInstance * obj) void MapViewController::onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest) { assert(!context->teleportAnimation); - context->teleportAnimation = HeroAnimationState{obj->id, from, dest, 0.0}; + bool actionVisible = context->isVisible(from) || context->isVisible(dest); + + if (actionVisible) + { + context->teleportAnimation = HeroAnimationState{obj->id, from, dest, 0.0}; + } + else + { + context->removeObject(obj); + context->addObject(obj); + } } void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) { assert(!context->movementAnimation); + bool actionVisible = context->isVisible(from) || context->isVisible(dest); const CGObjectInstance * movingObject = obj; if(obj->boat) @@ -164,7 +207,7 @@ void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & fro context->removeObject(movingObject); - if(settings["adventure"]["heroMoveTime"].Float() > 1) + if(settings["adventure"]["heroMoveTime"].Float() > 1 && actionVisible) { context->addMovingObject(movingObject, from, dest); context->movementAnimation = HeroAnimationState{movingObject->id, from, dest, 0.0}; @@ -173,13 +216,15 @@ void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & fro { // instant movement context->addObject(movingObject); - setViewCenter(movingObject->visitablePos()); + + if (actionVisible) + setViewCenter(movingObject->visitablePos()); } } void MapViewController::onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest) { - //TODO + //TODO. Or no-op? } bool MapViewController::hasOngoingAnimations() diff --git a/client/mapRenderer/MapViewController.h b/client/mapRenderer/MapViewController.h index dad5666d2..ed093e522 100644 --- a/client/mapRenderer/MapViewController.h +++ b/client/mapRenderer/MapViewController.h @@ -38,6 +38,7 @@ private: void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override; void onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest) override; + void moveFocusToSelection(); public: explicit MapViewController(std::shared_ptr model);