diff --git a/client/mapView/IMapRendererContext.h b/client/mapView/IMapRendererContext.h index e1ae49f47..c1ff9bfc6 100644 --- a/client/mapView/IMapRendererContext.h +++ b/client/mapView/IMapRendererContext.h @@ -56,6 +56,9 @@ public: /// returns true if specified object is the currently active hero virtual bool isActiveHero(const CGObjectInstance* obj) const = 0; + /// Returns moveDir of hero that attacked this wandering monster, or -1 on failure + virtual int attackedMonsterDirection(const CGObjectInstance * wanderingMonster) const = 0; + virtual size_t objectGroupIndex(ObjectInstanceID objectID) const = 0; virtual Point objectImageOffset(ObjectInstanceID objectID, const int3 & coordinates) const = 0; diff --git a/client/mapView/MapRenderer.cpp b/client/mapView/MapRenderer.cpp index 9c157b264..26a282ceb 100644 --- a/client/mapView/MapRenderer.cpp +++ b/client/mapView/MapRenderer.cpp @@ -420,6 +420,19 @@ std::shared_ptr MapRendererObjects::getAnimation(const AnimationPath return ret; } +std::shared_ptr MapRendererObjects::getImage(const ImagePath & filename) const +{ + auto it = images.find(filename); + + if(it != images.end()) + return it->second; + + auto ret = ENGINE->renderHandler().loadImage(filename, EImageBlitMode::SIMPLE); + images[filename] = ret; + + return ret; +} + std::shared_ptr MapRendererObjects::getFlagAnimation(const CGObjectInstance* obj) { //TODO: relocate to config file? @@ -456,7 +469,7 @@ std::shared_ptr MapRendererObjects::getOverlayAnimation(const CGObje return nullptr; } -std::shared_ptr MapRendererObjects::getImage(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr& animation) const +std::shared_ptr MapRendererObjects::getImageToRender(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr& animation) const { if(!animation) return nullptr; @@ -465,6 +478,17 @@ std::shared_ptr MapRendererObjects::getImage(IMapRendererContext & conte if(animation->size(groupIndex) == 0) return nullptr; + + auto attackerPos = context.attackedMonsterDirection(obj); + if(attackerPos != -1) + { + const auto * creature = dynamic_cast(obj); + auto const & creatureType = LIBRARY->creh->objects[creature->appearance->subid]; + auto dir = std::vector({1, 2, 7, 8}); + ImagePath imgPath = std::count(dir.begin(), dir.end(), attackerPos) ? creatureType->mapAttackFromRight : creatureType->mapAttackFromLeft; + if(!imgPath.empty()) + return getImage(imgPath); + } size_t frameIndex = context.objectImageIndex(obj->id, animation->size(groupIndex)); @@ -502,9 +526,9 @@ void MapRendererObjects::renderImage(IMapRendererContext & context, Canvas & tar void MapRendererObjects::renderObject(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * 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))); + renderImage(context, target, coordinates, instance, getImageToRender(context, instance, getBaseAnimation(instance))); + renderImage(context, target, coordinates, instance, getImageToRender(context, instance, getFlagAnimation(instance))); + renderImage(context, target, coordinates, instance, getImageToRender(context, instance, getOverlayAnimation(instance))); } void MapRendererObjects::renderTile(IMapRendererContext & context, Canvas & target, const int3 & coordinates) diff --git a/client/mapView/MapRenderer.h b/client/mapView/MapRenderer.h index 085846c63..9a69bc24a 100644 --- a/client/mapView/MapRenderer.h +++ b/client/mapView/MapRenderer.h @@ -73,14 +73,16 @@ public: class MapRendererObjects { std::map> animations; + mutable std::map> images; std::shared_ptr getBaseAnimation(const CGObjectInstance * obj); std::shared_ptr getFlagAnimation(const CGObjectInstance * obj); std::shared_ptr getOverlayAnimation(const CGObjectInstance * obj); std::shared_ptr getAnimation(const AnimationPath & filename, bool generateMovementGroups, bool enableOverlay); + std::shared_ptr getImage(const ImagePath & filename) const; - std::shared_ptr getImage(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr & animation) const; + std::shared_ptr getImageToRender(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr & animation) const; void renderImage(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr & image); void renderObject(IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * obj); diff --git a/client/mapView/MapRendererContext.cpp b/client/mapView/MapRendererContext.cpp index 9c5f66a31..f1c23c76a 100644 --- a/client/mapView/MapRendererContext.cpp +++ b/client/mapView/MapRendererContext.cpp @@ -25,6 +25,8 @@ #include "../../lib/spells/CSpellHandler.h" #include "../../lib/mapping/CMap.h" #include "../../lib/pathfinder/CGPathNode.h" +#include "../../lib/battle/CPlayerBattleCallback.h" +#include "../../lib/battle/IBattleState.h" MapRendererBaseContext::MapRendererBaseContext(const MapRendererContextState & viewState) : viewState(viewState) @@ -85,6 +87,18 @@ bool MapRendererBaseContext::isActiveHero(const CGObjectInstance * obj) const return false; } +int MapRendererBaseContext::attackedMonsterDirection(const CGObjectInstance * wanderingMonster) const +{ + if(wanderingMonster->ID != Obj::MONSTER) + return -1; + + for(auto & battle : GAME->interface()->cb->getActiveBattles()) + if(wanderingMonster->pos == battle.second->getBattle()->getLocation()) + return battle.second->getBattle()->getSideHero(BattleSide::ATTACKER)->moveDir; + + return -1; +} + bool MapRendererBaseContext::tileAnimated(const int3 & coordinates) const { return false; diff --git a/client/mapView/MapRendererContext.h b/client/mapView/MapRendererContext.h index b956f1f09..cc71fbc5d 100644 --- a/client/mapView/MapRendererContext.h +++ b/client/mapView/MapRendererContext.h @@ -36,6 +36,7 @@ public: bool tileAnimated(const int3 & coordinates) const override; bool isActiveHero(const CGObjectInstance* obj) const override; + int attackedMonsterDirection(const CGObjectInstance * wanderingMonster) const override; const TerrainTile & getMapTile(const int3 & coordinates) const override; const MapObjectsList & getObjects(const int3 & coordinates) const override; diff --git a/client/renderSDL/RenderHandler.cpp b/client/renderSDL/RenderHandler.cpp index fa49ee327..6f9bb8aa9 100644 --- a/client/renderSDL/RenderHandler.cpp +++ b/client/renderSDL/RenderHandler.cpp @@ -354,6 +354,16 @@ std::shared_ptr RenderHandler::loadImage(const AnimationPath & path, int std::shared_ptr RenderHandler::loadImage(const ImagePath & path, EImageBlitMode mode) { + auto name = path.getOriginalName(); + + std::vector splitted; + boost::split(splitted, name, boost::is_any_of(":")); + if(splitted.size() == 3) + { + ImageLocator locator = getLocatorForAnimationFrame(AnimationPath::builtin(splitted[0]), std::stoi(splitted[2]), std::stoi(splitted[1]), 1, mode); + return loadImage(locator); + } + ImageLocator locator(path, mode); return loadImage(locator); } diff --git a/config/creatures/castle.json b/config/creatures/castle.json index a703d486d..b1960d7c9 100644 --- a/config/creatures/castle.json +++ b/config/creatures/castle.json @@ -14,6 +14,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:0", + "mapAttackFromLeft": "AvWattak.def:0:1", "animation": "CPKMAN.DEF" }, "sound" : @@ -39,6 +41,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:2", + "mapAttackFromLeft": "AvWattak.def:0:3", "animation": "CHALBD.DEF" }, "sound" : @@ -66,6 +70,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:4", + "mapAttackFromLeft": "AvWattak.def:0:5", "animation": "CLCBOW.DEF", "missile" : { @@ -103,6 +109,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:6", + "mapAttackFromLeft": "AvWattak.def:0:7", "animation": "CHCBOW.DEF", "missile" : { @@ -140,6 +148,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:8", + "mapAttackFromLeft": "AvWattak.def:0:9", "animation": "CGRIFF.DEF" }, "sound" : @@ -169,6 +179,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:10", + "mapAttackFromLeft": "AvWattak.def:0:11", "animation": "CRGRIF.DEF" }, "sound" : @@ -188,6 +200,8 @@ "upgrades": ["crusader"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:12", + "mapAttackFromLeft": "AvWattak.def:0:13", "animation": "CSWORD.DEF" }, "sound" : @@ -214,6 +228,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:14", + "mapAttackFromLeft": "AvWattak.def:0:15", "animation": "CCRUSD.DEF" }, "sound" : @@ -240,6 +256,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:16", + "mapAttackFromLeft": "AvWattak.def:0:17", "animation": "CMONKK.DEF", "missile" : { @@ -273,6 +291,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:18", + "mapAttackFromLeft": "AvWattak.def:0:19", "animation": "CZEALT.DEF", "missile" : { @@ -306,6 +326,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:20", + "mapAttackFromLeft": "AvWattak.def:0:21", "animation": "CCAVLR.DEF" }, "sound" : @@ -333,6 +355,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:22", + "mapAttackFromLeft": "AvWattak.def:0:23", "animation": "CCHAMP.DEF" }, "sound" : @@ -384,6 +408,8 @@ "upgrades": ["archangel"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:24", + "mapAttackFromLeft": "AvWattak.def:0:25", "animation": "CANGEL.DEF" }, "sound" : @@ -451,6 +477,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:26", + "mapAttackFromLeft": "AvWattak.def:0:27", "animation": "CRANGL.DEF" }, "sound" : diff --git a/config/creatures/conflux.json b/config/creatures/conflux.json index 78cb70ec1..505f8f59c 100755 --- a/config/creatures/conflux.json +++ b/config/creatures/conflux.json @@ -15,6 +15,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:236", + "mapAttackFromLeft": "AvWattak.def:0:237", "animation": "CPIXIE.DEF" }, "sound" : @@ -44,6 +46,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:238", + "mapAttackFromLeft": "AvWattak.def:0:239", "animation": "CSPRITE.DEF" }, "sound" : @@ -111,6 +115,8 @@ "upgrades": ["stormElemental"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:224", + "mapAttackFromLeft": "AvWattak.def:0:225", "animation": "CAELEM.DEF" }, "sound" : @@ -196,6 +202,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:254", + "mapAttackFromLeft": "AvWattak.def:0:255", "animation": "CSTORM.DEF", "missile" : { @@ -285,6 +293,8 @@ "upgrades": ["iceElemental"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:230", + "mapAttackFromLeft": "AvWattak.def:0:231", "animation": "CWELEM.DEF" }, "sound" : @@ -388,6 +398,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:246", + "mapAttackFromLeft": "AvWattak.def:0:247", "animation": "CICEE.DEF", "missile" : { @@ -452,6 +464,8 @@ "upgrades": ["energyElemental"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:228", + "mapAttackFromLeft": "AvWattak.def:0:229", "animation": "CFELEM.DEF" }, "sound" : @@ -530,6 +544,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:258", + "mapAttackFromLeft": "AvWattak.def:0:259", "animation": "CNRG.DEF" }, "sound" : @@ -593,6 +609,8 @@ "upgrades": ["magmaElemental"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:226", + "mapAttackFromLeft": "AvWattak.def:0:227", "animation": "CEELEM.DEF" }, "sound" : @@ -671,6 +689,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:250", + "mapAttackFromLeft": "AvWattak.def:0:251", "animation": "CSTONE.DEF" }, "sound" : @@ -710,6 +730,8 @@ "upgrades": ["magicElemental"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:240", + "mapAttackFromLeft": "AvWattak.def:0:241", "animation": "CPSYEL.DEF" }, "sound" : @@ -749,6 +771,8 @@ "doubleWide" : false, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:242", + "mapAttackFromLeft": "AvWattak.def:0:243", "animation": "CMAGEL.DEF" }, "sound" : @@ -790,6 +814,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:260", + "mapAttackFromLeft": "AvWattak.def:0:261", "animation": "CFBIRD.DEF" }, "sound" : @@ -840,6 +866,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:262", + "mapAttackFromLeft": "AvWattak.def:0:263", "animation": "CPHX.DEF" }, "sound" : diff --git a/config/creatures/dungeon.json b/config/creatures/dungeon.json index 2cdafee4c..d6c8d915e 100644 --- a/config/creatures/dungeon.json +++ b/config/creatures/dungeon.json @@ -21,6 +21,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:140", + "mapAttackFromLeft": "AvWattak.def:0:141", "animation": "CTROGL.DEF" }, "sound" : @@ -52,6 +54,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:142", + "mapAttackFromLeft": "AvWattak.def:0:143", "animation": "CITROG.DEF" }, "sound" : @@ -83,6 +87,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:144", + "mapAttackFromLeft": "AvWattak.def:0:145", "animation": "CHARPY.DEF" }, "sound" : @@ -116,6 +122,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:146", + "mapAttackFromLeft": "AvWattak.def:0:147", "animation": "CHARPH.DEF" }, "sound" : @@ -148,6 +156,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:148", + "mapAttackFromLeft": "AvWattak.def:0:149", "animation": "CBEHOL.DEF", "missile" : { @@ -190,6 +200,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:150", + "mapAttackFromLeft": "AvWattak.def:0:151", "animation": "CEVEYE.DEF", "missile" : { @@ -241,6 +253,8 @@ "upgrades": ["medusaQueen"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:152", + "mapAttackFromLeft": "AvWattak.def:0:153", "animation": "CMEDUS.DEF", "missile" : { @@ -284,6 +298,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:154", + "mapAttackFromLeft": "AvWattak.def:0:155", "animation": "CMEDUQ.DEF", "missile" : { @@ -317,6 +333,8 @@ "upgrades": ["minotaurKing"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:156", + "mapAttackFromLeft": "AvWattak.def:0:157", "animation": "CMINOT.DEF" }, "sound" : @@ -344,6 +362,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:158", + "mapAttackFromLeft": "AvWattak.def:0:159", "animation": "CMINOK.DEF" }, "sound" : @@ -372,6 +392,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:160", + "mapAttackFromLeft": "AvWattak.def:0:161", "animation": "CMCORE.DEF" }, "sound" : @@ -405,6 +427,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:162", + "mapAttackFromLeft": "AvWattak.def:0:163", "animation": "CCMCOR.DEF" }, "sound" : @@ -456,6 +480,8 @@ "upgrades": ["blackDragon"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:164", + "mapAttackFromLeft": "AvWattak.def:0:165", "animation": "CRDRGN.DEF" }, "sound" : @@ -511,6 +537,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:166", + "mapAttackFromLeft": "AvWattak.def:0:167", "animation": "CBDRGN.DEF" }, "sound" : diff --git a/config/creatures/fortress.json b/config/creatures/fortress.json index 5b025cba5..f6a7989f1 100644 --- a/config/creatures/fortress.json +++ b/config/creatures/fortress.json @@ -7,6 +7,8 @@ "upgrades": ["gnollMarauder"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:196", + "mapAttackFromLeft": "AvWattak.def:0:197", "animation": "CGNOLL.DEF" }, "sound" : @@ -25,6 +27,8 @@ "faction": "fortress", "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:198", + "mapAttackFromLeft": "AvWattak.def:0:199", "animation": "CGNOLM.DEF" }, "sound" : @@ -54,6 +58,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:200", + "mapAttackFromLeft": "AvWattak.def:0:201", "animation": "CPLIZA.DEF", "missile" : { @@ -85,6 +91,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:202", + "mapAttackFromLeft": "AvWattak.def:0:203", "animation": "CALIZA.DEF", "missile" : { @@ -124,6 +132,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:208", + "mapAttackFromLeft": "AvWattak.def:0:209", "animation": "CDRFLY.DEF" }, "sound" : @@ -161,6 +171,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:210", + "mapAttackFromLeft": "AvWattak.def:0:211", "animation": "CDRFIR.DEF" }, "sound" : @@ -191,6 +203,8 @@ "upgrades": ["greaterBasilisk"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:212", + "mapAttackFromLeft": "AvWattak.def:0:213", "animation": "CBASIL.DEF" }, "sound" : @@ -219,6 +233,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:214", + "mapAttackFromLeft": "AvWattak.def:0:215", "animation": "CGBASI.DEF" }, "sound" : @@ -239,6 +255,8 @@ "doubleWide" : true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:204", + "mapAttackFromLeft": "AvWattak.def:0:205", "animation": "CCGORG.DEF" }, "sound" : @@ -267,6 +285,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:206", + "mapAttackFromLeft": "AvWattak.def:0:207", "animation": "CBGOG.DEF" }, "sound" : @@ -294,6 +314,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:216", + "mapAttackFromLeft": "AvWattak.def:0:217", "animation": "CWYVER.DEF" }, "sound" : @@ -326,6 +348,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:218", + "mapAttackFromLeft": "AvWattak.def:0:219", "animation": "CWYVMN.DEF" }, "sound" : @@ -367,6 +391,8 @@ "upgrades": ["chaosHydra"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:220", + "mapAttackFromLeft": "AvWattak.def:0:221", "animation": "CHYDRA.DEF" }, "sound" : @@ -407,6 +433,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:222", + "mapAttackFromLeft": "AvWattak.def:0:223", "animation": "CCHYDR.DEF" }, "sound" : diff --git a/config/creatures/inferno.json b/config/creatures/inferno.json index 87c8e5a7c..3a3fb5e90 100755 --- a/config/creatures/inferno.json +++ b/config/creatures/inferno.json @@ -7,6 +7,8 @@ "upgrades": ["familiar"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:84", + "mapAttackFromLeft": "AvWattak.def:0:85", "animation": "CIMP.DEF" }, "sound" : @@ -33,6 +35,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:86", + "mapAttackFromLeft": "AvWattak.def:0:87", "animation": "CFAMIL.DEF" }, "sound" : @@ -61,6 +65,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:88", + "mapAttackFromLeft": "AvWattak.def:0:89", "animation": "CGOG.DEF", "missile" : { @@ -97,6 +103,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:90", + "mapAttackFromLeft": "AvWattak.def:0:91", "animation": "CMAGOG.DEF", "missile" : { @@ -122,6 +130,8 @@ "doubleWide" : true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:92", + "mapAttackFromLeft": "AvWattak.def:0:93", "animation": "CHHOUN.DEF" }, "sound" : @@ -152,6 +162,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:94", + "mapAttackFromLeft": "AvWattak.def:0:95", "animation": "CCERBU.DEF" }, "sound" : @@ -171,6 +183,8 @@ "upgrades": ["hornedDemon"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:96", + "mapAttackFromLeft": "AvWattak.def:0:97", "animation": "COHDEM.DEF" }, "sound" : @@ -189,6 +203,8 @@ "faction": "inferno", "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:98", + "mapAttackFromLeft": "AvWattak.def:0:99", "animation": "CTHDEM.DEF" }, "sound" : @@ -208,6 +224,8 @@ "upgrades": ["pitLord"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:100", + "mapAttackFromLeft": "AvWattak.def:0:101", "animation": "CPFIEN.DEF" }, "sound" : @@ -246,6 +264,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:102", + "mapAttackFromLeft": "AvWattak.def:0:103", "animation": "CPFOE.DEF" }, "sound" : @@ -289,6 +309,8 @@ "upgrades": ["efreetSultan"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:104", + "mapAttackFromLeft": "AvWattak.def:0:105", "animation": "CEFREE.DEF" }, "sound" : @@ -336,6 +358,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:106", + "mapAttackFromLeft": "AvWattak.def:0:107", "animation": "CEFRES.DEF" }, "sound" : @@ -396,6 +420,8 @@ "upgrades": ["archDevil"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:108", + "mapAttackFromLeft": "AvWattak.def:0:109", "animation": "CDEVIL.DEF" }, "sound" : @@ -456,6 +482,8 @@ "graphics" : { "missile" : null, + "mapAttackFromRight": "AvWattak.def:0:110", + "mapAttackFromLeft": "AvWattak.def:0:111", "animation": "CADEVL.DEF" }, "sound" : diff --git a/config/creatures/necropolis.json b/config/creatures/necropolis.json index 7e98d6ff2..50da678f0 100644 --- a/config/creatures/necropolis.json +++ b/config/creatures/necropolis.json @@ -14,6 +14,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:112", + "mapAttackFromLeft": "AvWattak.def:0:113", "animation": "CSKELE.DEF" }, "sound" : @@ -39,6 +41,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:114", + "mapAttackFromLeft": "AvWattak.def:0:115", "animation": "CWSKEL.DEF" }, "sound" : @@ -66,6 +70,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:116", + "mapAttackFromLeft": "AvWattak.def:0:117", "animation": "CZOMBI.DEF" }, "sound" : @@ -84,6 +90,8 @@ "faction": "necropolis", "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:118", + "mapAttackFromLeft": "AvWattak.def:0:119", "animation": "CZOMLO.DEF" }, "sound" : @@ -133,6 +141,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:120", + "mapAttackFromLeft": "AvWattak.def:0:121", "animation": "CWIGHT.DEF" }, "sound" : @@ -172,6 +182,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:122", + "mapAttackFromLeft": "AvWattak.def:0:123", "animation": "CWRAIT.DEF" }, "sound" : @@ -206,6 +218,8 @@ "upgrades": ["vampireLord"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:124", + "mapAttackFromLeft": "AvWattak.def:0:125", "animation": "CVAMP.DEF" }, "sound" : @@ -246,6 +260,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:126", + "mapAttackFromLeft": "AvWattak.def:0:127", "animation": "CNOSFE.DEF" }, "sound" : @@ -285,6 +301,8 @@ "upgrades": ["powerLich"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:128", + "mapAttackFromLeft": "AvWattak.def:0:129", "animation": "CLICH.DEF", "missile" : { @@ -325,6 +343,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:130", + "mapAttackFromLeft": "AvWattak.def:0:131", "animation": "CPLICH.DEF", "missile" : { @@ -363,6 +383,8 @@ "upgrades": ["dreadKnight"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:132", + "mapAttackFromLeft": "AvWattak.def:0:133", "animation": "CBKNIG.DEF" }, "sound" : @@ -400,6 +422,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:134", + "mapAttackFromLeft": "AvWattak.def:0:135", "animation": "CBLORD.DEF" }, "sound" : @@ -450,6 +474,8 @@ "upgrades": ["ghostDragon"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:136", + "mapAttackFromLeft": "AvWattak.def:0:137", "animation": "CNDRGN.DEF" }, "sound" : @@ -505,6 +531,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:138", + "mapAttackFromLeft": "AvWattak.def:0:139", "animation": "CHDRGN.DEF" }, "sound" : diff --git a/config/creatures/neutral.json b/config/creatures/neutral.json index 1297dc519..9dcd9f10c 100644 --- a/config/creatures/neutral.json +++ b/config/creatures/neutral.json @@ -20,6 +20,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:232", + "mapAttackFromLeft": "AvWattak.def:0:233", "animation": "CGGOLE.DEF" }, "sound" : @@ -51,6 +53,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:234", + "mapAttackFromLeft": "AvWattak.def:0:235", "animation": "CDGOLE.DEF" }, "sound" : @@ -124,6 +128,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:264", + "mapAttackFromLeft": "AvWattak.def:0:265", "animation": "CADRGN.DEF" }, "sound" : @@ -170,6 +176,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:266", + "mapAttackFromLeft": "AvWattak.def:0:267", "animation": "CCDRGN.DEF" }, "sound" : @@ -282,6 +290,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:268", + "mapAttackFromLeft": "AvWattak.def:0:269", "animation": "CFDRGN.DEF" }, "sound" : @@ -340,6 +350,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:270", + "mapAttackFromLeft": "AvWattak.def:0:271", "animation": "CRSDGN.DEF" }, "sound" : @@ -423,6 +435,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:272", + "mapAttackFromLeft": "AvWattak.def:0:273", "animation": "Cench.DEF", "missile" : { @@ -464,6 +478,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:274", + "mapAttackFromLeft": "AvWattak.def:0:275", "animation": "CSHARP.DEF", "missile" : { @@ -501,6 +517,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:276", + "mapAttackFromLeft": "AvWattak.def:0:277", "animation": "CHALF.DEF", "missile" : { @@ -524,6 +542,8 @@ "faction": "neutral", "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:278", + "mapAttackFromLeft": "AvWattak.def:0:279", "animation": "CPEAS.DEF" }, "sound" : @@ -543,6 +563,8 @@ "doubleWide" : true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:280", + "mapAttackFromLeft": "AvWattak.def:0:281", "animation": "CBOAR.DEF" }, "sound" : @@ -574,6 +596,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:282", + "mapAttackFromLeft": "AvWattak.def:0:283", "animation": "CMUMMY.DEF" }, "sound" : @@ -602,6 +626,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:284", + "mapAttackFromLeft": "AvWattak.def:0:285", "animation": "CNOMAD.DEF" }, "sound" : @@ -647,6 +673,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:286", + "mapAttackFromLeft": "AvWattak.def:0:287", "animation": "CROGUE.DEF" }, "sound" : @@ -673,6 +701,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:288", + "mapAttackFromLeft": "AvWattak.def:0:289", "animation": "CTROLL.DEF" }, "sound" : diff --git a/config/creatures/rampart.json b/config/creatures/rampart.json index 1cd0de0b9..2a451035f 100644 --- a/config/creatures/rampart.json +++ b/config/creatures/rampart.json @@ -10,6 +10,8 @@ "graphics" : { "missile" : null, + "mapAttackFromRight": "AvWattak.def:0:28", + "mapAttackFromLeft": "AvWattak.def:0:29", "animation": "CCENTR.DEF" }, "sound" : @@ -31,6 +33,8 @@ "graphics" : { "missile" : null, + "mapAttackFromRight": "AvWattak.def:0:30", + "mapAttackFromLeft": "AvWattak.def:0:31", "animation": "CECENT.DEF" }, "sound" : @@ -58,6 +62,8 @@ "upgrades": ["battleDwarf"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:32", + "mapAttackFromLeft": "AvWattak.def:0:33", "animation": "CDWARF.DEF" }, "sound" : @@ -84,6 +90,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:34", + "mapAttackFromLeft": "AvWattak.def:0:35", "animation": "CBDWAR.DEF" }, "sound" : @@ -111,6 +119,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:36", + "mapAttackFromLeft": "AvWattak.def:0:37", "animation": "CELF.DEF", "missile" : { @@ -149,6 +159,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:38", + "mapAttackFromLeft": "AvWattak.def:0:39", "animation": "CGRELF.DEF", "missile" : { @@ -187,6 +199,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:40", + "mapAttackFromLeft": "AvWattak.def:0:41", "animation": "CPEGAS.DEF" }, "sound" : @@ -218,6 +232,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:42", + "mapAttackFromLeft": "AvWattak.def:0:43", "animation": "CAPEGS.DEF" }, "sound" : @@ -246,6 +262,8 @@ "upgrades": ["dendroidSoldier"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:44", + "mapAttackFromLeft": "AvWattak.def:0:45", "animation": "CTREE.DEF" }, "sound" : @@ -273,6 +291,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:46", + "mapAttackFromLeft": "AvWattak.def:0:47", "animation": "CBTREE.DEF" }, "sound" : @@ -308,6 +328,8 @@ "upgrades": ["warUnicorn"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:48", + "mapAttackFromLeft": "AvWattak.def:0:49", "animation": "CUNICO.DEF" }, "sound" : @@ -342,6 +364,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:50", + "mapAttackFromLeft": "AvWattak.def:0:51", "animation": "CWUNIC.DEF" }, "sound" : @@ -393,6 +417,8 @@ "upgrades": ["goldDragon"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:52", + "mapAttackFromLeft": "AvWattak.def:0:53", "animation": "CGDRAG.DEF" }, "sound" : @@ -442,6 +468,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:54", + "mapAttackFromLeft": "AvWattak.def:0:55", "animation": "CDDRAG.DEF" }, "sound" : diff --git a/config/creatures/stronghold.json b/config/creatures/stronghold.json index 7824a2b58..f85ebf420 100644 --- a/config/creatures/stronghold.json +++ b/config/creatures/stronghold.json @@ -8,6 +8,8 @@ "upgrades": ["hobgoblin"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:168", + "mapAttackFromLeft": "AvWattak.def:0:169", "animation": "CGOBLI.DEF" }, "sound" : @@ -27,6 +29,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:170", + "mapAttackFromLeft": "AvWattak.def:0:171", "animation": "CHGOBL.DEF" }, "sound" : @@ -48,6 +52,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:172", + "mapAttackFromLeft": "AvWattak.def:0:173", "animation": "CBWLFR.DEF" }, "sound" : @@ -75,6 +81,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:174", + "mapAttackFromLeft": "AvWattak.def:0:175", "animation": "CUWLFR.DEF" }, "sound" : @@ -102,6 +110,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:176", + "mapAttackFromLeft": "AvWattak.def:0:177", "animation": "CORC.DEF", "missile" : { @@ -133,6 +143,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:178", + "mapAttackFromLeft": "AvWattak.def:0:179", "animation": "CORCCH.DEF", "missile" : { @@ -157,6 +169,8 @@ "upgrades": ["ogreMage"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:180", + "mapAttackFromLeft": "AvWattak.def:0:181", "animation": "COGRE.DEF" }, "sound" : @@ -194,6 +208,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:182", + "mapAttackFromLeft": "AvWattak.def:0:183", "animation": "COGMAG.DEF" }, "sound" : @@ -222,6 +238,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:184", + "mapAttackFromLeft": "AvWattak.def:0:185", "animation": "CROC.DEF" }, "sound" : @@ -260,6 +278,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:186", + "mapAttackFromLeft": "AvWattak.def:0:187", "animation": "CTBIRD.DEF" }, "sound" : @@ -292,6 +312,8 @@ "upgrades": ["cyclopKing"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:188", + "mapAttackFromLeft": "AvWattak.def:0:189", "animation": "CCYCLR.DEF", "missile" : { @@ -335,6 +357,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:190", + "mapAttackFromLeft": "AvWattak.def:0:191", "animation": "CCYCLLOR.DEF", "missile" : { @@ -373,6 +397,8 @@ "upgrades": ["ancientBehemoth"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:192", + "mapAttackFromLeft": "AvWattak.def:0:193", "animation": "CYBEHE.DEF" }, "sound" : @@ -405,6 +431,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:194", + "mapAttackFromLeft": "AvWattak.def:0:195", "animation": "CABEHE.DEF" }, "sound" : diff --git a/config/creatures/tower.json b/config/creatures/tower.json index 99781a907..84bcef6e6 100644 --- a/config/creatures/tower.json +++ b/config/creatures/tower.json @@ -9,6 +9,8 @@ "hasDoubleWeek": true, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:56", + "mapAttackFromLeft": "AvWattak.def:0:57", "animation": "CGREMA.DEF" }, "sound" : @@ -36,6 +38,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:58", + "mapAttackFromLeft": "AvWattak.def:0:59", "animation": "CGREMM.DEF", "missile" : { @@ -71,6 +75,8 @@ "upgrades": ["obsidianGargoyle"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:60", + "mapAttackFromLeft": "AvWattak.def:0:61", "animation": "CGARGO.DEF" }, "sound" : @@ -100,6 +106,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:62", + "mapAttackFromLeft": "AvWattak.def:0:63", "animation": "COGARG.DEF" }, "sound" : @@ -132,6 +140,8 @@ "upgrades": ["stoneGolem"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:64", + "mapAttackFromLeft": "AvWattak.def:0:65", "animation": "CSGOLE.DEF" }, "sound" : @@ -163,6 +173,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:66", + "mapAttackFromLeft": "AvWattak.def:0:67", "animation": "CIGOLE.DEF" }, "sound" : @@ -199,6 +211,8 @@ "upgrades": ["archMage"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:68", + "mapAttackFromLeft": "AvWattak.def:0:69", "animation": "CMAGE.DEF", "missile" : { @@ -243,6 +257,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:70", + "mapAttackFromLeft": "AvWattak.def:0:71", "animation": "CAMAGE.DEF", "missile" : { @@ -294,6 +310,8 @@ "upgrades": ["masterGenie"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:72", + "mapAttackFromLeft": "AvWattak.def:0:73", "animation": "CGENIE.DEF" }, "sound" : @@ -346,6 +364,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:74", + "mapAttackFromLeft": "AvWattak.def:0:75", "animation": "CSULTA.DEF" }, "sound" : @@ -374,6 +394,8 @@ "upgrades": ["nagaQueen"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:76", + "mapAttackFromLeft": "AvWattak.def:0:77", "animation": "CNAGA.DEF" }, "sound" : @@ -400,6 +422,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:78", + "mapAttackFromLeft": "AvWattak.def:0:79", "animation": "CNAGAG.DEF" }, "sound" : @@ -431,6 +455,8 @@ "upgrades": ["titan"], "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:80", + "mapAttackFromLeft": "AvWattak.def:0:81", "animation": "CLTITA.DEF" }, "sound" : @@ -476,6 +502,8 @@ }, "graphics" : { + "mapAttackFromRight": "AvWattak.def:0:82", + "mapAttackFromLeft": "AvWattak.def:0:83", "animation": "CGTITA.DEF", "missile" : { diff --git a/config/schemas/creature.json b/config/schemas/creature.json index 19c218a39..dee7b063b 100644 --- a/config/schemas/creature.json +++ b/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", diff --git a/docs/modders/Entities_Format/Creature_Format.md b/docs/modders/Entities_Format/Creature_Format.md index 66cb5a83d..b308e4c7c 100644 --- a/docs/modders/Entities_Format/Creature_Format.md +++ b/docs/modders/Entities_Format/Creature_Format.md @@ -128,6 +128,10 @@ In order to make functional creature you also need: "iconSmall" : "", // Large icon for this creature, used for example in town screen "iconLarge" : "", + + // Optional. Images of creatures when attacked on adventure map + "mapAttackFromRight": "", + "mapAttackFromLeft": "", // animation parameters diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index c8c3c2eaa..aa2309842 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -902,6 +902,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"]); for(const auto & ability : config["abilities"].Struct()) { diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 4ba246eef..3ee4879c4 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -67,6 +67,8 @@ public: std::set 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 diff --git a/lib/callback/CBattleCallback.cpp b/lib/callback/CBattleCallback.cpp index a603f4bfd..5908fe6e9 100644 --- a/lib/callback/CBattleCallback.cpp +++ b/lib/callback/CBattleCallback.cpp @@ -79,6 +79,11 @@ void CBattleCallback::onBattleEnded(const BattleID & battleID) activeBattles.erase(battleID); } +std::map> CBattleCallback::getActiveBattles() +{ + return activeBattles; +} + void CBattleCallback::battleMakeSpellAction(const BattleID & battleID, const BattleAction & action) { assert(action.actionType == EActionType::HERO_SPELL); diff --git a/lib/callback/CBattleCallback.h b/lib/callback/CBattleCallback.h index c34110788..0d524fec6 100644 --- a/lib/callback/CBattleCallback.h +++ b/lib/callback/CBattleCallback.h @@ -39,6 +39,7 @@ public: void onBattleStarted(const IBattleInfo * info); void onBattleEnded(const BattleID & battleID); + std::map> getActiveBattles(); }; VCMI_LIB_NAMESPACE_END