diff --git a/client/CGameInfo.cpp b/client/CGameInfo.cpp index 3c8eb86fb..d8c58296a 100644 --- a/client/CGameInfo.cpp +++ b/client/CGameInfo.cpp @@ -38,6 +38,7 @@ void CGameInfo::setFromLib() skillh = VLC->skillh; objtypeh = VLC->objtypeh; battleFieldHandler = VLC->battlefieldsHandler; + obstacleHandler = VLC->obstacleHandler; } const ArtifactService * CGameInfo::artifacts() const @@ -85,6 +86,11 @@ const SkillService * CGameInfo::skills() const return globalServices->skills(); } +const ObstacleService * CGameInfo::obstacles() const +{ + return globalServices->obstacles(); +} + void CGameInfo::updateEntity(Metatype metatype, int32_t index, const JsonNode & data) { logGlobal->error("CGameInfo::updateEntity call is not expected."); diff --git a/client/CGameInfo.h b/client/CGameInfo.h index b93924873..70b56905c 100644 --- a/client/CGameInfo.h +++ b/client/CGameInfo.h @@ -32,6 +32,7 @@ class CGameState; class IMainVideoPlayer; class CServerHandler; class BattleFieldHandler; +class ObstacleHandler; class CMap; @@ -62,6 +63,7 @@ public: const spells::Service * spells() const override; const SkillService * skills() const override; const BattleFieldService * battlefields() const override; + const ObstacleService * obstacles() const override; void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override; @@ -77,6 +79,7 @@ public: ConstTransitivePtr skillh; ConstTransitivePtr objh; ConstTransitivePtr objtypeh; + ConstTransitivePtr obstacleHandler; CGeneralTextHandler * generaltexth; CMapHandler * mh; CTownHandler * townh; diff --git a/client/battle/CBattleInterface.cpp b/client/battle/CBattleInterface.cpp index b416578ba..50d41a8c3 100644 --- a/client/battle/CBattleInterface.cpp +++ b/client/battle/CBattleInterface.cpp @@ -42,6 +42,7 @@ #include "../../lib/spells/Problem.h" #include "../../lib/CTownHandler.h" #include "../../lib/BattleFieldHandler.h" +#include "../../lib/ObstacleHandler.h" #include "../../lib/CGameState.h" #include "../../lib/mapping/CMap.h" #include "../../lib/NetPacks.h" @@ -361,7 +362,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet { if(elem->obstacleType == CObstacleInstance::USUAL) { - std::string animationName = elem->getInfo().defName; + std::string animationName = elem->getInfo().animation; auto cached = animationsCache.find(animationName); @@ -379,7 +380,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet } else if (elem->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) { - std::string animationName = elem->getInfo().defName; + std::string animationName = elem->getInfo().animation; auto cached = animationsCache.find(animationName); diff --git a/config/gameConfig.json b/config/gameConfig.json index 186029a94..a8e5bc71b 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -88,5 +88,9 @@ "battlefields": [ "config/battlefields.json" + ], + "obstacles": + [ + "config/obstacles.json" ] } diff --git a/config/obstacles.json b/config/obstacles.json index 22a944f3c..e5105febf 100644 --- a/config/obstacles.json +++ b/config/obstacles.json @@ -8,1228 +8,1349 @@ // * "blockedTiles": for absolute obstacles contains absolute coordinates. For usual obstacles contains offsets relative to the obstacle position (that is bottom left corner). If obstacle is placed in an odd row (counting from 0) and the blocked tile is in an even row, position will be shifted one tile to the left. Thanks to that ie. -16 is always top-right hex, no matter where the obstale will get placed. // * "width" for usual obstacles it's count of tiles that must be free to the right for obstacle to be placed. For absolute obstacles, it's x offset for the graphics. // * "height" for usual obstacles it's count of tiles that must be free to the top for obstacle to be placed. For absolute obstacles, it's y offset for the graphics. -// * "defname" is name of the graphics. It's def file for usual obstacles and bitmap for the absolute ones. +// * "animation" is name of the graphics. It's def file for usual obstacles and bitmap for the absolute ones. { -"obstacles" : [ + "0": { - "id" : 0, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObDino1.def", - "unknown" : 1 + "animation" : "ObDino1.def", + "unknown" : 1, + "absolute" : false }, + "1": { - "id" : 1, "allowedTerrain" : ["dirt", "sand", "rough", "subterra"], "specialBattlefields" : ["sand_shore"], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObDino2.def", - "unknown" : 0 + "animation" : "ObDino2.def", + "unknown" : 0, + "absolute" : false }, + "2": { - "id" : 2, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 4, "height" : 2, "blockedTiles" : [0, 1, -14, -15, -16], - "defname" : "ObDino3.def", - "unknown" : 1 + "animation" : "ObDino3.def", + "unknown" : 1, + "absolute" : false }, + "3": { - "id" : 3, "allowedTerrain" : ["dirt", "rough"], "specialBattlefields" : ["cursed_ground"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObSkel1.def", - "unknown" : 1 + "animation" : "ObSkel1.def", + "unknown" : 1, + "absolute" : false }, + "4": { - "id" : 4, "allowedTerrain" : ["dirt", "rough", "subterra"], "specialBattlefields" : ["sand_shore", "cursed_ground"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObSkel2.def", - "unknown" : 1 + "animation" : "ObSkel2.def", + "unknown" : 1, + "absolute" : false }, + "5": { - "id" : 5, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 4, "height" : 2, "blockedTiles" : [1, 2, 3], - "defname" : "ObBDT01.def", - "unknown" : 1 + "animation" : "ObBDT01.def", + "unknown" : 1, + "absolute" : false }, + "6": { - "id" : 6, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [-15, -16], - "defname" : "ObDRk01.def", - "unknown" : 1 + "animation" : "ObDRk01.def", + "unknown" : 1, + "absolute" : false }, + "7": { - "id" : 7, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 2, "blockedTiles" : [0, 1], - "defname" : "ObDRk02.def", - "unknown" : 0 + "animation" : "ObDRk02.def", + "unknown" : 0, + "absolute" : false }, + "8": { - "id" : 8, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 2, "blockedTiles" : [-16], - "defname" : "ObDRk03.def", - "unknown" : 1 + "animation" : "ObDRk03.def", + "unknown" : 1, + "absolute" : false }, + "9": { - "id" : 9, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 2, "blockedTiles" : [0, 1], - "defname" : "ObDRk04.def", - "unknown" : 0 + "animation" : "ObDRk04.def", + "unknown" : 0, + "absolute" : false }, + "10": { - "id" : 10, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 2, "blockedTiles" : [0, 1], - "defname" : "ObDSh01.def", - "unknown" : 0 + "animation" : "ObDSh01.def", + "unknown" : 0, + "absolute" : false }, + "11": { - "id" : 11, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObDTF03.def", - "unknown" : 0 + "animation" : "ObDTF03.def", + "unknown" : 0, + "absolute" : false }, + "12": { - "id" : 12, "allowedTerrain" : ["dirt", "rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 3, "blockedTiles" : [0, 1, 2, 3], - "defname" : "ObDtS03.def", - "unknown" : 0 + "animation" : "ObDtS03.def", + "unknown" : 0, + "absolute" : false }, + "13": { - "id" : 13, "allowedTerrain" : ["dirt", "rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 2, "blockedTiles" : [1, 2, -15], - "defname" : "ObDtS04.def", - "unknown" : 1 + "animation" : "ObDtS04.def", + "unknown" : 1, + "absolute" : false }, + "14": { - "id" : 14, "allowedTerrain" : ["dirt", "rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 2, "blockedTiles" : [2, -15, -16], - "defname" : "ObDtS14.def", - "unknown" : 1 + "animation" : "ObDtS14.def", + "unknown" : 1, + "absolute" : false }, + "15": { - "id" : 15, "allowedTerrain" : ["dirt", "rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 3, "blockedTiles" : [1, -16, -33], - "defname" : "ObDtS15.def", - "unknown" : 1 + "animation" : "ObDtS15.def", + "unknown" : 1, + "absolute" : false }, + "16": { - "id" : 16, "allowedTerrain" : ["sand"], "specialBattlefields" : [], "width" : 4, "height" : 4, "blockedTiles" : [-15, -16, -32, -33, -48, -49], - "defname" : "ObDsM01.def", - "unknown" : 1 + "animation" : "ObDsM01.def", + "unknown" : 1, + "absolute" : false }, + "17": { - "id" : 17, "allowedTerrain" : ["sand"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [1, -15, -16], - "defname" : "ObDsS02.def", - "unknown" : 1 + "animation" : "ObDsS02.def", + "unknown" : 1, + "absolute" : false }, + "18": { - "id" : 18, "allowedTerrain" : ["sand"], "specialBattlefields" : [], "width" : 4, "height" : 2, "blockedTiles" : [1, 2, 3, -15, -16], - "defname" : "ObDsS17.def", - "unknown" : 1 + "animation" : "ObDsS17.def", + "unknown" : 1, + "absolute" : false }, + "19": { - "id" : 19, "allowedTerrain" : ["grass", "swamp"], "specialBattlefields" : [], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObGLg01.def", - "unknown" : 1 + "animation" : "ObGLg01.def", + "unknown" : 1, + "absolute" : false }, + "20": { - "id" : 20, "allowedTerrain" : ["grass", "swamp"], "specialBattlefields" : ["magic_plains"], "width" : 2, "height" : 2, "blockedTiles" : [0, 1], - "defname" : "ObGRk01.def", - "unknown" : 0 + "animation" : "ObGRk01.def", + "unknown" : 0, + "absolute" : false }, + "21": { - "id" : 21, "allowedTerrain" : ["grass", "swamp"], "specialBattlefields" : [], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObGSt01.def", - "unknown" : 1 + "animation" : "ObGSt01.def", + "unknown" : 1, + "absolute" : false }, + "22": { - "id" : 22, "allowedTerrain" : ["grass"], "specialBattlefields" : ["magic_plains"], "width" : 6, "height" : 2, "blockedTiles" : [1, 2, 3, 4, -13, -14, -15, -16], - "defname" : "ObGrS01.def", - "unknown" : 1 + "animation" : "ObGrS01.def", + "unknown" : 1, + "absolute" : false }, + "23": { - "id" : 23, "allowedTerrain" : ["grass"], "specialBattlefields" : [], "width" : 7, "height" : 1, "blockedTiles" : [1, 2], - "defname" : "OBGrS02.def", - "unknown" : 1 + "animation" : "OBGrS02.def", + "unknown" : 1, + "absolute" : false }, + "24": { - "id" : 24, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 1, "blockedTiles" : [0, 1, 2], - "defname" : "ObSnS01.def", - "unknown" : 1 + "animation" : "ObSnS01.def", + "unknown" : 1, + "absolute" : false }, + "25": { - "id" : 25, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 5, "height" : 1, "blockedTiles" : [1, 2, 3, 4], - "defname" : "ObSnS02.def", - "unknown" : 1 + "animation" : "ObSnS02.def", + "unknown" : 1, + "absolute" : false }, + "26": { - "id" : 26, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 3, "blockedTiles" : [0, -16, -33], - "defname" : "ObSnS03.def", - "unknown" : 1 + "animation" : "ObSnS03.def", + "unknown" : 1, + "absolute" : false }, + "27": { - "id" : 27, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 1, "blockedTiles" : [0, 1, 2], - "defname" : "ObSnS04.def", - "unknown" : 1 + "animation" : "ObSnS04.def", + "unknown" : 1, + "absolute" : false }, + "28": { - "id" : 28, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 1, "blockedTiles" : [1], - "defname" : "ObSnS05.def", - "unknown" : 1 + "animation" : "ObSnS05.def", + "unknown" : 1, + "absolute" : false }, + "29": { - "id" : 29, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [1, 2], - "defname" : "ObSnS06.def", - "unknown" : 0 + "animation" : "ObSnS06.def", + "unknown" : 0, + "absolute" : false }, + "30": { - "id" : 30, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObSnS07.def", - "unknown" : 1 + "animation" : "ObSnS07.def", + "unknown" : 1, + "absolute" : false }, + "31": { - "id" : 31, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObSnS08.def", - "unknown" : 0 + "animation" : "ObSnS08.def", + "unknown" : 0, + "absolute" : false }, + "32": { - "id" : 32, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 7, "height" : 2, "blockedTiles" : [2, 3, 4, 5, -13, -14, -15, -16], - "defname" : "ObSnS09.def", - "unknown" : 1 + "animation" : "ObSnS09.def", + "unknown" : 1, + "absolute" : false }, + "33": { - "id" : 33, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 5, "height" : 5, "blockedTiles" : [3, -13, -14, -15, -33, -49, -66], - "defname" : "ObSnS10.def", - "unknown" : 1 + "animation" : "ObSnS10.def", + "unknown" : 1, + "absolute" : false }, + "34": { - "id" : 34, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 2, "height" : 2, "blockedTiles" : [0], - "defname" : "ObSwS01.def", - "unknown" : 0 + "animation" : "ObSwS01.def", + "unknown" : 0, + "absolute" : false }, + "35": { - "id" : 35, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 8, "height" : 3, "blockedTiles" : [-10, -11, -12, -13, -14, -15, -16], - "defname" : "ObSwS02.def", - "unknown" : 1 + "animation" : "ObSwS02.def", + "unknown" : 1, + "absolute" : false }, + "36": { - "id" : 36, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObSwS03.def", - "unknown" : 0 + "animation" : "ObSwS03.def", + "unknown" : 0, + "absolute" : false }, + "37": { - "id" : 37, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 3, "height" : 1, "blockedTiles" : [0, 1, 2], - "defname" : "ObSwS04.def", - "unknown" : 0 + "animation" : "ObSwS04.def", + "unknown" : 0, + "absolute" : false }, + "38": { - "id" : 38, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 5, "height" : 4, "blockedTiles" : [-13, -14, -15, -16, -30, -31, -32, -33], - "defname" : "ObSwS11b.def", - "unknown" : 1 + "animation" : "ObSwS11b.def", + "unknown" : 1, + "absolute" : false }, + "39": { - "id" : 39, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 4, "height" : 3, "blockedTiles" : [-16, -17, -31, -32, -33, -34], - "defname" : "ObSwS13a.def", - "unknown" : 1 + "animation" : "ObSwS13a.def", + "unknown" : 1, + "absolute" : false }, + "40": { - "id" : 40, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 2, "height" : 2, "blockedTiles" : [0, 1, -16], - "defname" : "ObRgS01.def", - "unknown" : 1 + "animation" : "ObRgS01.def", + "unknown" : 1, + "absolute" : false }, + "41": { - "id" : 41, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 4, "height" : 3, "blockedTiles" : [-14, -15, -16, -32, -33], - "defname" : "ObRgS02.def", - "unknown" : 1 + "animation" : "ObRgS02.def", + "unknown" : 1, + "absolute" : false }, + "42": { - "id" : 42, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 2, "blockedTiles" : [1, 2, -15, -16], - "defname" : "ObRgS03.def", - "unknown" : 1 + "animation" : "ObRgS03.def", + "unknown" : 1, + "absolute" : false }, + "43": { - "id" : 43, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 3, "blockedTiles" : [-16, -32, -33], - "defname" : "ObRgS04.def", - "unknown" : 1 + "animation" : "ObRgS04.def", + "unknown" : 1, + "absolute" : false }, + "44": { - "id" : 44, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 3, "height" : 3, "blockedTiles" : [-15, -16, -32], - "defname" : "ObRgS05.def", - "unknown" : 1 + "animation" : "ObRgS05.def", + "unknown" : 1, + "absolute" : false }, + "45": { - "id" : 45, "allowedTerrain" : ["subterra"], "specialBattlefields" : [], "width" : 3, "height" : 3, "blockedTiles" : [0, 1, 2, -15, -16], - "defname" : "ObSuS01.def", - "unknown" : 0 + "animation" : "ObSuS01.def", + "unknown" : 0, + "absolute" : false }, + "46": { - "id" : 46, "allowedTerrain" : ["subterra"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObSuS02.def", - "unknown" : 0 + "animation" : "ObSuS02.def", + "unknown" : 0, + "absolute" : false }, + "47": { - "id" : 47, "allowedTerrain" : ["subterra"], "specialBattlefields" : [], "width" : 4, "height" : 3, "blockedTiles" : [0, 1, 2, 3, -14, -15, -16], - "defname" : "ObSuS11b.def", - "unknown" : 0 + "animation" : "ObSuS11b.def", + "unknown" : 0, + "absolute" : false }, + "48": { - "id" : 48, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 4, "height" : 3, "blockedTiles" : [-14, -32, -33], - "defname" : "ObLvS01.def", - "unknown" : 1 + "animation" : "ObLvS01.def", + "unknown" : 1, + "absolute" : false }, + "49": { - "id" : 49, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 4, "height" : 2, "blockedTiles" : [0, 1, 2, -14, -15, -16], - "defname" : "ObLvS02.def", - "unknown" : 1 + "animation" : "ObLvS02.def", + "unknown" : 1, + "absolute" : false }, + "50": { - "id" : 50, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 5, "height" : 3, "blockedTiles" : [-13, -14, -15, -30, -31, -32, -33], - "defname" : "ObLvS03.def", - "unknown" : 1 + "animation" : "ObLvS03.def", + "unknown" : 1, + "absolute" : false }, + "51": { - "id" : 51, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObLvS04.def", - "unknown" : 0 + "animation" : "ObLvS04.def", + "unknown" : 0, + "absolute" : false }, + "52": { - "id" : 52, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 4, "height" : 4, "blockedTiles" : [-14, -15, -32, -33, -49, -50], - "defname" : "ObLvS09.def", - "unknown" : 1 + "animation" : "ObLvS09.def", + "unknown" : 1, + "absolute" : false }, + "53": { - "id" : 53, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 5, "height" : 3, "blockedTiles" : [-13, -14, -15, -16, -30, -31], - "defname" : "ObLvS17.def", - "unknown" : 1 + "animation" : "ObLvS17.def", + "unknown" : 1, + "absolute" : false }, + "54": { - "id" : 54, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 5, "height" : 3, "blockedTiles" : [-13, -14, -15, -16, -31, -32, -33], - "defname" : "ObLvS22.def", - "unknown" : 1 + "animation" : "ObLvS22.def", + "unknown" : 1, + "absolute" : false }, + "55": { - "id" : 55, "allowedTerrain" : ["water"], "specialBattlefields" : [], "width" : 3, "height" : 3, "blockedTiles" : [-15, -16, -33], - "defname" : "ObBtS04.def", - "unknown" : 1 + "animation" : "ObBtS04.def", + "unknown" : 1, + "absolute" : false }, + "56": { - "id" : 56, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 3, "height" : 2, "blockedTiles" : [1, -15, -16], - "defname" : "ObBhS02.def", - "unknown" : 1 + "animation" : "ObBhS02.def", + "unknown" : 1, + "absolute" : false }, + "57": { - "id" : 57, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObBhS03.def", - "unknown" : 0 + "animation" : "ObBhS03.def", + "unknown" : 0, + "absolute" : false }, + "58": { - "id" : 58, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 5, "height" : 2, "blockedTiles" : [1, 2, 3, -14, -15, -16], - "defname" : "ObBhS11a.def", - "unknown" : 1 + "animation" : "ObBhS11a.def", + "unknown" : 1, + "absolute" : false }, + "59": { - "id" : 59, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 4, "height" : 2, "blockedTiles" : [1, 2, -14, -15], - "defname" : "ObBhS12b.def", - "unknown" : 1 + "animation" : "ObBhS12b.def", + "unknown" : 1, + "absolute" : false }, + "60": { - "id" : 60, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 2, "height" : 2, "blockedTiles" : [0, 1, -16], - "defname" : "ObBhS14b.def", - "unknown" : 1 + "animation" : "ObBhS14b.def", + "unknown" : 1, + "absolute" : false }, + "61": { - "id" : 61, "allowedTerrain" : [], "specialBattlefields" : ["holy_ground"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObHGs00.def", - "unknown" : 0 + "animation" : "ObHGs00.def", + "unknown" : 0, + "absolute" : false }, + "62": { - "id" : 62, "allowedTerrain" : [], "specialBattlefields" : ["holy_ground"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObHGs01.def", - "unknown" : 0 + "animation" : "ObHGs01.def", + "unknown" : 0, + "absolute" : false }, + "63": { - "id" : 63, "allowedTerrain" : [], "specialBattlefields" : ["holy_ground"], "width" : 3, "height" : 3, "blockedTiles" : [1], - "defname" : "ObHGs02.def", - "unknown" : 0 + "animation" : "ObHGs02.def", + "unknown" : 0, + "absolute" : false }, + "64": { - "id" : 64, "allowedTerrain" : [], "specialBattlefields" : ["holy_ground"], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObHGs03.def", - "unknown" : 0 + "animation" : "ObHGs03.def", + "unknown" : 0, + "absolute" : false }, + "65": { - "id" : 65, "allowedTerrain" : [], "specialBattlefields" : ["holy_ground"], "width" : 4, "height" : 3, "blockedTiles" : [0, 1, 2, 3], - "defname" : "ObHGs04.def", - "unknown" : 0 + "animation" : "ObHGs04.def", + "unknown" : 0, + "absolute" : false }, + "66": { - "id" : 66, "allowedTerrain" : [], "specialBattlefields" : ["evil_fog"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObEFs00.def", - "unknown" : 0 + "animation" : "ObEFs00.def", + "unknown" : 0, + "absolute" : false }, + "67": { - "id" : 67, "allowedTerrain" : [], "specialBattlefields" : ["evil_fog"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObEFs01.def", - "unknown" : 0 + "animation" : "ObEFs01.def", + "unknown" : 0, + "absolute" : false }, + "68": { - "id" : 68, "allowedTerrain" : [], "specialBattlefields" : ["evil_fog"], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2], - "defname" : "ObEFs02.def", - "unknown" : 0 + "animation" : "ObEFs02.def", + "unknown" : 0, + "absolute" : false }, + "69": { - "id" : 69, "allowedTerrain" : [], "specialBattlefields" : ["evil_fog"], "width" : 4, "height" : 2, "blockedTiles" : [1, 2], - "defname" : "ObEFs03.def", - "unknown" : 0 + "animation" : "ObEFs03.def", + "unknown" : 0, + "absolute" : false }, + "70": { - "id" : 70, "allowedTerrain" : [], "specialBattlefields" : ["evil_fog"], "width" : 6, "height" : 2, "blockedTiles" : [1, 2, 3, -12, -13], - "defname" : "ObEFs04.def", - "unknown" : 0 + "animation" : "ObEFs04.def", + "unknown" : 0, + "absolute" : false }, + "71": { - "id" : 71, "allowedTerrain" : [], "specialBattlefields" : ["clover_field"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObCFs00.def", - "unknown" : 1 + "animation" : "ObCFs00.def", + "unknown" : 1, + "absolute" : false }, + "72": { - "id" : 72, "allowedTerrain" : [], "specialBattlefields" : ["clover_field"], "width" : 3, "height" : 1, "blockedTiles" : [0, 1, 2], - "defname" : "ObCFs01.def", - "unknown" : 1 + "animation" : "ObCFs01.def", + "unknown" : 1, + "absolute" : false }, + "73": { - "id" : 73, "allowedTerrain" : [], "specialBattlefields" : ["clover_field"], "width" : 3, "height" : 2, "blockedTiles" : [1, 2, -15, -16], - "defname" : "ObCFs02.def", - "unknown" : 1 + "animation" : "ObCFs02.def", + "unknown" : 1, + "absolute" : false }, + "74": { - "id" : 74, "allowedTerrain" : [], "specialBattlefields" : ["clover_field"], "width" : 4, "height" : 2, "blockedTiles" : [0, 1, 2, -14, -15, -16], - "defname" : "ObCFs03.def", - "unknown" : 1 + "animation" : "ObCFs03.def", + "unknown" : 1, + "absolute" : false }, + "75": { - "id" : 75, "allowedTerrain" : [], "specialBattlefields" : ["lucid_pools"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObLPs00.def", - "unknown" : 1 + "animation" : "ObLPs00.def", + "unknown" : 1, + "absolute" : false }, + "76": { - "id" : 76, "allowedTerrain" : [], "specialBattlefields" : ["lucid_pools"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObLPs01.def", - "unknown" : 1 + "animation" : "ObLPs01.def", + "unknown" : 1, + "absolute" : false }, + "77": { - "id" : 77, "allowedTerrain" : [], "specialBattlefields" : ["lucid_pools"], "width" : 3, "height" : 2, "blockedTiles" : [0, -15, -16], - "defname" : "ObLPs02.def", - "unknown" : 1 + "animation" : "ObLPs02.def", + "unknown" : 1, + "absolute" : false }, + "78": { - "id" : 78, "allowedTerrain" : [], "specialBattlefields" : ["lucid_pools"], "width" : 5, "height" : 2, "blockedTiles" : [1, 2, 3, -13, -14, -15, -16], - "defname" : "ObLPs03.def", - "unknown" : 1 + "animation" : "ObLPs03.def", + "unknown" : 1, + "absolute" : false }, + "79": { - "id" : 79, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObFFs00.def", - "unknown" : 0 + "animation" : "ObFFs00.def", + "unknown" : 0, + "absolute" : false }, + "80": { - "id" : 80, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObFFs01.def", - "unknown" : 0 + "animation" : "ObFFs01.def", + "unknown" : 0, + "absolute" : false }, + "81": { - "id" : 81, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 3, "height" : 2, "blockedTiles" : [0, 1, 2, -15], - "defname" : "ObFFs02.def", - "unknown" : 0 + "animation" : "ObFFs02.def", + "unknown" : 0, + "absolute" : false }, + "82": { - "id" : 82, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 4, "height" : 2, "blockedTiles" : [1, 2, 3, -15, -16], - "defname" : "ObFFs03.def", - "unknown" : 0 + "animation" : "ObFFs03.def", + "unknown" : 0, + "absolute" : false }, + "83": { - "id" : 83, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 3, "height" : 3, "blockedTiles" : [0, 1, 2, 3, -14, -15, -16], - "defname" : "ObFFs04.def", - "unknown" : 0 + "animation" : "ObFFs04.def", + "unknown" : 0, + "absolute" : false }, + "84": { - "id" : 84, "allowedTerrain" : [], "specialBattlefields" : ["rocklands"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObRLs00.def", - "unknown" : 0 + "animation" : "ObRLs00.def", + "unknown" : 0, + "absolute" : false }, + "85": { - "id" : 85, "allowedTerrain" : [], "specialBattlefields" : ["rocklands"], "width" : 2, "height" : 1, "blockedTiles" : [0, 1], - "defname" : "ObRLs01.def", - "unknown" : 0 + "animation" : "ObRLs01.def", + "unknown" : 0, + "absolute" : false }, + "86": { - "id" : 86, "allowedTerrain" : [], "specialBattlefields" : ["rocklands"], "width" : 3, "height" : 1, "blockedTiles" : [0, 1, 2], - "defname" : "ObRLs02.def", - "unknown" : 0 + "animation" : "ObRLs02.def", + "unknown" : 0, + "absolute" : false }, + "87": { - "id" : 87, "allowedTerrain" : [], "specialBattlefields" : ["rocklands"], "width" : 4, "height" : 2, "blockedTiles" : [1, 2, 3, -15, -16], - "defname" : "ObRLs03.def", - "unknown" : 0 + "animation" : "ObRLs03.def", + "unknown" : 0, + "absolute" : false }, + "88": { - "id" : 88, "allowedTerrain" : [], "specialBattlefields" : ["magic_clouds"], "width" : 1, "height" : 1, "blockedTiles" : [0], - "defname" : "ObMCs00.def", - "unknown" : 1 + "animation" : "ObMCs00.def", + "unknown" : 1, + "absolute" : false }, + "89": { - "id" : 89, "allowedTerrain" : [], "specialBattlefields" : ["magic_clouds"], "width" : 2, "height" : 2, "blockedTiles" : [1, -16], - "defname" : "ObMCs01.def", - "unknown" : 1 + "animation" : "ObMCs01.def", + "unknown" : 1, + "absolute" : false }, + "90": { - "id" : 90, "allowedTerrain" : [], "specialBattlefields" : ["magic_clouds"], "width" : 4, "height" : 2, "blockedTiles" : [0, 1, -14, -15], - "defname" : "ObMCs02.def", - "unknown" : 1 - } -], -"absoluteObstacles" : [ + "animation" : "ObMCs02.def", + "unknown" : 1, + "absolute" : false + }, + + "100": { - "id" : 0, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 124, "height" : 254, "blockedTiles" : [80, 94, 95, 96, 97, 105, 106, 107, 108, 109, 110], - "defname" : "ObDtL04.pcx" + "animation" : "ObDtL04.pcx", + "absolute" : true }, + "101": { - "id" : 1, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 256, "height" : 254, "blockedTiles" : [73, 91, 108, 109, 110, 111, 112, 113], - "defname" : "ObDtL06.pcx" + "animation" : "ObDtL06.pcx", + "absolute" : true }, + "102": { - "id" : 2, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 168, "height" : 212, "blockedTiles" : [60, 61, 62, 63, 64, 72, 73, 74, 75, 76, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149], - "defname" : "ObDtL10.pcx" + "animation" : "ObDtL10.pcx", + "absolute" : true }, + "103": { - "id" : 3, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 124, "height" : 254, "blockedTiles" : [88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98], - "defname" : "ObDtL02.pcx" + "animation" : "ObDtL02.pcx", + "absolute" : true }, + "104": { - "id" : 4, "allowedTerrain" : ["dirt"], "specialBattlefields" : [], "width" : 146, "height" : 254, "blockedTiles" : [76, 77, 78, 79, 80, 89, 90, 91, 92, 93], - "defname" : "ObDtL03.pcx" + "animation" : "ObDtL03.pcx", + "absolute" : true }, + "105": { - "id" : 5, "allowedTerrain" : ["grass"], "specialBattlefields" : [], "width" : 173, "height" : 221, "blockedTiles" : [55, 56, 57, 58, 75, 76, 77, 95, 112, 113, 131], - "defname" : "ObGrL01.pcx" + "animation" : "ObGrL01.pcx", + "absolute" : true }, + "106": { - "id" : 6, "allowedTerrain" : ["grass"], "specialBattlefields" : [], "width" : 180, "height" : 264, "blockedTiles" : [81, 91, 92, 93, 94, 95, 96, 97, 98, 106, 107, 123], - "defname" : "ObGrL02.pcx" + "animation" : "ObGrL02.pcx", + "absolute" : true }, + "107": { - "id" : 7, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 166, "height" : 255, "blockedTiles" : [76, 77, 78, 79, 91, 92, 93, 97, 98, 106, 107, 108], - "defname" : "ObSnL01.pcx" + "animation" : "ObSnL01.pcx", + "absolute" : true }, + "108": { - "id" : 8, "allowedTerrain" : ["snow"], "specialBattlefields" : [], "width" : 302, "height" : 172, "blockedTiles" : [41, 42, 43, 58, 75, 92, 108, 126, 143], - "defname" : "ObSnL14.pcx" + "animation" : "ObSnL14.pcx", + "absolute" : true }, + "109": { - "id" : 9, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 300, "height" : 170, "blockedTiles" : [40, 41, 58, 59, 74, 75, 92, 93, 109, 110, 111, 127, 128, 129, 130], - "defname" : "ObSwL15.pcx" + "animation" : "ObSwL15.pcx", + "absolute" : true }, + "110": { - "id" : 10, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 278, "height" : 171, "blockedTiles" : [43, 60, 61, 77, 93, 94, 95, 109, 110, 126, 127], - "defname" : "ObSwL14.pcx" + "animation" : "ObSwL14.pcx", + "absolute" : true }, + "111": { - "id" : 11, "allowedTerrain" : ["swamp"], "specialBattlefields" : [], "width" : 256, "height" : 254, "blockedTiles" : [74, 75, 76, 77, 91, 92, 93, 94, 95, 109, 110, 111, 112], - "defname" : "ObSwL22.pcx" + "animation" : "ObSwL22.pcx", + "absolute" : true }, + "112": { - "id" : 12, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 124, "height" : 254, "blockedTiles" : [77, 78, 79, 80, 81, 91, 92, 93, 94, 105, 106, 107], - "defname" : "ObLvL01.pcx" + "animation" : "ObLvL01.pcx", + "absolute" : true }, + "113": { - "id" : 13, "allowedTerrain" : ["lava"], "specialBattlefields" : [], "width" : 256, "height" : 128, "blockedTiles" : [43, 60, 61, 76, 77, 93, 109, 126, 127, 142, 143], - "defname" : "OBLvL02.pcx" + "animation" : "OBLvL02.pcx", + "absolute" : true }, + "114": { - "id" : 14, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 186, "height" : 212, "blockedTiles" : [55, 72, 90, 107, 125, 126, 127, 128, 129, 130, 131, 132], - "defname" : "ObRgL01.pcx" + "animation" : "ObRgL01.pcx", + "absolute" : true }, + "115": { - "id" : 15, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 347, "height" : 174, "blockedTiles" : [41, 59, 76, 94, 111, 129, 143, 144, 145], - "defname" : "ObRgL02.pcx" + "animation" : "ObRgL02.pcx", + "absolute" : true }, + "116": { - "id" : 16, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 294, "height" : 169, "blockedTiles" : [40, 41, 42, 43, 58, 75, 93, 110, 128, 145], - "defname" : "ObRgL03.pcx" + "animation" : "ObRgL03.pcx", + "absolute" : true }, + "117": { - "id" : 17, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 165, "height" : 257, "blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 89, 105], - "defname" : "ObRgL04.pcx" + "animation" : "ObRgL04.pcx", + "absolute" : true }, + "118": { - "id" : 18, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 208, "height" : 268, "blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 90, 91, 92, 93, 94, 95, 96, 97], - "defname" : "ObRgL05.pcx" + "animation" : "ObRgL05.pcx", + "absolute" : true }, + "119": { - "id" : 19, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 252, "height" : 254, "blockedTiles" : [73, 74, 75, 76, 77, 78, 91, 92, 93, 94], - "defname" : "ObRgL06.pcx" + "animation" : "ObRgL06.pcx", + "absolute" : true }, + "120": { - "id" : 20, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 278, "height" : 128, "blockedTiles" : [23, 40, 58, 75, 93, 110, 128, 145, 163], - "defname" : "ObRgL15.pcx" + "animation" : "ObRgL15.pcx", + "absolute" : true }, + "121": { - "id" : 21, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 208, "height" : 268, "blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 90, 91, 92, 93, 94, 95, 96, 97], - "defname" : "ObRgL05.pcx" + "animation" : "ObRgL05.pcx", + "absolute" : true }, + "122": { - "id" : 22, "allowedTerrain" : ["rough"], "specialBattlefields" : ["cursed_ground"], "width" : 168, "height" : 212, "blockedTiles" : [73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, 95, 96, 97, 106, 107, 108, 109, 110, 111, 112], - "defname" : "ObRgL22.pcx" + "animation" : "ObRgL22.pcx", + "absolute" : true }, + "123": { - "id" : 23, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 147, "height" : 264, "blockedTiles" : [72, 73, 74, 75, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98], - "defname" : "ObBhL02.pcx" + "animation" : "ObBhL02.pcx", + "absolute" : true }, + "124": { - "id" : 24, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 178, "height" : 262, "blockedTiles" : [71, 72, 73, 74, 75, 76, 77, 78, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98], - "defname" : "ObBhL03.pcx" + "animation" : "ObBhL03.pcx", + "absolute" : true }, + "125": { - "id" : 25, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 173, "height" : 257, "blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 89, 90, 105, 106], - "defname" : "ObBhL05.pcx" + "animation" : "ObBhL05.pcx", + "absolute" : true }, + "126": { - "id" : 26, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 241, "height" : 272, "blockedTiles" : [73, 91, 108, 109, 110, 111, 112, 113], - "defname" : "ObBhL06.pcx" + "animation" : "ObBhL06.pcx", + "absolute" : true }, + "127": { - "id" : 27, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 261, "height" : 129, "blockedTiles" : [27, 28, 43, 44, 60, 61, 76, 77, 93, 94, 109, 110, 126, 127, 142, 143, 159], - "defname" : "ObBhL14.pcx" + "animation" : "ObBhL14.pcx", + "absolute" : true }, + "128": { - "id" : 28, "allowedTerrain" : [], "specialBattlefields" : ["sand_shore"], "width" : 180, "height" : 154, "blockedTiles" : [22, 38, 39, 40, 44, 45, 46, 55, 56, 57, 62, 63, 123, 124, 125, 130, 131, 140, 141, 146, 147, 148], - "defname" : "ObBhL16.pcx" + "animation" : "ObBhL16.pcx", + "absolute" : true }, + "129": { - "id" : 29, "allowedTerrain" : [], "specialBattlefields" : ["clover_field"], "width" : 304, "height" : 264, "blockedTiles" : [76, 77, 92, 93, 94, 95, 109, 110, 111], - "defname" : "ObCFL00.pcx" + "animation" : "ObCFL00.pcx", + "absolute" : true }, + "130": { - "id" : 30, "allowedTerrain" : [], "specialBattlefields" : ["lucid_pools"], "width" : 256, "height" : 257, "blockedTiles" : [76, 77, 78, 92, 93, 94, 107, 108, 109], - "defname" : "ObLPL00.pcx" + "animation" : "ObLPL00.pcx", + "absolute" : true }, + "131": { - "id" : 31, "allowedTerrain" : [], "specialBattlefields" : ["fiery_fields"], "width" : 257, "height" : 255, "blockedTiles" : [76, 77, 91, 92, 93, 94, 95, 108, 109, 110, 111], - "defname" : "ObFFL00.pcx" + "animation" : "ObFFL00.pcx", + "absolute" : true }, + "132": { - "id" : 32, "allowedTerrain" : [], "specialBattlefields" : ["rocklands"], "width" : 277, "height" : 218, "blockedTiles" : [60, 61, 75, 76, 77, 91, 92, 93, 94, 95], - "defname" : "ObRLL00.pcx" + "animation" : "ObRLL00.pcx", + "absolute" : true }, + "133": { - "id" : 33, "allowedTerrain" : [], "specialBattlefields" : ["magic_clouds"], "width" : 300, "height" : 214, "blockedTiles" : [59, 60, 74, 75, 76, 93, 94, 95, 111, 112], - "defname" : "ObMCL00.pcx" + "animation" : "ObMCL00.pcx", + "absolute" : true } -] - } diff --git a/config/schemas/battlefield.json b/config/schemas/battlefield.json index 02aa0dcfd..4abd729d2 100644 --- a/config/schemas/battlefield.json +++ b/config/schemas/battlefield.json @@ -2,7 +2,7 @@ "type":"object", "$schema": "http://json-schema.org/draft-04/schema", "title" : "VCMI battlefield format", - "description" : "Format used to define new artifacts in VCMI", + "description" : "Format used to define new battlefields in VCMI", "required" : [ "graphics" ], "additionalProperties" : false, diff --git a/config/schemas/obstacle.json b/config/schemas/obstacle.json new file mode 100644 index 000000000..18cc76c10 --- /dev/null +++ b/config/schemas/obstacle.json @@ -0,0 +1,46 @@ +{ + "type":"object", + "$schema": "http://json-schema.org/draft-04/schema", + "title" : "VCMI obstacle format", + "description" : "Format used to define new obstacles in VCMI", + "required" : [ "animation" ], + + "additionalProperties" : false, + "properties":{ + "allowedTerrains": { + "type": "array", + "description": "Obstacles can be place on specified terrains only", + "items": { "type" : "string" } + }, + "specialBattlefields": { + "type": "array", + "description": "Obstacles can be placed on specified specified battlefields", + "items": { "$ref" : "battlefield.json" } + }, + "width": { + "type": "number", + "description": "Width ob obstacle" + }, + "height": { + "type": "number", + "description": "height if obstacle" + }, + "blockedTiles": { + "type": "array", + "description": "Blocked hexes - absolute or relative hex id", + "items": { "type" : "number" } + }, + "animation": { + "type": "string", + "description": "Image resource" + }, + "unknown": { + "type": "number", + "description": "Unknown field" + }, + "absolute": { + "type": "boolean", + "description": "Should be used absolute or relative coordinates for obstacle. There is possible only one absolute obstacle" + } + } +} diff --git a/include/vcmi/Services.h b/include/vcmi/Services.h index 1b567a824..7bd2a7bb0 100644 --- a/include/vcmi/Services.h +++ b/include/vcmi/Services.h @@ -20,6 +20,7 @@ class HeroTypeService; class SkillService; class JsonNode; class BattleFieldService; +class ObstacleService; namespace spells { @@ -50,6 +51,7 @@ public: virtual const spells::Service * spells() const = 0; virtual const SkillService * skills() const = 0; virtual const BattleFieldService * battlefields() const = 0; + virtual const ObstacleService * obstacles() const = 0; virtual void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) = 0; diff --git a/lib/BattleFieldHandler.cpp b/lib/BattleFieldHandler.cpp index 317afcad7..1155e1d3f 100644 --- a/lib/BattleFieldHandler.cpp +++ b/lib/BattleFieldHandler.cpp @@ -1,5 +1,5 @@ /* - * BattleFieldHandler.h, part of VCMI engine + * BattleFieldHandler.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * diff --git a/lib/BattleFieldHandler.h b/lib/BattleFieldHandler.h index ab5ab2742..b9023f3d0 100644 --- a/lib/BattleFieldHandler.h +++ b/lib/BattleFieldHandler.h @@ -10,6 +10,7 @@ #pragma once #include +#include #include "HeroBonus.h" #include "GameConstants.h" #include "IHandlerBase.h" diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 8f27b596a..890189eeb 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -153,41 +153,6 @@ CHeroClass::CHeroClass() { } -std::vector CObstacleInfo::getBlocked(BattleHex hex) const -{ - std::vector ret; - if(isAbsoluteObstacle) - { - assert(!hex.isValid()); - range::copy(blockedTiles, std::back_inserter(ret)); - return ret; - } - - for(int offset : blockedTiles) - { - BattleHex toBlock = hex + offset; - if((hex.getY() & 1) && !(toBlock.getY() & 1)) - toBlock += BattleHex::LEFT; - - if(!toBlock.isValid()) - logGlobal->error("Misplaced obstacle!"); - else - ret.push_back(toBlock); - } - - return ret; -} - -bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const -{ - auto bgInfo = battlefield.getInfo(); - - if(bgInfo->isSpecial) - return vstd::contains(allowedSpecialBfields, bgInfo->identifier); - - return vstd::contains(allowedTerrains, terrainType); -} - void CHeroClassHandler::fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill) { const auto & skillName = PrimarySkill::names[pSkill]; @@ -378,7 +343,6 @@ CHeroHandler::~CHeroHandler() = default; CHeroHandler::CHeroHandler() { - loadObstacles(); loadTerrains(); for(int i = 0; i < Terrain::Manager::terrains().size(); ++i) { @@ -818,51 +782,6 @@ void CHeroHandler::loadExperience() expPerLevel.pop_back();//last value is broken } -void CHeroHandler::loadObstacles() -{ - auto loadObstacles = [](const JsonNode & node, bool absolute, std::vector & out) - { - for(const JsonNode &obs : node.Vector()) - { - out.emplace_back(); - CObstacleInfo & obi = out.back(); - obi.defName = obs["defname"].String(); - obi.width = static_cast(obs["width"].Float()); - obi.height = static_cast(obs["height"].Float()); - for(auto & t : obs["allowedTerrain"].Vector()) - obi.allowedTerrains.emplace_back(t.String()); - for(auto & t : obs["specialBattlefields"].Vector()) - obi.allowedSpecialBfields.emplace_back(t.String()); - obi.blockedTiles = obs["blockedTiles"].convertTo >(); - obi.isAbsoluteObstacle = absolute; - } - }; - - auto allConfigs = VLC->modh->getActiveMods(); - allConfigs.insert(allConfigs.begin(), "core"); - for(auto & mod : allConfigs) - { - ISimpleResourceLoader * modResourceLoader; - try - { - modResourceLoader = CResourceHandler::get(mod); - } - catch(const std::out_of_range &) - { - logMod->warn("Mod '%1%' doesn't exist! Its obstacles won't be loaded!", mod); - continue; - } - - const ResourceID obstaclesResource{"config/obstacles.json"}; - if(!modResourceLoader->existsResource(obstaclesResource)) - continue; - - const JsonNode config(mod, obstaclesResource); - loadObstacles(config["obstacles"], false, obstacles); - loadObstacles(config["absoluteObstacles"], true, absoluteObstacles); - } -} - /// convert h3-style ID (e.g. Gobin Wolf Rider) to vcmi (e.g. goblinWolfRider) static std::string genRefName(std::string input) { diff --git a/lib/CHeroHandler.h b/lib/CHeroHandler.h index 264eecfcb..87da89149 100644 --- a/lib/CHeroHandler.h +++ b/lib/CHeroHandler.h @@ -223,32 +223,6 @@ public: EAlignment::EAlignment getAlignment() const; }; -struct DLL_LINKAGE CObstacleInfo -{ - std::string defName; - std::vector allowedTerrains; - std::vector allowedSpecialBfields; - - ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same - si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm) - std::vector blockedTiles; //offsets relative to obstacle position (that is its left bottom corner) - - std::vector getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex' - - bool isAppropriate(const Terrain & terrainType, const BattleField & specialBattlefield) const; - - template void serialize(Handler &h, const int version) - { - h & defName; - h & allowedTerrains; - h & allowedSpecialBfields; - h & isAbsoluteObstacle; - h & width; - h & height; - h & blockedTiles; - } -}; - class DLL_LINKAGE CHeroClassHandler : public CHandlerBase { void fillPrimarySkillData(const JsonNode & node, CHeroClass * heroClass, PrimarySkill::PrimarySkill pSkill); @@ -286,7 +260,6 @@ class DLL_LINKAGE CHeroHandler : public CHandlerBase ballistics; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert - std::vector obstacles; //info about obstacles that may be placed on battlefield - std::vector absoluteObstacles; //info about obstacles that may be placed on battlefield - ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount ui64 reqExp(ui32 level) const; //calculates experience required for given level @@ -340,8 +310,6 @@ public: h & expPerLevel; h & ballistics; h & terrCosts; - h & obstacles; - h & absoluteObstacles; } protected: diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1f7a5e6d3..7f2ef298b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -179,6 +179,7 @@ set(lib_SRCS JsonNode.cpp LogicalExpression.cpp NetPacksLib.cpp + ObstacleHandler.cpp StartInfo.cpp ResourceSet.cpp ScriptHandler.cpp @@ -418,6 +419,7 @@ set(lib_HEADERS NetPacksBase.h NetPacks.h NetPacksLobby.h + ObstacleHandler.h PathfinderUtil.h ResourceSet.h ScriptHandler.h diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index a7b2ace73..1c30b1208 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -26,6 +26,7 @@ #include "CSkillHandler.h" #include "ScriptHandler.h" #include "BattleFieldHandler.h" +#include "ObstacleHandler.h" #include @@ -435,6 +436,7 @@ void CContentHandler::init() handlers.insert(std::make_pair("templates", ContentTypeHandler((IHandlerBase *)VLC->tplh, "template"))); handlers.insert(std::make_pair("scripts", ContentTypeHandler(VLC->scriptHandler, "script"))); handlers.insert(std::make_pair("battlefields", ContentTypeHandler(VLC->battlefieldsHandler, "battlefield"))); + handlers.insert(std::make_pair("obstacles", ContentTypeHandler(VLC->obstacleHandler, "obstacle"))); //TODO: any other types of moddables? } diff --git a/lib/GameConstants.cpp b/lib/GameConstants.cpp index ac9658bb1..ae543bcf5 100644 --- a/lib/GameConstants.cpp +++ b/lib/GameConstants.cpp @@ -35,6 +35,7 @@ #include "CGeneralTextHandler.h" #include "CModHandler.h"//todo: remove #include "BattleFieldHandler.h" +#include "ObstacleHandler.h" const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2); const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3); @@ -292,4 +293,24 @@ BattleField BattleField::fromString(std::string identifier) return BattleField(rawId.get()); else return BattleField::NONE; -} \ No newline at end of file +} + +const ObstacleInfo * Obstacle::getInfo() const +{ + return VLC->obstacles()->getById(*this); +} + +Obstacle::operator std::string() const +{ + return getInfo()->identifier; +} + +Obstacle Obstacle::fromString(std::string identifier) +{ + auto rawId = VLC->modh->identifiers.getIdentifier("core", "obstacle", identifier); + + if(rawId) + return Obstacle(rawId.get()); + else + return Obstacle(-1); +} diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 7dfbde61a..d86c760ce 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -1125,6 +1125,16 @@ class BattleField : public BaseForID DLL_LINKAGE static BattleField fromString(std::string identifier); }; + +class ObstacleInfo; +class Obstacle : public BaseForID +{ + INSTID_LIKE_CLASS_COMMON(Obstacle, si32) + + DLL_LINKAGE const ObstacleInfo * getInfo() const; + DLL_LINKAGE operator std::string() const; + DLL_LINKAGE static Obstacle fromString(std::string identifier); +}; enum class ESpellSchool: ui8 { diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index b5d6f37b0..337eae901 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -17,6 +17,7 @@ #include "CBonusTypeHandler.h" #include "CModHandler.h" #include "BattleFieldHandler.h" +#include "ObstacleHandler.h" #include "serializer/CSerializer.h" // for SAVEGAME_MAGIC #include "serializer/BinaryDeserializer.h" diff --git a/lib/ObstacleHandler.cpp b/lib/ObstacleHandler.cpp new file mode 100644 index 000000000..a55fe0678 --- /dev/null +++ b/lib/ObstacleHandler.cpp @@ -0,0 +1,112 @@ +/* + * ObstacleHandler.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" +#include "ObstacleHandler.h" +#include "BattleFieldHandler.h" + +int32_t ObstacleInfo::getIndex() const +{ + return obstacle.getNum(); +} + +int32_t ObstacleInfo::getIconIndex() const +{ + return iconIndex; +} + +const std::string & ObstacleInfo::getName() const +{ + return identifier; +} + +const std::string & ObstacleInfo::getJsonKey() const +{ + return identifier; +} + +void ObstacleInfo::registerIcons(const IconRegistar & cb) const +{ +} + +Obstacle ObstacleInfo::getId() const +{ + return obstacle; +} + + +std::vector ObstacleInfo::getBlocked(BattleHex hex) const +{ + std::vector ret; + if(isAbsoluteObstacle) + { + assert(!hex.isValid()); + range::copy(blockedTiles, std::back_inserter(ret)); + return ret; + } + + for(int offset : blockedTiles) + { + BattleHex toBlock = hex + offset; + if((hex.getY() & 1) && !(toBlock.getY() & 1)) + toBlock += BattleHex::LEFT; + + if(!toBlock.isValid()) + logGlobal->error("Misplaced obstacle!"); + else + ret.push_back(toBlock); + } + + return ret; +} + +bool ObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const +{ + auto bgInfo = battlefield.getInfo(); + + if(bgInfo->isSpecial) + return vstd::contains(allowedSpecialBfields, bgInfo->identifier); + + return vstd::contains(allowedTerrains, terrainType); +} + +ObstacleInfo * ObstacleHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) +{ + auto * info = new ObstacleInfo(Obstacle(index), identifier); + + info->animation = json["animation"].String(); + info->width = json["width"].Integer(); + info->height = json["height"].Integer(); + for(auto & t : json["allowedTerrain"].Vector()) + info->allowedTerrains.emplace_back(t.String()); + for(auto & t : json["specialBattlefields"].Vector()) + info->allowedSpecialBfields.emplace_back(t.String()); + info->blockedTiles = json["blockedTiles"].convertTo>(); + info->isAbsoluteObstacle = json["absolute"].Bool(); + + objects.push_back(info); + + return info; +} + +std::vector ObstacleHandler::loadLegacyData(size_t dataSize) +{ + return {}; +} + +std::vector ObstacleHandler::getDefaultAllowed() const +{ + return {}; +} + +const std::vector & ObstacleHandler::getTypeNames() const +{ + static const std::vector types = { "obstacle" }; + return types; +} diff --git a/lib/ObstacleHandler.h b/lib/ObstacleHandler.h new file mode 100644 index 000000000..7075d140b --- /dev/null +++ b/lib/ObstacleHandler.h @@ -0,0 +1,94 @@ +/* + * ObstacleHandler.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +#include +#include +#include "GameConstants.h" +#include "IHandlerBase.h" +#include "Terrain.h" +#include "battle/BattleHex.h" + +class DLL_LINKAGE ObstacleInfo : public EntityT +{ +public: + ObstacleInfo(): obstacle(-1), width(0), height(0), isAbsoluteObstacle(false), iconIndex(0) + {} + + ObstacleInfo(Obstacle obstacle, std::string identifier) + : obstacle(obstacle), identifier(identifier), iconIndex(obstacle.getNum()), width(0), height(0), isAbsoluteObstacle(false) + { + } + + Obstacle obstacle; + si32 iconIndex; + std::string identifier; + std::string appearAnimation, animation, dissapearAnimation; + std::vector allowedTerrains; + std::vector allowedSpecialBfields; + + //TODO: here is extra field to implement it's logic in the future but save backward compatibility + int obstacleType = -1; + + ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same + si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm) + std::vector blockedTiles; //offsets relative to obstacle position (that is its left bottom corner) + + int32_t getIndex() const override; + int32_t getIconIndex() const override; + const std::string & getJsonKey() const override; + const std::string & getName() const override; + void registerIcons(const IconRegistar & cb) const override; + Obstacle getId() const override; + + std::vector getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex' + + bool isAppropriate(const Terrain & terrainType, const BattleField & specialBattlefield) const; + + template void serialize(Handler &h, const int version) + { + h & obstacle; + h & obstacleType; + h & iconIndex; + h & identifier; + h & animation; + h & appearAnimation; + h & dissapearAnimation; + h & allowedTerrains; + h & allowedSpecialBfields; + h & isAbsoluteObstacle; + h & width; + h & height; + h & blockedTiles; + } +}; + +class DLL_LINKAGE ObstacleService : public EntityServiceT +{ +public: +}; + +class ObstacleHandler: public CHandlerBase +{ +public: + ObstacleInfo * loadFromJson(const std::string & scope, + const JsonNode & json, + const std::string & identifier, + size_t index) override; + + const std::vector & getTypeNames() const override; + std::vector loadLegacyData(size_t dataSize) override; + std::vector getDefaultAllowed() const override; + + template void serialize(Handler & h, const int version) + { + h & objects; + } +}; diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index ff8d35eec..81fd2bd99 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -33,6 +33,7 @@ #include "mapping/CMapEditManager.h" #include "ScriptHandler.h" #include "BattleFieldHandler.h" +#include "ObstacleHandler.h" LibClasses * VLC = nullptr; @@ -116,6 +117,11 @@ const BattleFieldService * LibClasses::battlefields() const return battlefieldsHandler; } +const ObstacleService * LibClasses::obstacles() const +{ + return obstacleHandler; +} + void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data) { switch(metatype) @@ -212,6 +218,8 @@ void LibClasses::init(bool onlyEssential) createHandler(scriptHandler, "Script", pomtime); createHandler(battlefieldsHandler, "Battlefields", pomtime); + + createHandler(obstacleHandler, "Obstacles", pomtime); logGlobal->info("\tInitializing handlers: %d ms", totalTime.getDiff()); diff --git a/lib/VCMI_Lib.h b/lib/VCMI_Lib.h index 4ab7c126c..774db316d 100644 --- a/lib/VCMI_Lib.h +++ b/lib/VCMI_Lib.h @@ -27,6 +27,7 @@ class CContentHandler; class BattleFieldHandler; class IBonusTypeHandler; class CBonusTypeHandler; +class ObstacleHandler; class CTerrainViewPatternConfig; class CRmgTemplateStorage; class IHandlerBase; @@ -58,6 +59,7 @@ public: const spells::Service * spells() const override; const SkillService * skills() const override; const BattleFieldService * battlefields() const override; + const ObstacleService * obstacles() const override; void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override; @@ -79,6 +81,7 @@ public: CTerrainViewPatternConfig * terviewh; CRmgTemplateStorage * tplh; BattleFieldHandler * battlefieldsHandler; + ObstacleHandler * obstacleHandler; scripting::ScriptHandler * scriptHandler; LibClasses(); //c-tor, loads .lods and NULLs handlers @@ -108,6 +111,7 @@ public: h & spellh; h & skillh; h & battlefieldsHandler; + h & obstacleHandler; if(!h.saving) { diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index 59925927e..9ffbbd2c5 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -17,6 +17,7 @@ #include "../CGeneralTextHandler.h" #include "../Terrain.h" #include "../BattleFieldHandler.h" +#include "../ObstacleHandler.h" //TODO: remove #include "../IGameCallback.h" @@ -240,9 +241,6 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, //randomize obstacles if (town == nullptr && !creatureBank) //do it only when it's not siege and not creature bank { - const int ABSOLUTE_OBSTACLES_COUNT = VLC->heroh->absoluteObstacles.size(); - const int USUAL_OBSTACLES_COUNT = VLC->heroh->obstacles.size(); //shouldn't be changes if we want H3-like obstacle placement - RandGen r; auto ourRand = [&](){ return r.rand(); }; r.srand(tile); @@ -253,17 +251,19 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, auto appropriateAbsoluteObstacle = [&](int id) { - return VLC->heroh->absoluteObstacles[id].isAppropriate(curB->terrainType, battlefieldType); + auto * info = Obstacle(id).getInfo(); + return info && info->isAbsoluteObstacle && info->isAppropriate(curB->terrainType, battlefieldType); }; - auto appropriateUsualObstacle = [&](int id) -> bool + auto appropriateUsualObstacle = [&](int id) { - return VLC->heroh->obstacles[id].isAppropriate(curB->terrainType, battlefieldType); + auto * info = Obstacle(id).getInfo(); + return info && !info->isAbsoluteObstacle && info->isAppropriate(curB->terrainType, battlefieldType); }; + RangeGenerator obidgen(0, VLC->obstacleHandler->objects.size() - 1, ourRand); + if(r.rand(1,100) <= 40) //put cliff-like obstacle { - RangeGenerator obidgen(0, ABSOLUTE_OBSTACLES_COUNT-1, ourRand); - try { auto obstPtr = std::make_shared(); @@ -274,7 +274,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, for(BattleHex blocked : obstPtr->getBlockedTiles()) blockedTiles.push_back(blocked); - tilesToBlock -= (int)VLC->heroh->absoluteObstacles[obstPtr->ID].blockedTiles.size() / 2; + tilesToBlock -= Obstacle(obstPtr->ID).getInfo()->blockedTiles.size() / 2; } catch(RangeGenerator::ExhaustedPossibilities &) { @@ -283,14 +283,13 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, } } - RangeGenerator obidgen(0, USUAL_OBSTACLES_COUNT-1, ourRand); try { while(tilesToBlock > 0) { auto tileAccessibility = curB->getAccesibility(); const int obid = obidgen.getSuchNumber(appropriateUsualObstacle); - const CObstacleInfo &obi = VLC->heroh->obstacles[obid]; + const ObstacleInfo &obi = *Obstacle(obid).getInfo(); auto validPosition = [&](BattleHex pos) -> bool { diff --git a/lib/battle/CObstacleInstance.cpp b/lib/battle/CObstacleInstance.cpp index 8be8fa090..78edff13b 100644 --- a/lib/battle/CObstacleInstance.cpp +++ b/lib/battle/CObstacleInstance.cpp @@ -11,6 +11,7 @@ #include "CObstacleInstance.h" #include "../CHeroHandler.h" #include "../CTownHandler.h" +#include "../ObstacleHandler.h" #include "../VCMI_Lib.h" #include "../NetPacksBase.h" @@ -29,17 +30,9 @@ CObstacleInstance::~CObstacleInstance() } -const CObstacleInfo & CObstacleInstance::getInfo() const +const ObstacleInfo & CObstacleInstance::getInfo() const { - switch(obstacleType) - { - case ABSOLUTE_OBSTACLE: - return VLC->heroh->absoluteObstacles[ID]; - case USUAL: - return VLC->heroh->obstacles[ID]; - default: - throw std::runtime_error("Unknown obstacle type in CObstacleInstance::getInfo()"); - } + return *Obstacle(ID).getInfo(); } std::vector CObstacleInstance::getBlockedTiles() const diff --git a/lib/battle/CObstacleInstance.h b/lib/battle/CObstacleInstance.h index 38a3d1def..041330779 100644 --- a/lib/battle/CObstacleInstance.h +++ b/lib/battle/CObstacleInstance.h @@ -10,7 +10,7 @@ #pragma once #include "BattleHex.h" -struct CObstacleInfo; +class ObstacleInfo; class ObstacleChanges; class JsonSerializeFormat; @@ -30,7 +30,7 @@ struct DLL_LINKAGE CObstacleInstance CObstacleInstance(); virtual ~CObstacleInstance(); - const CObstacleInfo &getInfo() const; //allowed only when not generated by spell (usual or absolute) + const ObstacleInfo &getInfo() const; //allowed only when not generated by spell (usual or absolute) std::vector getBlockedTiles() const; std::vector getStoppingTile() const; //hexes that will stop stack move diff --git a/test/mock/mock_Services.h b/test/mock/mock_Services.h index 7c6587159..2ebd30c4a 100644 --- a/test/mock/mock_Services.h +++ b/test/mock/mock_Services.h @@ -25,6 +25,7 @@ public: MOCK_CONST_METHOD0(spells, const spells::Service *()); MOCK_CONST_METHOD0(skills, const SkillService * ()); MOCK_CONST_METHOD0(battlefields, const BattleFieldService *()); + MOCK_CONST_METHOD0(obstacles, const ObstacleService *()); MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &));