Explorar o código

Animations from config

nordsoft %!s(int64=2) %!d(string=hai) anos
pai
achega
d1dacd45e2

+ 8 - 26
client/mapView/MapRenderer.cpp

@@ -26,6 +26,7 @@
 #include "../../lib/RoadHandler.h"
 #include "../../lib/TerrainHandler.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
+#include "../../lib/mapObjects/MiscObjects.h"
 #include "../../lib/mapping/CMap.h"
 
 struct NeighborTilesInfo
@@ -394,15 +395,11 @@ std::shared_ptr<CAnimation> MapRendererObjects::getBaseAnimation(const CGObjectI
 
 	bool generateMovementGroups = (info->id == Obj::TRANSPORT) || (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::TRANSPORT && info->subid < boatAnimations.size())
-		return getAnimation(boatAnimations[info->subid], generateMovementGroups);
+	if (info->id == Obj::TRANSPORT)
+		if(auto boat = dynamic_cast<const CGBoat*>(obj); boat && !boat->actualAnimation.empty())
+			return getAnimation(boat->actualAnimation, generateMovementGroups);
 
 	return getAnimation(info->animationFile, generateMovementGroups);
 }
@@ -438,13 +435,6 @@ std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectI
 		"AF00", "AF01", "AF02", "AF03", "AF04", "AF05", "AF06", "AF07"
 	};
 
-	//TODO: relocate to config file?
-	static const std::vector<std::vector<std::string>> boatFlags = {
-		{"ABF01L", "ABF01G", "ABF01R", "ABF01D", "ABF01B", "ABF01P", "ABF01W", "ABF01K"},
-		{"ABF02L", "ABF02G", "ABF02R", "ABF02D", "ABF02B", "ABF02P", "ABF02W", "ABF02K"},
-		{"ABF03L", "ABF03G", "ABF03R", "ABF03D", "ABF03B", "ABF03P", "ABF03W", "ABF03K"}
-	};
-
 	if(obj->ID == Obj::HERO)
 	{
 		assert(dynamic_cast<const CGHeroInstance *>(obj) != nullptr);
@@ -455,11 +445,8 @@ std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectI
 	if(obj->ID == Obj::TRANSPORT)
 	{
 		const auto * boat = dynamic_cast<const CGBoat *>(obj);
-		if(boat->hero && boat->subID < boatFlags.size())
-		{
-			assert(boat->hero->tempOwner.isValidPlayer());
-			return getAnimation(boatFlags[boat->subID][boat->hero->tempOwner.getNum()], true);
-		}
+		if(boat && boat->hero && !boat->flagAnimations[boat->hero->tempOwner.getNum()].empty())
+			return getAnimation(boat->flagAnimations[boat->hero->tempOwner.getNum()], true);
 	}
 
 	return nullptr;
@@ -469,15 +456,10 @@ std::shared_ptr<CAnimation> MapRendererObjects::getOverlayAnimation(const CGObje
 {
 	if(obj->ID == Obj::TRANSPORT)
 	{
-		//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 && obj->subID < boatAnimations.size())
-			return getAnimation(boatAnimations[obj->subID], true);
+		if(boat && boat->hero && !boat->overlayAnimation.empty())
+			return getAnimation(boat->overlayAnimation, true);
 	}
 	return nullptr;
 }

+ 26 - 3
config/objects/moddables.json

@@ -115,9 +115,32 @@
 			}
 		},
 		"types" : {
-			"evil" : { "index" : 0,	"rmg" : { "mapLimit" : 64 } },
-			"good" : { "index" : 1, "rmg" : { "mapLimit" : 64 } },
-			"neutral" : { "index" : 2, "rmg" : { "mapLimit" : 64 } },
+			"evil" : 
+			{ 
+				"index" : 0,	
+				"rmg" : { "mapLimit" : 64 },
+				"layer" : "sail",
+				"actualAnimation" : "AB01_.def",
+				"overlayAnimation" : "ABM01_.def",
+				"flagAnimations" : ["ABF01L", "ABF01G", "ABF01R", "ABF01D", "ABF01B", "ABF01P", "ABF01W", "ABF01K"]
+			},
+			"good" : 
+			{ 
+				"index" : 1, 
+				"rmg" : { "mapLimit" : 64 },
+				"layer" : "sail",
+				"actualAnimation" : "AB02_.def",
+				"overlayAnimation" : "ABM02_.def",
+				"flagAnimations" : ["ABF02L", "ABF02G", "ABF02R", "ABF02D", "ABF02B", "ABF02P", "ABF02W", "ABF02K"]
+			},
+			"neutral" : { 
+				"index" : 2, 
+				"rmg" : { "mapLimit" : 64 },
+				"layer" : "sail",
+				"actualAnimation" : "AB03_.def",
+				"overlayAnimation" : "ABM03_.def",
+				"flagAnimations" : ["ABF03L", "ABF03G", "ABF03R", "ABF03D", "ABF03B", "ABF03P", "ABF03W", "ABF03K"]
+			},
 		}
 	},
 

+ 8 - 0
lib/StringConstants.h

@@ -114,4 +114,12 @@ namespace NMetaclass
     };
 }
 
+namespace NPathfindingLayer
+{
+	const std::string names[EPathfindingLayer::NUM_LAYERS] =
+	{
+		"land", "sail", "water", "air"
+	};
+}
+
 VCMI_LIB_NAMESPACE_END

+ 17 - 9
lib/mapObjects/CommonConstructors.cpp

@@ -21,6 +21,7 @@
 #include "JsonRandom.h"
 #include "../CModHandler.h"
 #include "../IGameCallback.h"
+#include "../StringConstants.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -259,24 +260,31 @@ std::vector<const CCreature *> CDwellingInstanceConstructor::getProducedCreature
 
 void BoatInstanceConstructor::initTypeData(const JsonNode & input)
 {
-	layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
-	if(input["layer"].String() == "land")
-		layer = EPathfindingLayer::EEPathfindingLayer::LAND;
-	if(input["layer"].String() == "air")
-		layer = EPathfindingLayer::EEPathfindingLayer::AIR;
-	if(input["layer"].String() == "water")
-		layer = EPathfindingLayer::EEPathfindingLayer::WATER;
-	if(input["layer"].String() == "sail")
-		layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
+	layer = EPathfindingLayer::SAIL;
+	int pos = vstd::find_pos(NPathfindingLayer::names, input["layer"].String());
+	if(pos != -1)
+		layer = EPathfindingLayer(pos);
+	actualAnimation = input["actualAnimation"].String();
+	overlayAnimation = input["overlayAnimation"].String();
+	for(int i = 0; i < flagAnimations.size() && i < input["flagAnimations"].Vector().size(); ++i)
+		flagAnimations[i] = input["flagAnimations"].Vector()[i].String();
 }
 
 CGObjectInstance * BoatInstanceConstructor::create(std::shared_ptr<const ObjectTemplate> tmpl) const
 {
 	CGBoat * boat = createTyped(tmpl);
 	boat->layer = layer;
+	boat->actualAnimation = actualAnimation;
+	boat->overlayAnimation = overlayAnimation;
+	boat->flagAnimations = flagAnimations;
 	return boat;
 }
 
+void BoatInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
+{
+
+}
+
 bool CBankInstanceConstructor::hasNameTextID() const
 {
 	return true;

+ 5 - 1
lib/mapObjects/CommonConstructors.h

@@ -145,10 +145,14 @@ class BoatInstanceConstructor : public CDefaultObjectTypeHandler<CGBoat>
 protected:
 	void initTypeData(const JsonNode & config) override;
 	
-	EPathfindingLayer::EEPathfindingLayer layer;
+	EPathfindingLayer layer;
+	std::string actualAnimation; //for OH3 boats those have actual animations
+	std::string overlayAnimation; //waves animations
+	std::array<std::string, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
 	
 public:
 	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override;
+	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 5 - 0
lib/mapObjects/MiscObjects.h

@@ -421,6 +421,11 @@ public:
 	const CGHeroInstance *hero;  //hero on board
 	
 	EPathfindingLayer::EEPathfindingLayer layer;
+	
+	//animation filenames. If empty - animations won't be used
+	std::string actualAnimation; //for OH3 boats those have actual animations
+	std::string overlayAnimation; //waves animations
+	std::array<std::string, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
 
 	void initObj(CRandomGenerator & rand) override;