mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	allow configurable battleground graphics
This commit is contained in:
		| @@ -914,7 +914,7 @@ | ||||
| 	/// Passive objects, terrain overlays | ||||
| 	"cursedGround" : { | ||||
| 		"index" : 21, | ||||
| 		"handler": "generic", | ||||
| 		"handler": "terrain", | ||||
| 		"base" : { | ||||
| 			"sounds" : { | ||||
| 				"ambient" : ["LOOPCURS"] | ||||
| @@ -922,13 +922,14 @@ | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"object" : { | ||||
| 				"index" : 0 | ||||
| 				"index" : 0, | ||||
| 				"battleground": "cursed_ground" | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"magicPlains"	: { | ||||
| 	"magicPlains" : { | ||||
| 		"index" : 46, | ||||
| 		"handler" : "generic", | ||||
| 		"handler" : "terrain", | ||||
| 		"base" : { | ||||
| 			"sounds" : { | ||||
| 				"ambient" : ["LOOPMAGI"] | ||||
| @@ -936,18 +937,28 @@ | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"object" : { | ||||
| 				"index" : 0 | ||||
| 				"index" : 0, | ||||
| 				"battleground": "magic_plains" | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"swampFoliage" : { "index" :211, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"cloverField"	: { "index" :222, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"swampFoliage" : { | ||||
| 		"index" :211, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0} } | ||||
| 	}, | ||||
| 	"cloverField" : { | ||||
| 		"index" :222,  | ||||
| 		"handler": "terrain",  | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "clover_field" } } | ||||
| 	}, | ||||
| 	"cursedGroundDUPLICATE"	: { | ||||
| 		"index" : 223, | ||||
| 		"handler" : "generic", | ||||
| 		"handler" : "terrain", | ||||
| 		"types" : { | ||||
| 			"object" : { | ||||
| 				"index" : 0 | ||||
| 				"index" : 0, | ||||
| 				"battleground": "cursed_ground" | ||||
| 			} | ||||
| 		}, | ||||
| 		"base" : { | ||||
| @@ -956,15 +967,39 @@ | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"evilFog"	: { "index" :224, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"favorableWinds" : { "index" :225, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"fieryFields"	: { "index" :226, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"holyGround" : { "index" :227, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"lucidPools" : { "index" :228, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"magicClouds"	: { "index" :229, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"evilFog" : { | ||||
| 		"index" :224, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "evil_fog" } } | ||||
| 	}, | ||||
| 	"favorableWinds" : { | ||||
| 		"index" :225, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "favorable_winds" } } | ||||
| 	}, | ||||
| 	"fieryFields": { | ||||
| 		"index" :226, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "fiery_fields" } } | ||||
| 	}, | ||||
| 	"holyGround" : { | ||||
| 		"index" :227, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "holy_ground" } } | ||||
| 	}, | ||||
| 	"lucidPools" : { | ||||
| 		"index" :228, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "lucid_pools" } } | ||||
| 	}, | ||||
| 	"magicClouds" : { | ||||
| 		"index" :229, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "magic_clouds" } } | ||||
| 	}, | ||||
| 	"magicPlainsDUPLICATE" : { | ||||
| 		"index" : 230, | ||||
| 		"handler": "generic", | ||||
| 		"handler": "terrain", | ||||
| 		"base" : { | ||||
| 			"sounds" : { | ||||
| 				"ambient" : ["LOOPMAGI"] | ||||
| @@ -972,11 +1007,16 @@ | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"object" : { | ||||
| 				"index" : 0 | ||||
| 				"index" : 0, | ||||
| 				"battleground": "magic_plains" | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	"rocklands"	: { "index" :231, "handler": "generic", "types" : { "object" : { "index" : 0} } }, | ||||
| 	"rocklands"	: { | ||||
| 		"index" :231, | ||||
| 		"handler": "terrain", | ||||
| 		"types" : { "object" : { "index" : 0, "battleground": "rocklands" } } | ||||
| 	}, | ||||
|  | ||||
| 	/// Decorations | ||||
| 	"cactus"						: { "index" :116, "handler": "static", "types" : { "object" : { "index" : 0} } }, | ||||
|   | ||||
| @@ -237,7 +237,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPLUMB"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"alchemistLab" : { | ||||
| 				"index" : 1, | ||||
| @@ -247,7 +248,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPSTAR"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"orePit" : { | ||||
| 				"index" : 2, | ||||
| @@ -257,7 +259,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPSULF"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"sulfurDune" : { | ||||
| 				"index" : 3, | ||||
| @@ -267,7 +270,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPSULF"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"crystalCavern" : { | ||||
| 				"index" : 4, | ||||
| @@ -277,7 +281,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPCRYS"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"gemPond" : { | ||||
| 				"index" : 5, | ||||
| @@ -287,7 +292,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPGEMP"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"goldMine" : { | ||||
| 				"index" : 6, | ||||
| @@ -297,7 +303,8 @@ | ||||
| 				}, | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPMINE"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			}, | ||||
| 			"abandoned" :	{ | ||||
| 				"index" : 7, | ||||
| @@ -305,7 +312,8 @@ | ||||
| 				"sounds" : { | ||||
| 					"ambient" : ["LOOPCAVE"], | ||||
| 					"visit" : ["MYSTERY"] | ||||
| 				} | ||||
| 				}, | ||||
| 				"battleground": "subterranean" | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| @@ -319,7 +327,7 @@ | ||||
| 			} | ||||
| 		}, | ||||
| 		"types" : { | ||||
| 			"mine" : { "index" : 7 } | ||||
| 			"mine" : { "index" : 7, "battleground": "subterranean" } | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
|   | ||||
| @@ -1902,9 +1902,12 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & r | ||||
| 		return BattleField::NONE; | ||||
|  | ||||
| 	const TerrainTile &t = map->getTile(tile); | ||||
| 	//fight in mine -> subterranean | ||||
| 	if(dynamic_cast<const CGMine *>(t.visitableObjects.front())) | ||||
| 		return BattleField("subterranean"); | ||||
|  | ||||
| 	auto topObject = t.visitableObjects.front(); | ||||
| 	if(topObject && topObject->getBattlefield() != BattleField::NONE) | ||||
| 	{ | ||||
| 		return topObject->getBattlefield(); | ||||
| 	} | ||||
|  | ||||
| 	for(auto &obj : map->objects) | ||||
| 	{ | ||||
| @@ -1912,29 +1915,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & r | ||||
| 		if( !obj || obj->pos.z != tile.z || !obj->coveringAt(tile.x, tile.y)) | ||||
| 			continue; | ||||
|  | ||||
| 		switch(obj->ID) | ||||
| 		{ | ||||
| 		case Obj::CLOVER_FIELD: | ||||
| 			return BattleField("clover_field"); | ||||
| 		case Obj::CURSED_GROUND1: case Obj::CURSED_GROUND2: | ||||
| 			return BattleField("cursed_ground"); | ||||
| 		case Obj::EVIL_FOG: | ||||
| 			return BattleField("evil_fog"); | ||||
| 		case Obj::FAVORABLE_WINDS: | ||||
| 			return BattleField("favorable_winds"); | ||||
| 		case Obj::FIERY_FIELDS: | ||||
| 			return BattleField("fiery_fields"); | ||||
| 		case Obj::HOLY_GROUNDS: | ||||
| 			return BattleField("holy_ground"); | ||||
| 		case Obj::LUCID_POOLS: | ||||
| 			return BattleField("lucid_pools"); | ||||
| 		case Obj::MAGIC_CLOUDS: | ||||
| 			return BattleField("magic_clouds"); | ||||
| 		case Obj::MAGIC_PLAINS1: case Obj::MAGIC_PLAINS2: | ||||
| 			return BattleField("magic_plains"); | ||||
| 		case Obj::ROCKLANDS: | ||||
| 			return BattleField("rocklands"); | ||||
| 		} | ||||
| 		auto customBattlefield = obj->getBattlefield(); | ||||
|  | ||||
| 		if(customBattlefield != BattleField::NONE) | ||||
| 			return customBattlefield; | ||||
| 	} | ||||
|  | ||||
| 	if(map->isCoastalTile(tile)) //coastal tile is always ground | ||||
|   | ||||
| @@ -177,10 +177,10 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & specialBattlefield) const | ||||
| bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const | ||||
| { | ||||
| 	if(!allowedSpecialBfields.empty() && specialBattlefield != BattleField::NONE) | ||||
| 		return vstd::contains(allowedSpecialBfields, specialBattlefield); | ||||
| 	if(battlefield.isSpecial()) | ||||
| 		return vstd::contains(allowedSpecialBfields, battlefield); | ||||
|  | ||||
| 	return vstd::contains(allowedTerrains, terrainType); | ||||
| } | ||||
|   | ||||
| @@ -42,6 +42,11 @@ public: | ||||
| 	{ | ||||
| 		h & name; | ||||
| 	} | ||||
|  | ||||
| 	bool isSpecial() const | ||||
| 	{ | ||||
| 		return name.find('_') >= 0; // hack for special battlefields, move to JSON | ||||
| 	} | ||||
| 	 | ||||
| protected: | ||||
| 	 | ||||
|   | ||||
| @@ -467,7 +467,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("fiery_fields")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 1; | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 2; | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("rocklands")) | ||||
| 	{ | ||||
| @@ -475,13 +475,13 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("magic_clouds")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 2; | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 1; | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("lucid_pools")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 4; | ||||
| 	} | ||||
| 	if(bonusSubtype == -1) | ||||
| 	if(bonusSubtype != -1) | ||||
| 	{ //common part for cases 9, 14, 15, 16, 17 | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MAGIC_SCHOOL_SKILL,Bonus::TERRAIN_OVERLAY, 3, battlefieldType.hash(), bonusSubtype)); | ||||
| 	} | ||||
|   | ||||
| @@ -97,6 +97,7 @@ CObjectClassesHandler::CObjectClassesHandler() | ||||
| 	SET_HANDLER("oncePerHero", CGVisitableOPH); | ||||
| 	SET_HANDLER("oncePerWeek", CGVisitableOPW); | ||||
| 	SET_HANDLER("witch", CGWitchHut); | ||||
| 	SET_HANDLER("terrain", CGTerrainPatch); | ||||
|  | ||||
| #undef SET_HANDLER_CLASS | ||||
| #undef SET_HANDLER | ||||
| @@ -514,6 +515,11 @@ void AObjectTypeHandler::init(const JsonNode & input, boost::optional<std::strin | ||||
| 	else | ||||
| 		aiValue = static_cast<boost::optional<si32>>(input["aiValue"].Integer()); | ||||
|  | ||||
| 	if(input["battleground"].isNull()) | ||||
| 		battlefield = BattleField::NONE; | ||||
| 	else | ||||
| 		battlefield = BattleField(input["battleground"].String()); | ||||
|  | ||||
| 	initTypeData(input); | ||||
| } | ||||
|  | ||||
| @@ -569,6 +575,11 @@ std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const | ||||
| 	return templates; | ||||
| } | ||||
|  | ||||
| BattleField AObjectTypeHandler::getBattlefield() const | ||||
| { | ||||
| 	return battlefield; | ||||
| } | ||||
|  | ||||
| std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(const Terrain & terrainType) const | ||||
| { | ||||
| 	std::vector<ObjectTemplate> templates = getTemplates(); | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include "../ConstTransitivePtr.h" | ||||
| #include "../IHandlerBase.h" | ||||
| #include "../JsonNode.h" | ||||
| #include "Terrain.h" | ||||
|  | ||||
| class JsonNode; | ||||
| class CRandomGenerator; | ||||
| @@ -148,6 +149,9 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable | ||||
| 	SObjectSounds sounds; | ||||
|  | ||||
| 	boost::optional<si32> aiValue; | ||||
|  | ||||
| 	BattleField battlefield; | ||||
|  | ||||
| protected: | ||||
| 	void preInitObject(CGObjectInstance * obj) const; | ||||
| 	virtual bool objectFilter(const CGObjectInstance *, const ObjectTemplate &) const; | ||||
| @@ -179,6 +183,7 @@ public: | ||||
| 	/// returns all templates matching parameters | ||||
| 	std::vector<ObjectTemplate> getTemplates() const; | ||||
| 	std::vector<ObjectTemplate> getTemplates(const Terrain & terrainType) const; | ||||
| 	BattleField getBattlefield() const; | ||||
|  | ||||
| 	/// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle) | ||||
| 	/// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server) | ||||
|   | ||||
| @@ -400,6 +400,11 @@ void CGObjectInstance::serializeJsonOwner(JsonSerializeFormat & handler) | ||||
| 		tempOwner = PlayerColor(temp); | ||||
| } | ||||
|  | ||||
| BattleField CGObjectInstance::getBattlefield() const | ||||
| { | ||||
| 	return VLC->objtypeh->getHandlerFor(ID, subID)->getBattlefield(); | ||||
| } | ||||
|  | ||||
| CGObjectInstanceBySubIdFinder::CGObjectInstanceBySubIdFinder(CGObjectInstance * obj) : obj(obj) | ||||
| { | ||||
|  | ||||
|   | ||||
| @@ -159,21 +159,9 @@ public: | ||||
| 	std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object | ||||
| 	bool isVisitable() const; //returns true if object is visitable | ||||
|  | ||||
| 	bool isTile2Terrain() const | ||||
| 	{ | ||||
| 		return ID.num == Obj::CLOVER_FIELD | ||||
| 			|| ID.num == Obj::CURSED_GROUND1 | ||||
| 			|| ID.num == Obj::CURSED_GROUND2 | ||||
| 			|| ID.num == Obj::EVIL_FOG | ||||
| 			|| ID.num == Obj::FAVORABLE_WINDS | ||||
| 			|| ID.num == Obj::FIERY_FIELDS | ||||
| 			|| ID.num == Obj::HOLY_GROUNDS | ||||
| 			|| ID.num == Obj::LUCID_POOLS | ||||
| 			|| ID.num == Obj::MAGIC_CLOUDS | ||||
| 			|| ID.num == Obj::MAGIC_PLAINS1 | ||||
| 			|| ID.num == Obj::MAGIC_PLAINS2 | ||||
| 			|| ID.num == Obj::ROCKLANDS; | ||||
| 	} | ||||
| 	BattleField getBattlefield() const; | ||||
|  | ||||
| 	virtual bool isTile2Terrain() const { return false; } | ||||
|  | ||||
| 	boost::optional<std::string> getAmbientSound() const; | ||||
| 	boost::optional<std::string> getVisitSound() const; | ||||
|   | ||||
| @@ -2199,4 +2199,4 @@ void CGLighthouse::giveBonusTo(PlayerColor player, bool onInit) const | ||||
| void CGLighthouse::serializeJsonOptions(JsonSerializeFormat& handler) | ||||
| { | ||||
| 	serializeJsonOwner(handler); | ||||
| } | ||||
| } | ||||
| @@ -529,3 +529,14 @@ public: | ||||
| protected: | ||||
| 	void serializeJsonOptions(JsonSerializeFormat & handler) override; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGTerrainPatch : public CGObjectInstance | ||||
| { | ||||
| public: | ||||
| 	CGTerrainPatch() = default; | ||||
|  | ||||
| 	virtual bool isTile2Terrain() const override | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user