浏览代码

direction & image functionality

Laserlicht 4 月之前
父节点
当前提交
e1adbde5ac

+ 2 - 2
client/mapView/IMapRendererContext.h

@@ -56,8 +56,8 @@ public:
 	/// returns true if specified object is the currently active hero
 	virtual bool isActiveHero(const CGObjectInstance* obj) const = 0;
 
-	/// returns true if specified object is a monster and currently attacked
-	virtual bool isMonsterAttacked(const CGObjectInstance * obj) const = 0;
+	/// returns pos of attacker if specified object is a monster and currently attacked
+	virtual std::optional<int3> monsterAttacked(const CGObjectInstance * obj) const = 0;
 
 	virtual size_t objectGroupIndex(ObjectInstanceID objectID) const = 0;
 	virtual Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const = 0;

+ 8 - 3
client/mapView/MapRenderer.cpp

@@ -466,10 +466,15 @@ std::shared_ptr<IImage> MapRendererObjects::getImage(IMapRendererContext & conte
 	if(animation->size(groupIndex) == 0)
 		return nullptr;
 	
-	if(context.isMonsterAttacked(obj))
+	if(auto attackerPos = context.monsterAttacked(obj))
 	{
-		auto img = ENGINE->renderHandler().loadImage(ImagePath::builtin("AvWattak:0:0"), EImageBlitMode::SIMPLE);
-		return img;
+		const auto * creature = dynamic_cast<const CArmedInstance *>(obj);
+		ImagePath imgPath = (*attackerPos).x < obj->pos.x ? (*creature->getCreatureMap().begin()).first->mapAttackFromLeft : (*creature->getCreatureMap().begin()).first->mapAttackFromRight;
+		if(!imgPath.empty())
+		{
+			auto img = ENGINE->renderHandler().loadImage(imgPath, EImageBlitMode::SIMPLE);
+			return img;
+		}
 	}
 
 	size_t frameIndex = context.objectImageIndex(obj->id, animation->size(groupIndex));

+ 4 - 4
client/mapView/MapRendererContext.cpp

@@ -87,16 +87,16 @@ bool MapRendererBaseContext::isActiveHero(const CGObjectInstance * obj) const
 	return false;
 }
 
-bool MapRendererBaseContext::isMonsterAttacked(const CGObjectInstance * obj) const
+std::optional<int3> MapRendererBaseContext::monsterAttacked(const CGObjectInstance * obj) const
 {
 	if(obj->ID != Obj::MONSTER)
-		return false;
+		return std::nullopt;
 		
 	for(auto & battle : GAME->interface()->cb->getActiveBattles())
 		if(obj->pos == battle.second->getBattle()->getLocation())
-			return true;
+			return battle.second->getBattle()->getSideHero(BattleSide::ATTACKER)->pos;
 
-	return false;
+	return std::nullopt;
 }
 
 bool MapRendererBaseContext::tileAnimated(const int3 & coordinates) const

+ 1 - 1
client/mapView/MapRendererContext.h

@@ -36,7 +36,7 @@ public:
 	bool tileAnimated(const int3 & coordinates) const override;
 
 	bool isActiveHero(const CGObjectInstance* obj) const override;
-	bool isMonsterAttacked(const CGObjectInstance * obj) const override;
+	std::optional<int3> monsterAttacked(const CGObjectInstance * obj) const override;
 
 	const TerrainTile & getMapTile(const int3 & coordinates) const override;
 	const MapObjectsList & getObjects(const int3 & coordinates) const override;

+ 10 - 0
config/schemas/creature.json

@@ -153,6 +153,16 @@
 					"items" : { "type" : "string" },
 					"description" : "Object mask that describes on which tiles object is visible/blocked/activatable"
 				},
+				"mapAttackFromLeft" : {
+					"type" : "string",
+					"description" : "Adventure map creature image when attacked from left",
+					"format" : "imageFile"
+				},
+				"mapAttackFromRight" : {
+					"type" : "string",
+					"description" : "Adventure map creature image when attacked from right",
+					"format" : "imageFile"
+				},
 				"iconLarge" : {
 					"type" : "string",
 					"description" : "Large icon for this creature, used for example in town screen",

+ 2 - 0
lib/CCreatureHandler.cpp

@@ -901,6 +901,8 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph
 void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config) const
 {
 	creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]);
+	creature->mapAttackFromLeft = ImagePath::fromJson(config["graphics"]["mapAttackFromLeft"]);
+	creature->mapAttackFromRight = ImagePath::fromJson(config["graphics"]["mapAttackFromRight"]);
 
 	//FIXME: MOD COMPATIBILITY
 	if (config["abilities"].getType() == JsonNode::JsonType::DATA_STRUCT)

+ 2 - 0
lib/CCreatureHandler.h

@@ -67,6 +67,8 @@ public:
 	std::set<CreatureID> upgrades; // IDs of creatures to which this creature can be upgraded
 
 	AnimationPath animDefName; // creature animation used during battles
+	ImagePath mapAttackFromLeft; // adventure map creature image when attacked from left
+	ImagePath mapAttackFromRight; // adventure map creature image when attacked from right
 
 	si32 iconIndex = -1; // index of icon in files like twcrport, used in tests now.
 	/// names of files with appropriate icons. Used only during loading