Переглянути джерело

Fix graphical artifact in hero movement animation

Ivan Savenko 2 роки тому
батько
коміт
2cca15c2db

+ 4 - 2
client/mapView/MapView.cpp

@@ -66,16 +66,18 @@ void BasicMapView::render(Canvas & target, bool fullUpdate)
 
 void BasicMapView::show(SDL_Surface * to)
 {
-	controller->update(GH.mainFPSmng->getElapsedMilliseconds());
+	controller->updateBefore(GH.mainFPSmng->getElapsedMilliseconds());
 
 	Canvas target(to);
 	CSDL_Ext::CClipRectGuard guard(to, pos);
 	render(target, false);
+
+	controller->updateAfter(GH.mainFPSmng->getElapsedMilliseconds());
 }
 
 void BasicMapView::showAll(SDL_Surface * to)
 {
-	controller->update(0);
+	controller->updateBefore(0);
 
 	Canvas target(to);
 	CSDL_Ext::CClipRectGuard guard(to, pos);

+ 48 - 30
client/mapView/MapViewController.cpp

@@ -88,7 +88,7 @@ std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
 	return context;
 }
 
-void MapViewController::update(uint32_t timeDelta)
+void MapViewController::updateBefore(uint32_t timeDelta)
 {
 	// confirmed to match H3 for
 	// - hero embarking on boat (500 ms)
@@ -116,56 +116,32 @@ void MapViewController::update(uint32_t timeDelta)
 			settings["adventure"]["enemyMoveTime"].Float();
 
 		movementContext->progress += timeDelta / heroMoveTime;
+		movementContext->progress = std::min( 1.0, movementContext->progress);
 
 		Point positionFrom = Point(hero->convertToVisitablePos(movementContext->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
 		Point positionDest = Point(hero->convertToVisitablePos(movementContext->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
 
 		Point positionCurr = vstd::lerp(positionFrom, positionDest, movementContext->progress);
 
-		if(movementContext->progress >= 1.0)
-		{
-			setViewCenter(hero->getSightCenter());
-
-			removeObject(context->getObject(movementContext->target));
-			addObject(context->getObject(movementContext->target));
-
-			activateAdventureContext(movementContext->animationTime);
-		}
-		else
-		{
-			setViewCenter(positionCurr, movementContext->tileDest.z);
-		}
+		setViewCenter(positionCurr, movementContext->tileDest.z);
 	}
 
 	if(teleportContext)
 	{
 		teleportContext->progress += timeDelta / heroTeleportDuration;
-		if(teleportContext->progress >= 1.0)
-		{
-			activateAdventureContext(teleportContext->animationTime);
-		}
+		teleportContext->progress = std::min( 1.0, teleportContext->progress);
 	}
 
 	if(fadingOutContext)
 	{
 		fadingOutContext->progress -= timeDelta / fadeOutDuration;
-
-		if(fadingOutContext->progress <= 0.0)
-		{
-			removeObject(context->getObject(fadingOutContext->target));
-
-			activateAdventureContext(fadingOutContext->animationTime);
-		}
+		fadingOutContext->progress = std::max( 0.0, fadingOutContext->progress);
 	}
 
 	if(fadingInContext)
 	{
 		fadingInContext->progress += timeDelta / fadeInDuration;
-
-		if(fadingInContext->progress >= 1.0)
-		{
-			activateAdventureContext(fadingInContext->animationTime);
-		}
+		fadingInContext->progress = std::min( 1.0, fadingInContext->progress);
 	}
 
 	if(adventureContext)
@@ -180,6 +156,48 @@ void MapViewController::update(uint32_t timeDelta)
 	}
 }
 
+void MapViewController::updateAfter(uint32_t timeDelta)
+{
+	if(movementContext)
+	{
+		const auto * object = context->getObject(movementContext->target);
+		const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
+		const auto * boat = dynamic_cast<const CGBoat *>(object);
+
+		assert(boat || hero);
+
+		if(!hero)
+			hero = boat->hero;
+
+		if(movementContext->progress >= 1.0)
+		{
+			setViewCenter(hero->getSightCenter());
+
+			removeObject(context->getObject(movementContext->target));
+			addObject(context->getObject(movementContext->target));
+
+			activateAdventureContext(movementContext->animationTime);
+		}
+	}
+
+	if(teleportContext && teleportContext->progress >= 1.0)
+	{
+		activateAdventureContext(teleportContext->animationTime);
+	}
+
+	if(fadingOutContext && fadingOutContext->progress <= 0.0)
+	{
+		removeObject(context->getObject(fadingOutContext->target));
+
+		activateAdventureContext(fadingOutContext->animationTime);
+	}
+
+	if(fadingInContext && fadingInContext->progress >= 1.0)
+	{
+		activateAdventureContext(fadingInContext->animationTime);
+	}
+}
+
 bool MapViewController::isEventVisible(const CGObjectInstance * obj)
 {
 	if(adventureContext == nullptr)

+ 2 - 1
client/mapView/MapViewController.h

@@ -83,7 +83,8 @@ public:
 	void setViewCenter(const int3 & position);
 	void setViewCenter(const Point & position, int level);
 	void setTileSize(const Point & tileSize);
-	void update(uint32_t timeDelta);
+	void updateBefore(uint32_t timeDelta);
+	void updateAfter(uint32_t timeDelta);
 
 	void activateAdventureContext(uint32_t animationTime);
 	void activateAdventureContext();