Browse Source

Fixed in-boat movement

Ivan Savenko 2 years ago
parent
commit
b5ad3a0559

+ 37 - 7
client/adventureMap/MapRenderer.cpp

@@ -312,7 +312,7 @@ void MapRendererFow::renderTile(const IMapRendererContext & context, Canvas & ta
 	}
 }
 
-std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInstance * obj)
+std::shared_ptr<CAnimation> MapRendererObjects::getBaseAnimation(const CGObjectInstance* obj)
 {
 	const auto & info = obj->appearance;
 
@@ -328,6 +328,16 @@ std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInsta
 
 	bool generateMovementGroups = (info->id == Obj::BOAT) || (info->id == Obj::HERO);
 
+	//TODO: relocate to config file?
+	// Boat appearance files only contain single, unanimated image
+	// proper boat animations are actually in different file
+	static const std::vector<std::string> boatAnimations = {
+		"AB01_.def", "AB02_.def", "AB03_.def"
+	};
+
+	if (info->id == Obj::BOAT)
+		return getAnimation(boatAnimations[info->subid], generateMovementGroups);
+
 	return getAnimation(info->animationFile, generateMovementGroups);
 }
 
@@ -373,15 +383,34 @@ std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectI
 		assert(obj->tempOwner.isValidPlayer());
 		return getAnimation(heroFlags[obj->tempOwner.getNum()], true);
 	}
+
 	if(obj->ID == Obj::BOAT)
 	{
 		const auto * boat = dynamic_cast<const CGBoat *>(obj);
-		assert(boat);
 		assert(boat->subID < boatFlags.size());
-		assert(!boat->hero || boat->hero->tempOwner.isValidPlayer());
+		if (boat->hero)
+		{
+			assert(boat->hero->tempOwner.isValidPlayer());
+			return getAnimation(boatFlags[boat->subID][boat->hero->tempOwner.getNum()], true);
+		}
+	}
 
-		if(boat->hero)
-			return getAnimation(boatFlags[obj->subID][boat->hero->tempOwner.getNum()], true);
+	return nullptr;
+}
+
+std::shared_ptr<CAnimation> MapRendererObjects::getOverlayAnimation(const CGObjectInstance * obj)
+{
+	if(obj->ID == Obj::BOAT)
+	{
+		//TODO: relocate to config file?
+		// Boats have additional animation with waves around boat
+		static const std::vector<std::string> boatAnimations = {
+			"ABM01_.def", "ABM02_.def", "ABM03_.def"
+		};
+
+		const auto * boat = dynamic_cast<const CGBoat *>(obj);
+		if (boat->hero)
+			return getAnimation(boatAnimations[obj->subID], true);
 	}
 	return nullptr;
 }
@@ -406,7 +435,7 @@ void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas
 	if(!image)
 		return;
 
-	uint8_t 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)));
 
 	if (transparency == 0)
 		return;
@@ -425,8 +454,9 @@ void MapRendererObjects::renderImage(const IMapRendererContext & context, Canvas
 
 void MapRendererObjects::renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance* instance)
 {
-	renderImage(context, target, coordinates, instance, getImage(context, instance, getAnimation(instance)));
+	renderImage(context, target, coordinates, instance, getImage(context, instance, getBaseAnimation(instance)));
 	renderImage(context, target, coordinates, instance, getImage(context, instance, getFlagAnimation(instance)));
+	renderImage(context, target, coordinates, instance, getImage(context, instance, getOverlayAnimation(instance)));
 }
 
 void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)

+ 3 - 1
client/adventureMap/MapRenderer.h

@@ -76,8 +76,10 @@ class MapRendererObjects
 {
 	std::map<std::string, std::shared_ptr<CAnimation>> animations;
 
+	std::shared_ptr<CAnimation> getBaseAnimation(const CGObjectInstance * obj);
 	std::shared_ptr<CAnimation> getFlagAnimation(const CGObjectInstance * obj);
-	std::shared_ptr<CAnimation> getAnimation(const CGObjectInstance * obj);
+	std::shared_ptr<CAnimation> getOverlayAnimation(const CGObjectInstance * obj);
+
 	std::shared_ptr<CAnimation> getAnimation(const std::string & filename, bool generateMovementGroups);
 
 	std::shared_ptr<IImage> getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation> & animation) const;

+ 27 - 20
client/adventureMap/MapView.cpp

@@ -11,35 +11,21 @@
 #include "StdInc.h"
 #include "MapView.h"
 
-#include <utility>
-
 #include "MapRenderer.h"
 #include "mapHandler.h"
 #include "CAdvMapInt.h"
 
 #include "../CGameInfo.h"
-#include "../CMusicHandler.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CGuiHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
-#include "../render/Colors.h"
-#include "../render/Graphics.h"
-#include "../render/IImage.h"
 #include "../renderSDL/SDL_Extensions.h"
 
 #include "../../CCallback.h"
 
 #include "../../lib/CConfigHandler.h"
-#include "../../lib/CGeneralTextHandler.h"
-#include "../../lib/CRandomGenerator.h"
-#include "../../lib/CStopWatch.h"
-#include "../../lib/Color.h"
-#include "../../lib/RiverHandler.h"
-#include "../../lib/RoadHandler.h"
-#include "../../lib/TerrainHandler.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
-#include "../../lib/mapObjects/CObjectClassesHandler.h"
 #include "../../lib/mapping/CMap.h"
 
 MapViewCache::~MapViewCache() = default;
@@ -414,9 +400,12 @@ size_t MapRendererContext::objectGroupIndex(ObjectInstanceID objectID) const
 	if(obj->ID == Obj::BOAT)
 	{
 		const auto * boat = dynamic_cast<const CGBoat *>(obj);
+
+		uint8_t direction = boat->hero ? boat->hero->moveDir : boat->direction;
+
 		if (movementAnimation && movementAnimation->target == objectID)
-			return moveGroups[boat->direction];
-		return idleGroups[boat->direction];
+			return moveGroups[direction];
+		return idleGroups[direction];
 	}
 	return 0;
 }
@@ -443,6 +432,19 @@ Point MapRendererContext::objectImageOffset(ObjectInstanceID objectID, const int
 
 double MapRendererContext::objectTransparency(ObjectInstanceID objectID) const
 {
+	const CGObjectInstance * object = getObject(objectID);
+
+	if (object && object->ID == Obj::HERO)
+	{
+		const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
+
+		if (hero->inTownGarrison)
+			return 0;
+
+		if (hero->boat)
+			return 0;
+	}
+
 	if (fadeOutAnimation && objectID == fadeOutAnimation->target)
 		return 1.0 - fadeOutAnimation->progress;
 
@@ -550,17 +552,22 @@ void MapViewController::onHeroTeleported(const CGHeroInstance * obj, const int3
 void MapViewController::onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest)
 {
 	assert(!context->movementAnimation);
-	context->removeObject(obj);
+
+	const CGObjectInstance * movingObject = obj;
+	if (obj->boat)
+		movingObject = obj->boat;
+
+	context->removeObject(movingObject);
 
 	if (settings["adventure"]["heroMoveTime"].Float() > 1)
 	{
-		context->addMovingObject(obj, from, dest);
-		context->movementAnimation = HeroAnimationState{ obj->id, from, dest, 0.0 };
+		context->addMovingObject(movingObject, from, dest);
+		context->movementAnimation = HeroAnimationState{ movingObject->id, from, dest, 0.0 };
 	}
 	else
 	{
 		// instant movement
-		context->addObject(obj);
+		context->addObject(movingObject);
 	}
 }