mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	battlefields in VLC and custom bonuses for terrain patches
This commit is contained in:
		| @@ -37,6 +37,7 @@ void CGameInfo::setFromLib() | ||||
| 	spellh = VLC->spellh; | ||||
| 	skillh = VLC->skillh; | ||||
| 	objtypeh = VLC->objtypeh; | ||||
| 	battleFieldHandler = VLC->battlefieldsHandler; | ||||
| } | ||||
|  | ||||
| const ArtifactService * CGameInfo::artifacts() const | ||||
| @@ -44,6 +45,11 @@ const ArtifactService * CGameInfo::artifacts() const | ||||
| 	return globalServices->artifacts(); | ||||
| } | ||||
|  | ||||
| const BattleFieldService * CGameInfo::battlefields() const | ||||
| { | ||||
| 	return globalServices->battlefields(); | ||||
| } | ||||
|  | ||||
| const CreatureService * CGameInfo::creatures() const | ||||
| { | ||||
| 	return globalServices->creatures(); | ||||
|   | ||||
| @@ -31,6 +31,7 @@ class CCursorHandler; | ||||
| class CGameState; | ||||
| class IMainVideoPlayer; | ||||
| class CServerHandler; | ||||
| class BattleFieldHandler; | ||||
|  | ||||
| class CMap; | ||||
|  | ||||
| @@ -60,6 +61,7 @@ public: | ||||
| 	const scripting::Service * scripts() const override; | ||||
| 	const spells::Service * spells() const override; | ||||
| 	const SkillService * skills() const override; | ||||
| 	const BattleFieldService * battlefields() const override; | ||||
|  | ||||
| 	void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override; | ||||
|  | ||||
| @@ -68,6 +70,7 @@ public: | ||||
|  | ||||
|  | ||||
| 	ConstTransitivePtr<CModHandler> modh; //public? | ||||
| 	ConstTransitivePtr<BattleFieldHandler> battleFieldHandler; | ||||
| 	ConstTransitivePtr<CHeroHandler> heroh; | ||||
| 	ConstTransitivePtr<CCreatureHandler> creh; | ||||
| 	ConstTransitivePtr<CSpellHandler> spellh; | ||||
|   | ||||
| @@ -109,12 +109,6 @@ void Graphics::initializeBattleGraphics() | ||||
| 			 | ||||
| 		const JsonNode config(mod, ResourceID("config/battles_graphics.json")); | ||||
|  | ||||
| 		if(!config["backgrounds"].isNull()) | ||||
| 		for(auto & t : config["backgrounds"].Struct()) | ||||
| 		{ | ||||
| 			battleBacks[t.first] = t.second.String(); | ||||
| 		} | ||||
|  | ||||
| 		//initialization of AC->def name mapping | ||||
| 		if(!config["ac_mapping"].isNull()) | ||||
| 		for(const JsonNode &ac : config["ac_mapping"].Vector()) | ||||
|   | ||||
| @@ -87,7 +87,6 @@ public: | ||||
| 	//towns | ||||
| 	std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type | ||||
| 	//for battles | ||||
| 	std::map<std::string, std::string> battleBacks; //maps BattleField to it's picture's name | ||||
| 	std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names | ||||
|  | ||||
| 	//functions | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
| #include "../../lib/spells/ISpellMechanics.h" | ||||
| #include "../../lib/spells/Problem.h" | ||||
| #include "../../lib/CTownHandler.h" | ||||
| #include "../../lib/BattleFieldHandler.h" | ||||
| #include "../../lib/CGameState.h" | ||||
| #include "../../lib/mapping/CMap.h" | ||||
| #include "../../lib/NetPacks.h" | ||||
| @@ -201,13 +202,14 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet | ||||
| 	else | ||||
| 	{ | ||||
| 		auto bfieldType = curInt->cb->battleGetBattlefieldType(); | ||||
| 		if(!vstd::contains(graphics->battleBacks, bfieldType)) | ||||
|  | ||||
| 		if(bfieldType == BattleField::NONE) | ||||
| 		{ | ||||
| 			logGlobal->error("%s is not valid battlefield type!", static_cast<std::string>(bfieldType)); | ||||
| 			logGlobal->error("Invalid battlefield returned for current battle"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			background = BitmapHandler::loadBitmap(graphics->battleBacks[bfieldType], false); | ||||
| 			background = BitmapHandler::loadBitmap(bfieldType.getInfo()->graphics, false); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										173
									
								
								config/battlefields.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								config/battlefields.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| { | ||||
| 	"sand_shore": { "graphics" : "CMBKBCH.BMP" }, | ||||
| 	"sand_mesas": { "graphics" : "CMBKDES.BMP" }, | ||||
| 	"dirt_birches": { "graphics" : "CMBKDRTR.BMP" }, | ||||
| 	"dirt_hills": { "graphics" : "CMBKDRMT.BMP" }, | ||||
| 	"dirt_pines": { "graphics" : "CMBKDRDD.BMP" }, | ||||
| 	"grass_hills": { "graphics" : "CMBKGRMT.BMP" }, | ||||
| 	"grass_pines": { "graphics" : "CMBKGRTR.BMP" }, | ||||
| 	"lava":  { "graphics" :"CMBKLAVA.BMP" }, | ||||
| 	"magic_plains": { | ||||
| 		"graphics": "CMBKMAG.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 0, | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"snow_mountains": { "graphics" : "CMBKSNMT.BMP" }, | ||||
| 	"snow_trees": { "graphics" : "CMBKSNTR.BMP" }, | ||||
| 	"subterranean": { "graphics" : "CMBKSUB.BMP", "isSpecial" : true }, | ||||
| 	"swamp_trees": { "graphics" : "CMBKSWMP.BMP" }, | ||||
| 	"fiery_fields": { | ||||
| 		"graphics": "CMBKFF.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 2, | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"rocklands": { | ||||
| 		"graphics": "CMBKRK.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 8, | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"magic_clouds": { | ||||
| 		"graphics": "CMBKMC.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 1, | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"lucid_pools": { | ||||
| 		"graphics": "CMBKLP.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 4, | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"holy_ground": { | ||||
| 		"graphics": "CMBKHG.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MORALE", | ||||
| 				"val" : 1, | ||||
| 				"valueType" : "BASE_NUMBER", | ||||
| 				"description" : "Creatures of good town alignment on Holly Ground", | ||||
| 				"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["good"] }] | ||||
| 			}, | ||||
| 			{ | ||||
| 				"type" : "MORALE", | ||||
| 				"val" : -1, | ||||
| 				"valueType" : "BASE_NUMBER", | ||||
| 				"description" : "Creatures of evil town alignment on Holly Ground", | ||||
| 				"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["evil"] }] | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"clover_field": { | ||||
| 		"graphics": "CMBKCF.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "LUCK", | ||||
| 				"val" : 2, | ||||
| 				"valueType" : "BASE_NUMBER", | ||||
| 				"description" : "Creatures of neutral town alignment on Clover Field", | ||||
| 				"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["neutral"] }] | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"evil_fog": { | ||||
| 		"graphics": "CMBKEF.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MORALE", | ||||
| 				"val" : -1, | ||||
| 				"valueType" : "BASE_NUMBER", | ||||
| 				"description" : "Creatures of good town alignment on Evil Fog", | ||||
| 				"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["good"] }] | ||||
| 			}, | ||||
| 			{ | ||||
| 				"type" : "MORALE", | ||||
| 				"val" : 1, | ||||
| 				"valueType" : "BASE_NUMBER", | ||||
| 				"description" : "Creatures of evil town alignment on Evil Fog", | ||||
| 				"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["evil"] }] | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"favorable_winds": { | ||||
| 		"graphics": "CMBKFW.BMP", | ||||
| 		"isSpecial" : true | ||||
| 	}, | ||||
| 	"cursed_ground": { | ||||
| 		"graphics": "CMBKCUR.BMP", | ||||
| 		"isSpecial" : true, | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "NO_MORALE", | ||||
| 				"subtype" : 0, | ||||
| 				"val" : 0, | ||||
| 				"valueType" : "INDEPENDENT_MIN", | ||||
| 				"description" : "Creatures on Cursed Ground" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"type" : "NO_LUCK", | ||||
| 				"subtype" : 0, | ||||
| 				"val" : 0, | ||||
| 				"valueType" : "INDEPENDENT_MIN", | ||||
| 				"description" : "Creatures on Cursed Ground" | ||||
| 			}, | ||||
| 			{ | ||||
| 				"type" : "BLOCK_MAGIC_ABOVE", | ||||
| 				"subtype" : 0, | ||||
| 				"val" : 1, | ||||
| 				"valueType" : "INDEPENDENT_MIN" | ||||
| 			} | ||||
| 		] | ||||
| 	}, | ||||
| 	"rough": { "graphics" : "CMBKRGH.BMP" }, | ||||
| 	"ship_to_ship":  | ||||
| 	{ | ||||
| 		"graphics" : "CMBKBOAT.BMP" | ||||
| 		"impassableHexes" : [ | ||||
| 			6, 7, 8, 9, | ||||
| 			24, 25, 26, | ||||
| 			58, 59, 60, | ||||
| 			75, 76, 77, | ||||
| 			92, 93, 94, | ||||
| 			109, 110, 111, | ||||
| 			126, 127, 128, | ||||
| 			159, 160, 161, 162, 163, | ||||
| 			176, 177, 178, 179, 180] | ||||
| 	}, | ||||
| 	"ship": { "graphics" : "CMBKDECK.BMP" } | ||||
| } | ||||
| @@ -1,33 +1,4 @@ | ||||
| { | ||||
| 	// backgrounds of terrains battles can be fought on | ||||
| 	"backgrounds": { | ||||
| 		"sand_shore": "CMBKBCH.BMP", | ||||
| 		"sand_mesas": "CMBKDES.BMP", | ||||
| 		"dirt_birches": "CMBKDRTR.BMP", | ||||
| 		"dirt_hills": "CMBKDRMT.BMP", | ||||
| 		"dirt_pines": "CMBKDRDD.BMP", | ||||
| 		"grass_hills": "CMBKGRMT.BMP", | ||||
| 		"grass_pines": "CMBKGRTR.BMP", | ||||
| 		"lava": "CMBKLAVA.BMP", | ||||
| 		"magic_plains": "CMBKMAG.BMP", | ||||
| 		"snow_mountains": "CMBKSNMT.BMP", | ||||
| 		"snow_trees": "CMBKSNTR.BMP", | ||||
| 		"subterranean": "CMBKSUB.BMP", | ||||
| 		"swamp_trees": "CMBKSWMP.BMP", | ||||
| 		"fiery_fields": "CMBKFF.BMP", | ||||
| 		"rocklands": "CMBKRK.BMP", | ||||
| 		"magic_clouds": "CMBKMC.BMP", | ||||
| 		"lucid_pools": "CMBKLP.BMP", | ||||
| 		"holy_ground": "CMBKHG.BMP", | ||||
| 		"clover_field": "CMBKCF.BMP", | ||||
| 		"evil_fog": "CMBKEF.BMP", | ||||
| 		"favorable_winds": "CMBKFW.BMP", | ||||
| 		"cursed_ground": "CMBKCUR.BMP", | ||||
| 		"rough": "CMBKRGH.BMP", | ||||
| 		"ship_to_ship": "CMBKBOAT.BMP", | ||||
| 		"ship": "CMBKDECK.BMP" | ||||
| 	}, | ||||
|  | ||||
| 	// WoG_Ac_format_to_def_names_mapping | ||||
| 	"ac_mapping": [ | ||||
| 		{ "id": 0, "defnames": [ "C10SPW.DEF" ] },//merged | ||||
|   | ||||
| @@ -84,5 +84,9 @@ | ||||
| 	"terrains": | ||||
| 	[ | ||||
| 		"config/terrains.json" | ||||
| 	], | ||||
| 	"battlefields": | ||||
| 	[ | ||||
| 		"config/battlefields.json" | ||||
| 	] | ||||
| } | ||||
|   | ||||
							
								
								
									
										35
									
								
								config/schemas/battlefield.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								config/schemas/battlefield.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| { | ||||
| 	"type":"object", | ||||
| 	"$schema": "http://json-schema.org/draft-04/schema", | ||||
| 	"title" : "VCMI battlefield format", | ||||
| 	"description" : "Format used to define new artifacts in VCMI", | ||||
| 	"required" : [ "graphics" ], | ||||
|  | ||||
| 	"additionalProperties" : false, | ||||
| 	"properties":{ | ||||
| 		"bonuses": { | ||||
| 			"type":"array", | ||||
| 			"description": "Bonuses provided by this battleground using bonus system", | ||||
| 			"items": { "$ref" : "bonus.json" } | ||||
| 		}, | ||||
| 		"name": { | ||||
| 			"type":"string", | ||||
| 			"description": "Name of the battleground" | ||||
| 		}, | ||||
| 		"graphics": { | ||||
| 			"type":"string", | ||||
| 			"description": "BMP battleground resource" | ||||
| 		}, | ||||
| 		"isSpecial": { | ||||
| 			"type":"boolean", | ||||
| 			"description": "Shows if this battleground has own obstacles" | ||||
| 		}, | ||||
| 		"impassableHexes": { | ||||
| 			"type":"array", | ||||
| 			"description": "Battle hexes always impassable for this type of battlefield (ship to ship for instance)", | ||||
| 			"items": { | ||||
| 				"type":"number" | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -112,6 +112,12 @@ | ||||
| 			"description": "List of configuration files for RMG templates", | ||||
| 			"items": { "type":"string", "format" : "textFile" } | ||||
|  | ||||
| 		}, | ||||
| 		"battlefields":{ | ||||
| 			"type":"array", | ||||
| 			"description": "List of configuration files for battlefields", | ||||
| 			"items": { "type":"string", "format" : "textFile" } | ||||
|  | ||||
| 		}, | ||||
|  | ||||
| 		"changelog" : { | ||||
|   | ||||
| @@ -19,6 +19,7 @@ class HeroClassService; | ||||
| class HeroTypeService; | ||||
| class SkillService; | ||||
| class JsonNode; | ||||
| class BattleFieldService; | ||||
|  | ||||
| namespace spells | ||||
| { | ||||
| @@ -48,6 +49,7 @@ public: | ||||
| 	virtual const scripting::Service * scripts() const = 0; | ||||
| 	virtual const spells::Service * spells() const = 0; | ||||
| 	virtual const SkillService * skills() const = 0; | ||||
| 	virtual const BattleFieldService * battlefields() const = 0; | ||||
|  | ||||
| 	virtual void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) = 0; | ||||
|  | ||||
|   | ||||
							
								
								
									
										108
									
								
								lib/BattleFieldHandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								lib/BattleFieldHandler.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* | ||||
|  * BattleFieldHandler.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 | ||||
|  * | ||||
|  */ | ||||
| #include "StdInc.h" | ||||
|  | ||||
| #include <vcmi/Entity.h> | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| BattleFieldInfo * BattleFieldHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) | ||||
| { | ||||
| 	BattleFieldInfo * info = new BattleFieldInfo(BattleField(index), identifier); | ||||
|  | ||||
| 	if(json["graphics"].getType() == JsonNode::JsonType::DATA_STRING) | ||||
| 	{ | ||||
| 		info->graphics = json["graphics"].String(); | ||||
| 	} | ||||
|  | ||||
| 	if(json["icon"].getType() == JsonNode::JsonType::DATA_STRING) | ||||
| 	{ | ||||
| 		info->icon = json["icon"].String(); | ||||
| 	} | ||||
|  | ||||
| 	if(json["name"].getType() == JsonNode::JsonType::DATA_STRING) | ||||
| 	{ | ||||
| 		info->name = json["name"].String(); | ||||
| 	} | ||||
|  | ||||
| 	if(json["bonuses"].getType() == JsonNode::JsonType::DATA_VECTOR) | ||||
| 	{ | ||||
| 		for(auto b : json["bonuses"].Vector()) | ||||
| 		{ | ||||
| 			auto bonus = JsonUtils::parseBonus(b); | ||||
|  | ||||
| 			bonus->source = Bonus::TERRAIN_OVERLAY; | ||||
| 			bonus->sid = info->getIndex(); | ||||
| 			bonus->duration = Bonus::ONE_BATTLE; | ||||
|  | ||||
| 			info->bonuses.push_back(bonus); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(json["isSpecial"].getType() == JsonNode::JsonType::DATA_BOOL) | ||||
| 	{ | ||||
| 		info->isSpecial = json["isSpecial"].Bool(); | ||||
| 	} | ||||
|  | ||||
| 	if(json["impassableHexes"].getType() == JsonNode::JsonType::DATA_VECTOR) | ||||
| 	{ | ||||
| 		for(auto node : json["impassableHexes"].Vector()) | ||||
| 			info->impassableHexes.push_back(BattleHex(node.Integer())); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	return info; | ||||
| } | ||||
|  | ||||
| std::vector<JsonNode> BattleFieldHandler::loadLegacyData(size_t dataSize) | ||||
| { | ||||
| 	return std::vector<JsonNode>(); | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & BattleFieldHandler::getTypeNames() const | ||||
| { | ||||
| 	static const  std::vector<std::string> types = std::vector<std::string> { "battlefield" }; | ||||
|  | ||||
| 	return types; | ||||
| } | ||||
|  | ||||
| std::vector<bool> BattleFieldHandler::getDefaultAllowed() const | ||||
| { | ||||
| 	return std::vector<bool>(); | ||||
| } | ||||
|  | ||||
| int32_t BattleFieldInfo::getIndex() const | ||||
| { | ||||
| 	return battlefield.getNum(); | ||||
| } | ||||
|  | ||||
| int32_t BattleFieldInfo::getIconIndex() const | ||||
| { | ||||
| 	return iconIndex; | ||||
| } | ||||
|  | ||||
| const std::string & BattleFieldInfo::getName() const | ||||
| { | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| const std::string & BattleFieldInfo::getJsonKey() const | ||||
| { | ||||
| 	return identifier; | ||||
| } | ||||
|  | ||||
| void BattleFieldInfo::registerIcons(const IconRegistar & cb) const | ||||
| { | ||||
| 	//cb(getIconIndex(), "BATTLEFIELD", icon); | ||||
| } | ||||
|  | ||||
| BattleField BattleFieldInfo::getId() const | ||||
| { | ||||
| 	return battlefield; | ||||
| } | ||||
							
								
								
									
										85
									
								
								lib/BattleFieldHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/BattleFieldHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| /* | ||||
|  * BattleFieldHandler.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 <vcmi/EntityService.h> | ||||
| #include "HeroBonus.h" | ||||
| #include "GameConstants.h" | ||||
| #include "IHandlerBase.h" | ||||
| #include "Terrain.h" | ||||
| #include "battle/BattleHex.h" | ||||
|  | ||||
| class BattleFieldInfo : public EntityT<BattleField> | ||||
| { | ||||
| public: | ||||
| 	BattleField battlefield; | ||||
| 	std::vector<std::shared_ptr<Bonus>> bonuses; | ||||
| 	bool isSpecial; | ||||
| 	std::string graphics; | ||||
| 	std::string name; | ||||
| 	std::string identifier; | ||||
| 	std::string icon; | ||||
| 	si32 iconIndex; | ||||
| 	std::vector<BattleHex> impassableHexes; | ||||
|  | ||||
| 	BattleFieldInfo()  | ||||
| 		: BattleFieldInfo(BattleField::NONE, "") | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	BattleFieldInfo(BattleField battlefield, std::string identifier) | ||||
| 		:bonuses(), isSpecial(false), battlefield(battlefield), identifier(identifier), graphics(), icon(), iconIndex(battlefield.getNum()), impassableHexes(), name(identifier) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	int32_t getIndex() const override; | ||||
| 	int32_t getIconIndex() const override; | ||||
| 	const std::string & getName() const override; | ||||
| 	const std::string & getJsonKey() const override; | ||||
| 	void registerIcons(const IconRegistar & cb) const override; | ||||
| 	BattleField getId() const override; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler & h, const int version) | ||||
| 	{ | ||||
| 		h & name; | ||||
| 		h & identifier; | ||||
| 		h & isSpecial; | ||||
| 		h & graphics; | ||||
| 		h & icon; | ||||
| 		h & iconIndex; | ||||
| 		h & battlefield; | ||||
| 		h & impassableHexes; | ||||
|  | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE BattleFieldService : public EntityServiceT<BattleField, BattleFieldInfo> | ||||
| { | ||||
| public: | ||||
| }; | ||||
|  | ||||
| class BattleFieldHandler : public CHandlerBase<BattleField, BattleFieldInfo, BattleFieldInfo, BattleFieldService> | ||||
| { | ||||
| public: | ||||
| 	virtual BattleFieldInfo * loadFromJson( | ||||
| 		const std::string & scope, | ||||
| 		const JsonNode & json, | ||||
| 		const std::string & identifier, | ||||
| 		size_t index) override; | ||||
|  | ||||
| 	virtual const std::vector<std::string> & getTypeNames() const override; | ||||
| 	virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override; | ||||
| 	virtual std::vector<bool> getDefaultAllowed() const override; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler & h, const int version) | ||||
| 	{ | ||||
| 		h & objects; | ||||
| 	} | ||||
| }; | ||||
| @@ -1922,9 +1922,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & r | ||||
| 	} | ||||
|  | ||||
| 	if(map->isCoastalTile(tile)) //coastal tile is always ground | ||||
| 		return BattleField("sand_shore"); | ||||
| 		return BattleField::fromString("sand_shore"); | ||||
| 	 | ||||
| 	return *RandomGeneratorUtil::nextItem(Terrain::Manager::getInfo(t.terType).battleFields, rand); | ||||
| 	return BattleField::fromString( | ||||
| 		*RandomGeneratorUtil::nextItem(Terrain::Manager::getInfo(t.terType).battleFields, rand)); | ||||
| } | ||||
|  | ||||
| UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack) | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include <math.h> | ||||
|  | ||||
| #include "mapObjects/CObjectClassesHandler.h" | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| CHero::CHero() = default; | ||||
| CHero::~CHero() = default; | ||||
| @@ -179,8 +180,10 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const | ||||
|  | ||||
| bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const | ||||
| { | ||||
| 	if(battlefield.isSpecial()) | ||||
| 		return vstd::contains(allowedSpecialBfields, battlefield); | ||||
| 	auto bgInfo = battlefield.getInfo(); | ||||
|  | ||||
| 	if(bgInfo->isSpecial) | ||||
| 		return vstd::contains(allowedSpecialBfields, bgInfo->identifier); | ||||
|  | ||||
| 	return vstd::contains(allowedTerrains, terrainType); | ||||
| } | ||||
|   | ||||
| @@ -227,7 +227,7 @@ struct DLL_LINKAGE CObstacleInfo | ||||
| { | ||||
| 	std::string defName; | ||||
| 	std::vector<Terrain> allowedTerrains; | ||||
| 	std::vector<BattleField> allowedSpecialBfields; | ||||
| 	std::vector<std::string> 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) | ||||
|   | ||||
| @@ -129,7 +129,8 @@ set(lib_SRCS | ||||
| 		spells/effects/Sacrifice.cpp | ||||
|  | ||||
| 		vstd/StringUtils.cpp | ||||
|  | ||||
| 		 | ||||
| 		BattleFieldHandler.cpp | ||||
| 		CAndroidVMHelper.cpp | ||||
| 		CArtHandler.cpp | ||||
| 		CBonusTypeHandler.cpp | ||||
| @@ -338,6 +339,7 @@ set(lib_HEADERS | ||||
| 		spells/effects/Sacrifice.h | ||||
|  | ||||
| 		AI_Base.h | ||||
| 		BattleFieldHandler.h | ||||
| 		CAndroidVMHelper.h | ||||
| 		CArtHandler.h | ||||
| 		CBonusTypeHandler.h | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "spells/CSpellHandler.h" | ||||
| #include "CSkillHandler.h" | ||||
| #include "ScriptHandler.h" | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| #include <vstd/StringUtils.h> | ||||
|  | ||||
| @@ -433,6 +434,7 @@ void CContentHandler::init() | ||||
| 	handlers.insert(std::make_pair("skills", ContentTypeHandler(VLC->skillh, "skill"))); | ||||
| 	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"))); | ||||
| 	//TODO: any other types of moddables? | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ | ||||
| #include "StringConstants.h" | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "CModHandler.h"//todo: remove | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2); | ||||
| const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3); | ||||
| @@ -255,3 +256,40 @@ std::ostream & operator<<(std::ostream & os, const EPathfindingLayer pathfinding | ||||
| 	if (it == pathfinderLayerToString.end()) return os << "<Unknown type>"; | ||||
| 	else return os << it->second; | ||||
| } | ||||
|  | ||||
| const BattleField BattleField::NONE; | ||||
|  | ||||
| bool operator==(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.num == r.num; | ||||
| } | ||||
|  | ||||
| bool operator!=(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.num != r.num; | ||||
| } | ||||
|  | ||||
| bool operator<(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.num < r.num; | ||||
| } | ||||
|  | ||||
| BattleField::operator std::string() const | ||||
| { | ||||
| 	return getInfo()->identifier; | ||||
| } | ||||
|  | ||||
| const BattleFieldInfo * BattleField::getInfo() const | ||||
| { | ||||
| 	return VLC->battlefields()->getById(*this); | ||||
| } | ||||
|  | ||||
| BattleField BattleField::fromString(std::string identifier) | ||||
| { | ||||
| 	auto rawId = VLC->modh->identifiers.getIdentifier("core", "battlefield", identifier); | ||||
|  | ||||
| 	if(rawId) | ||||
| 		return BattleField(rawId.get()); | ||||
| 	else | ||||
| 		return BattleField::NONE; | ||||
| } | ||||
| @@ -1109,6 +1109,23 @@ public: | ||||
|  | ||||
| ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID) | ||||
|  | ||||
| class BattleFieldInfo; | ||||
| class BattleField : public BaseForID<BattleField, si32> | ||||
| { | ||||
| 	INSTID_LIKE_CLASS_COMMON(BattleField, si32) | ||||
|  | ||||
| 	DLL_LINKAGE static const BattleField NONE; | ||||
|  | ||||
| 	DLL_LINKAGE friend bool operator==(const BattleField & l, const BattleField & r); | ||||
| 	DLL_LINKAGE friend bool operator!=(const BattleField & l, const BattleField & r); | ||||
| 	DLL_LINKAGE friend bool operator<(const BattleField & l, const BattleField & r); | ||||
|  | ||||
| 	DLL_LINKAGE operator std::string() const; | ||||
| 	DLL_LINKAGE const BattleFieldInfo * getInfo() const; | ||||
|  | ||||
| 	DLL_LINKAGE static BattleField fromString(std::string identifier); | ||||
| }; | ||||
|  | ||||
| enum class ESpellSchool: ui8 | ||||
| { | ||||
| 	AIR 	= 0, | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
| #include "NetPacks.h" | ||||
| #include "CBonusTypeHandler.h" | ||||
| #include "CModHandler.h" | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| #include "serializer/CSerializer.h" // for SAVEGAME_MAGIC | ||||
| #include "serializer/BinaryDeserializer.h" | ||||
|   | ||||
| @@ -18,8 +18,6 @@ | ||||
|  | ||||
| const Terrain Terrain::ANY("ANY"); | ||||
|  | ||||
| const BattleField BattleField::NONE(""); | ||||
|  | ||||
| Terrain Terrain::createTerrainTypeH3M(int tId) | ||||
| { | ||||
| 	static std::array<std::string, 10> terrainsH3M | ||||
| @@ -227,27 +225,3 @@ bool Terrain::isTransitionRequired() const | ||||
| { | ||||
| 	return Terrain::Manager::getInfo(*this).transitionRequired; | ||||
| } | ||||
|  | ||||
| bool operator==(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.name == r.name; | ||||
| } | ||||
|  | ||||
| bool operator!=(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.name != r.name; | ||||
| } | ||||
|  | ||||
| bool operator<(const BattleField & l, const BattleField & r) | ||||
| { | ||||
| 	return l.name < r.name; | ||||
| } | ||||
| BattleField::operator std::string() const | ||||
| { | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| int BattleField::hash() const | ||||
| { | ||||
| 	return std::hash<std::string>{}(name); | ||||
| } | ||||
|   | ||||
| @@ -11,47 +11,9 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "ConstTransitivePtr.h" | ||||
| #include "GameConstants.h" | ||||
| #include "JsonNode.h" | ||||
|  | ||||
| class DLL_LINKAGE BattleField | ||||
| { | ||||
| public: | ||||
| 	//   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines | ||||
| 	//8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields | ||||
| 	//15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog | ||||
| 	//21. "favorable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship | ||||
| 	/*enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS, | ||||
| 	 GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS, | ||||
| 	 ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVORABLE_WINDS, CURSED_GROUND, | ||||
| 	 ROUGH, SHIP_TO_SHIP, SHIP | ||||
| 	 };*/ | ||||
| 	 | ||||
| 	BattleField(const std::string & type = "") : name(type) | ||||
| 	{} | ||||
| 	 | ||||
| 	static const BattleField NONE; | ||||
| 	 | ||||
| 	DLL_LINKAGE friend bool operator==(const BattleField & l, const BattleField & r); | ||||
| 	DLL_LINKAGE friend bool operator!=(const BattleField & l, const BattleField & r); | ||||
| 	DLL_LINKAGE friend bool operator<(const BattleField & l, const BattleField & r); | ||||
| 	 | ||||
| 	operator std::string() const; | ||||
| 	int hash() const; | ||||
| 	 | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & name; | ||||
| 	} | ||||
|  | ||||
| 	bool isSpecial() const | ||||
| 	{ | ||||
| 		return name.find('_') >= 0; // hack for special battlefields, move to JSON | ||||
| 	} | ||||
| 	 | ||||
| protected: | ||||
| 	 | ||||
| 	std::string name; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE Terrain | ||||
| { | ||||
| @@ -77,7 +39,7 @@ public: | ||||
| 		std::string terrainViewPatterns; | ||||
| 		int horseSoundId; | ||||
| 		Type type; | ||||
| 		std::vector<BattleField> battleFields; | ||||
| 		std::vector<std::string> battleFields; | ||||
| 	}; | ||||
| 	 | ||||
| 	class DLL_LINKAGE Manager | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
| #include "rmg/CRmgTemplateStorage.h" | ||||
| #include "mapping/CMapEditManager.h" | ||||
| #include "ScriptHandler.h" | ||||
| #include "BattleFieldHandler.h" | ||||
|  | ||||
| LibClasses * VLC = nullptr; | ||||
|  | ||||
| @@ -110,6 +111,11 @@ spells::effects::Registry * LibClasses::spellEffects() | ||||
| 	return spells::effects::GlobalRegistry::get(); | ||||
| } | ||||
|  | ||||
| const BattleFieldService * LibClasses::battlefields() const | ||||
| { | ||||
| 	return battlefieldsHandler; | ||||
| } | ||||
|  | ||||
| void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data) | ||||
| { | ||||
| 	switch(metatype) | ||||
| @@ -205,6 +211,8 @@ void LibClasses::init(bool onlyEssential) | ||||
|  | ||||
| 	createHandler(scriptHandler, "Script", pomtime); | ||||
|  | ||||
| 	createHandler(battlefieldsHandler, "Battlefields", pomtime); | ||||
|  | ||||
| 	logGlobal->info("\tInitializing handlers: %d ms", totalTime.getDiff()); | ||||
|  | ||||
| 	modh->load(); | ||||
| @@ -231,6 +239,7 @@ void LibClasses::clear() | ||||
| 	delete tplh; | ||||
| 	delete terviewh; | ||||
| 	delete scriptHandler; | ||||
| 	delete battlefieldsHandler; | ||||
| 	makeNull(); | ||||
| } | ||||
|  | ||||
| @@ -250,6 +259,7 @@ void LibClasses::makeNull() | ||||
| 	tplh = nullptr; | ||||
| 	terviewh = nullptr; | ||||
| 	scriptHandler = nullptr; | ||||
| 	battlefieldsHandler = nullptr; | ||||
| } | ||||
|  | ||||
| LibClasses::LibClasses() | ||||
|   | ||||
| @@ -24,6 +24,7 @@ class CTownHandler; | ||||
| class CGeneralTextHandler; | ||||
| class CModHandler; | ||||
| class CContentHandler; | ||||
| class BattleFieldHandler; | ||||
| class IBonusTypeHandler; | ||||
| class CBonusTypeHandler; | ||||
| class CTerrainViewPatternConfig; | ||||
| @@ -56,6 +57,7 @@ public: | ||||
| 	const scripting::Service * scripts() const override; | ||||
| 	const spells::Service * spells() const override; | ||||
| 	const SkillService * skills() const override; | ||||
| 	const BattleFieldService * battlefields() const override; | ||||
|  | ||||
| 	void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override; | ||||
|  | ||||
| @@ -76,6 +78,7 @@ public: | ||||
| 	CModHandler * modh; | ||||
| 	CTerrainViewPatternConfig * terviewh; | ||||
| 	CRmgTemplateStorage * tplh; | ||||
| 	BattleFieldHandler * battlefieldsHandler; | ||||
| 	scripting::ScriptHandler * scriptHandler; | ||||
|  | ||||
| 	LibClasses(); //c-tor, loads .lods and NULLs handlers | ||||
| @@ -104,6 +107,8 @@ public: | ||||
| 		h & objtypeh; | ||||
| 		h & spellh; | ||||
| 		h & skillh; | ||||
| 		h & battlefieldsHandler; | ||||
|  | ||||
| 		if(!h.saving) | ||||
| 		{ | ||||
| 			//modh will be changed and modh->content will be empty after deserialization | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
| #include "../mapObjects/CGTownInstance.h" | ||||
| #include "../CGeneralTextHandler.h" | ||||
| #include "../Terrain.h" | ||||
| #include "../BattleFieldHandler.h" | ||||
|  | ||||
| //TODO: remove | ||||
| #include "../IGameCallback.h" | ||||
| @@ -458,64 +459,12 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, | ||||
| 	auto good = std::make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD); | ||||
| 	auto evil = std::make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL); | ||||
|  | ||||
| 	//giving terrain overlay premies | ||||
| 	int bonusSubtype = -1; | ||||
| 	auto bgInfo = VLC->battlefields()->getById(battlefieldType); | ||||
|  | ||||
| 	if(battlefieldType == BattleField("magic_plains")) | ||||
| 	for(const std::shared_ptr<Bonus> & bonus : bgInfo->bonuses) | ||||
| 	{ | ||||
| 		bonusSubtype = 0; | ||||
| 		curB->addNewBonus(bonus); | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("fiery_fields")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 2; | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("rocklands")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 8; | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("magic_clouds")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 1; | ||||
| 	} | ||||
| 	if(battlefieldType == BattleField("lucid_pools")) | ||||
| 	{ | ||||
| 		if(bonusSubtype == -1) bonusSubtype = 4; | ||||
| 	} | ||||
| 	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)); | ||||
| 	} | ||||
| 	else if(battlefieldType == BattleField("holy_ground")) | ||||
| 	{ | ||||
| 		std::string goodArmyDesc = VLC->generaltexth->arraytxt[123]; | ||||
| 		goodArmyDesc.erase(goodArmyDesc.size() - 2, 2); //omitting hardcoded +1 in description | ||||
| 		std::string evilArmyDesc = VLC->generaltexth->arraytxt[124]; | ||||
| 		evilArmyDesc.erase(evilArmyDesc.size() - 2, 2); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType.hash(), goodArmyDesc, 0)->addLimiter(good)); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType.hash(), evilArmyDesc, 0)->addLimiter(evil)); | ||||
| 	} | ||||
| 	else if(battlefieldType == BattleField("clover_field")) | ||||
| 	{ //+2 luck bonus for neutral creatures | ||||
| 		std::string desc = VLC->generaltexth->arraytxt[83]; | ||||
| 		desc.erase(desc.size() - 2, 2); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::LUCK, Bonus::TERRAIN_OVERLAY, +2, battlefieldType.hash(), desc, 0)->addLimiter(neutral)); | ||||
| 	} | ||||
| 	else if(battlefieldType == BattleField("evil_fog")) | ||||
| 	{ | ||||
| 		std::string goodArmyDesc = VLC->generaltexth->arraytxt[126]; | ||||
| 		goodArmyDesc.erase(goodArmyDesc.size() - 2, 2); | ||||
| 		std::string evilArmyDesc = VLC->generaltexth->arraytxt[125]; | ||||
| 		evilArmyDesc.erase(evilArmyDesc.size() - 2, 2); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType.hash(), goodArmyDesc, 0)->addLimiter(good)); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType.hash(), evilArmyDesc, 0)->addLimiter(evil)); | ||||
| 	} | ||||
| 	else if(battlefieldType == BattleField("cursed_ground")) | ||||
| 	{ | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_MORALE, Bonus::TERRAIN_OVERLAY, 0, battlefieldType.hash(), VLC->generaltexth->arraytxt[112], 0)); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_LUCK, Bonus::TERRAIN_OVERLAY, 0, battlefieldType.hash(), VLC->generaltexth->arraytxt[81], 0)); | ||||
| 		curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::BLOCK_MAGIC_ABOVE, Bonus::TERRAIN_OVERLAY, 1, battlefieldType.hash(), 0, Bonus::INDEPENDENT_MIN)); | ||||
| 	} | ||||
| 	//overlay premies given | ||||
|  | ||||
| 	//native terrain bonuses | ||||
| 	static auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>(); | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| #include "../NetPacks.h" | ||||
| #include "../spells/CSpellHandler.h" | ||||
| #include "../mapObjects/CGTownInstance.h" | ||||
| #include "../BattleFieldHandler.h" | ||||
|  | ||||
| namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO | ||||
| { | ||||
| @@ -1058,24 +1059,15 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const | ||||
| 	} | ||||
|  | ||||
| 	//special battlefields with logically unavailable tiles | ||||
| 	std::vector<BattleHex> impassableHexes; | ||||
| 	if(battleGetBattlefieldType() == BattleField("ship_to_ship")) | ||||
| 	auto bFieldType = battleGetBattlefieldType(); | ||||
|  | ||||
| 	if(bFieldType != BattleField::NONE) | ||||
| 	{ | ||||
| 		impassableHexes = | ||||
| 		{ | ||||
| 			6, 7, 8, 9, | ||||
| 			24, 25, 26, | ||||
| 			58, 59, 60, | ||||
| 			75, 76, 77, | ||||
| 			92, 93, 94, | ||||
| 			109, 110, 111, | ||||
| 			126, 127, 128, | ||||
| 			159, 160, 161, 162, 163, | ||||
| 			176, 177, 178, 179, 180 | ||||
| 		}; | ||||
| 		std::vector<BattleHex> impassableHexes = bFieldType.getInfo()->impassableHexes; | ||||
|  | ||||
| 		for(auto hex : impassableHexes) | ||||
| 			ret[hex] = EAccessibility::UNAVAILABLE; | ||||
| 	} | ||||
| 	for(auto hex : impassableHexes) | ||||
| 		ret[hex] = EAccessibility::UNAVAILABLE; | ||||
|  | ||||
| 	//gate -> should be before stacks | ||||
| 	if(battleGetSiegeLevel() > 0) | ||||
|   | ||||
| @@ -515,10 +515,10 @@ 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; | ||||
| 	if(input["battleground"].getType() == JsonNode::JsonType::DATA_STRING) | ||||
| 		battlefield = input["battleground"].String(); | ||||
| 	else | ||||
| 		battlefield = BattleField(input["battleground"].String()); | ||||
| 		battlefield = boost::none; | ||||
|  | ||||
| 	initTypeData(input); | ||||
| } | ||||
| @@ -577,7 +577,7 @@ std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const | ||||
|  | ||||
| BattleField AObjectTypeHandler::getBattlefield() const | ||||
| { | ||||
| 	return battlefield; | ||||
| 	return battlefield ? BattleField::fromString(battlefield.get()) : BattleField::NONE; | ||||
| } | ||||
|  | ||||
| std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(const Terrain & terrainType) const | ||||
|   | ||||
| @@ -150,7 +150,7 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable | ||||
|  | ||||
| 	boost::optional<si32> aiValue; | ||||
|  | ||||
| 	BattleField battlefield; | ||||
| 	boost::optional<std::string> battlefield; | ||||
|  | ||||
| protected: | ||||
| 	void preInitObject(CGObjectInstance * obj) const; | ||||
| @@ -219,6 +219,7 @@ public: | ||||
| 		h & subTypeName; | ||||
| 		h & sounds; | ||||
| 		h & aiValue; | ||||
| 		h & battlefield; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -461,12 +461,15 @@ const std::vector<CTerrainViewPatternConfig::TVPVector> & CTerrainViewPatternCon | ||||
| 	return iter->second; | ||||
| } | ||||
|  | ||||
| boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(const Terrain & terrain, const std::string & id) const | ||||
| boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(std::string patternId, const std::string & id) const | ||||
| { | ||||
| 	const std::vector<TVPVector> & groupPatterns = getTerrainViewPatterns(terrain); | ||||
| 	auto iter = terrainViewPatterns.find(patternId); | ||||
| 	const std::vector<TVPVector> & groupPatterns = (iter == terrainViewPatterns.end()) ? terrainViewPatterns.at("normal") : iter->second; | ||||
|  | ||||
| 	for (const TVPVector & patternFlips : groupPatterns) | ||||
| 	{ | ||||
| 		const TerrainViewPattern & pattern = patternFlips.front(); | ||||
|  | ||||
| 		if(id == pattern.id) | ||||
| 		{ | ||||
| 			return boost::optional<const TerrainViewPattern &>(pattern); | ||||
|   | ||||
| @@ -327,7 +327,7 @@ public: | ||||
| 	~CTerrainViewPatternConfig(); | ||||
|  | ||||
| 	const std::vector<TVPVector> & getTerrainViewPatterns(const Terrain & terrain) const; | ||||
| 	boost::optional<const TerrainViewPattern &> getTerrainViewPatternById(const Terrain & terrain, const std::string & id) const; | ||||
| 	boost::optional<const TerrainViewPattern &> getTerrainViewPatternById(std::string patternId, const std::string & id) const; | ||||
| 	boost::optional<const TVPVector &> getTerrainViewPatternsById(const Terrain & terrain, const std::string & id) const; | ||||
| 	const TVPVector * getTerrainTypePatternById(const std::string & id) const; | ||||
| 	void flipPattern(TerrainViewPattern & pattern, int flip) const; | ||||
|   | ||||
| @@ -55,6 +55,7 @@ void registerTypesMapObjects1(Serializer &s) | ||||
| 	s.template registerType<CGObjectInstance, CGShipyard>(); s.template registerType<IShipyard, CGShipyard>(); | ||||
| 	s.template registerType<CGObjectInstance, CGDenOfthieves>(); | ||||
| 	s.template registerType<CGObjectInstance, CGLighthouse>(); | ||||
| 	s.template registerType<CGObjectInstance, CGTerrainPatch>(); | ||||
| 	s.template registerType<CGObjectInstance, CGMarket>(); s.template registerType<IMarket, CGMarket>(); | ||||
| 		s.template registerType<CGMarket, CGBlackMarket>(); | ||||
| 		s.template registerType<CGMarket, CGUniversity>(); | ||||
| @@ -108,6 +109,7 @@ void registerTypesMapObjectTypes(Serializer &s) | ||||
| 	REGISTER_GENERIC_HANDLER(CGHeroInstance); | ||||
| 	REGISTER_GENERIC_HANDLER(CGKeymasterTent); | ||||
| 	REGISTER_GENERIC_HANDLER(CGLighthouse); | ||||
| 	REGISTER_GENERIC_HANDLER(CGTerrainPatch); | ||||
| 	REGISTER_GENERIC_HANDLER(CGMagi); | ||||
| 	REGISTER_GENERIC_HANDLER(CGMagicSpring); | ||||
| 	REGISTER_GENERIC_HANDLER(CGMagicWell); | ||||
|   | ||||
| @@ -246,8 +246,18 @@ void CMapGenOptions::finalize(CRandomGenerator & rand) | ||||
|  | ||||
| 	if(waterContent == EWaterContent::RANDOM) | ||||
| 	{ | ||||
| 		waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand); | ||||
| 		auto allowedContent = mapTemplate->getWaterContentAllowed(); | ||||
|  | ||||
| 		if(allowedContent.size()) | ||||
| 		{ | ||||
| 			waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			waterContent = EWaterContent::NONE; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(monsterStrength == EMonsterStrength::RANDOM) | ||||
| 	{ | ||||
| 		monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(rand.nextInt(EMonsterStrength::GLOBAL_WEAK, EMonsterStrength::GLOBAL_STRONG)); | ||||
|   | ||||
| @@ -2019,6 +2019,10 @@ int3 CRmgTemplateZone::makeBoat(TRmgTemplateZoneId land, const std::set<int3> & | ||||
| { | ||||
| 	std::set<int3> lakeCoast; | ||||
| 	std::set_intersection(gen->getZones()[land]->getCoastTiles().begin(), gen->getZones()[land]->getCoastTiles().end(), lake.begin(), lake.end(), std::inserter(lakeCoast, lakeCoast.begin())); | ||||
|  | ||||
| 	if(lakeCoast.empty()) | ||||
| 		return int3(-1, -1, -1); | ||||
|  | ||||
| 	for(int randomAttempts = 0; randomAttempts<5; ++randomAttempts) | ||||
| 	{ | ||||
| 		auto coastTile = *RandomGeneratorUtil::nextItem(lakeCoast, gen->rand); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| #include "ISpellMechanics.h" | ||||
|  | ||||
| #include "../CRandomGenerator.h" | ||||
| #include "../VCMI_Lib.h" | ||||
|  | ||||
| #include "../HeroBonus.h" | ||||
| #include "../battle/CBattleInfoCallback.h" | ||||
| @@ -39,6 +40,7 @@ | ||||
|  | ||||
| #include "../CHeroHandler.h"//todo: remove | ||||
| #include "../IGameCallback.h"//todo: remove | ||||
| #include "../BattleFieldHandler.h" | ||||
|  | ||||
| namespace spells | ||||
| { | ||||
| @@ -520,7 +522,7 @@ bool BaseMechanics::adaptProblem(ESpellCastProblem::ESpellCastProblem source, Pr | ||||
| 				caster->getCasterName(text); | ||||
| 				target.add(std::move(text), spells::Problem::NORMAL); | ||||
| 			} | ||||
| 			else if(b && b->source == Bonus::TERRAIN_OVERLAY && b->sid == BattleField("cursed_ground").hash()) | ||||
| 			else if(b && b->source == Bonus::TERRAIN_OVERLAY && VLC->battlefields()->getByIndex(b->sid)->identifier == "cursed_ground") | ||||
| 			{ | ||||
| 				text.addTxt(MetaString::GENERAL_TXT, 537); | ||||
| 				target.add(std::move(text), spells::Problem::NORMAL); | ||||
|   | ||||
| @@ -10,12 +10,14 @@ | ||||
| #include "StdInc.h" | ||||
|  | ||||
| #include "BattleCb.h" | ||||
| #include <vcmi/Entity.h> | ||||
|  | ||||
| #include "../LuaStack.h" | ||||
| #include "../LuaCallWrapper.h" | ||||
|  | ||||
| #include "../../../lib/GameConstants.h" | ||||
| #include "../../../lib/battle/Unit.h" | ||||
| #include "../../../lib/BattleFieldHandler.h" | ||||
|  | ||||
| namespace scripting | ||||
| { | ||||
| @@ -73,7 +75,7 @@ int BattleCbProxy::getBattlefieldType(lua_State * L) | ||||
|  | ||||
| 	auto ret = object->battleGetBattlefieldType(); | ||||
|  | ||||
| 	return LuaStack::quickRetStr(L, ret); | ||||
| 	return LuaStack::quickRetStr(L, ret.getInfo()->identifier); | ||||
| } | ||||
|  | ||||
| int BattleCbProxy::getTerrainType(lua_State * L) | ||||
|   | ||||
| @@ -55,16 +55,16 @@ end | ||||
|  | ||||
| local SPECIAL_FIELDS = {} | ||||
|  | ||||
| SPECIAL_FIELDS[0] = 0 | ||||
| SPECIAL_FIELDS[22] = 1 | ||||
| SPECIAL_FIELDS[9] = 2 | ||||
| SPECIAL_FIELDS[18] = 3 | ||||
| SPECIAL_FIELDS[20] = 4 | ||||
| SPECIAL_FIELDS[19] = 5 | ||||
| SPECIAL_FIELDS[17] = 6 | ||||
| SPECIAL_FIELDS[14] = 7 | ||||
| SPECIAL_FIELDS[15] = 8 | ||||
| SPECIAL_FIELDS[16] = 9 | ||||
| SPECIAL_FIELDS['sand_shore'] = 0 | ||||
| SPECIAL_FIELDS['cursed_ground'] = 1 | ||||
| SPECIAL_FIELDS['magic_plains'] = 2 | ||||
| SPECIAL_FIELDS['holy_ground'] = 3 | ||||
| SPECIAL_FIELDS['evil_fog'] = 4 | ||||
| SPECIAL_FIELDS['clover_field'] = 5 | ||||
| SPECIAL_FIELDS['lucid_pools'] = 6 | ||||
| SPECIAL_FIELDS['fiery_fields'] = 7 | ||||
| SPECIAL_FIELDS['rocklands'] = 8 | ||||
| SPECIAL_FIELDS['magic_clouds'] = 9 | ||||
|  | ||||
|  | ||||
| function BU:G(x, p1) | ||||
|   | ||||
| @@ -2221,7 +2221,7 @@ void CGameHandler::setupBattle(int3 tile, const CArmedInstance *armies[2], const | ||||
|  | ||||
| 	BattleField terType = gs->battleGetBattlefieldType(tile, getRandomGenerator()); | ||||
| 	if (heroes[0] && heroes[0]->boat && heroes[1] && heroes[1]->boat) | ||||
| 		terType = BattleField("ship_to_ship"); | ||||
| 		terType = BattleField::fromString("ship_to_ship"); | ||||
|  | ||||
| 	//send info about battles | ||||
| 	BattleStart bs; | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "StdInc.h" | ||||
|  | ||||
| #include "../../lib/battle/CBattleInfoCallback.h" | ||||
| #include "../../lib/battle/CUnitState.h" | ||||
|  | ||||
| #include <vstd/RNG.h> | ||||
|  | ||||
| @@ -25,7 +26,15 @@ using namespace testing; | ||||
|  | ||||
| class UnitFake : public UnitMock | ||||
| { | ||||
| private: | ||||
| 	std::shared_ptr<CUnitState> state; | ||||
|  | ||||
| public: | ||||
| 	UnitFake() | ||||
| 	{ | ||||
| 		state.reset(new CUnitStateDetached(this, this)); | ||||
| 	} | ||||
|  | ||||
| 	void addNewBonus(const std::shared_ptr<Bonus> & b) | ||||
| 	{ | ||||
| 		bonusFake.addNewBonus(b); | ||||
| @@ -58,6 +67,13 @@ public: | ||||
| 		EXPECT_CALL(*this, unitSlot()).WillRepeatedly(Return(SlotID(0))); | ||||
| 		EXPECT_CALL(*this, creatureIndex()).WillRepeatedly(Return(0)); | ||||
| 	} | ||||
|  | ||||
| 	void setDefaultState() | ||||
| 	{ | ||||
| 		EXPECT_CALL(*this, isClone()).WillRepeatedly(Return(false)); | ||||
| 		EXPECT_CALL(*this, isCaster()).WillRepeatedly(Return(false)); | ||||
| 		EXPECT_CALL(*this, acquireState()).WillRepeatedly(Return(state)); | ||||
| 	} | ||||
| private: | ||||
| 	BonusBearerMock bonusFake; | ||||
| }; | ||||
| @@ -207,6 +223,7 @@ TEST_F(BattleFinishedTest, LastAliveUnitWins) | ||||
| { | ||||
| 	UnitFake & unit = unitsFake.add(1); | ||||
| 	unit.makeAlive(); | ||||
| 	unit.setDefaultState(); | ||||
|  | ||||
| 	setDefaultExpectations(); | ||||
| 	startBattle(); | ||||
| @@ -232,6 +249,7 @@ TEST_F(BattleFinishedTest, LastWarMachineNotWins) | ||||
| 	UnitFake & unit = unitsFake.add(0); | ||||
| 	unit.makeAlive(); | ||||
| 	unit.makeWarMachine(); | ||||
| 	unit.setDefaultState(); | ||||
|  | ||||
| 	setDefaultExpectations(); | ||||
| 	startBattle(); | ||||
| @@ -241,17 +259,26 @@ TEST_F(BattleFinishedTest, LastWarMachineNotWins) | ||||
|  | ||||
| TEST_F(BattleFinishedTest, LastWarMachineLoose) | ||||
| { | ||||
| 	UnitFake & unit1 = unitsFake.add(0); | ||||
| 	unit1.makeAlive(); | ||||
| 	try | ||||
| 	{ | ||||
| 		UnitFake & unit1 = unitsFake.add(0); | ||||
| 		unit1.makeAlive(); | ||||
| 		unit1.setDefaultState(); | ||||
|  | ||||
| 	UnitFake & unit2 = unitsFake.add(1); | ||||
| 	unit2.makeAlive(); | ||||
| 	unit2.makeWarMachine(); | ||||
| 		UnitFake & unit2 = unitsFake.add(1); | ||||
| 		unit2.makeAlive(); | ||||
| 		unit2.makeWarMachine(); | ||||
| 		unit2.setDefaultState(); | ||||
|  | ||||
| 	setDefaultExpectations(); | ||||
| 	startBattle(); | ||||
| 		setDefaultExpectations(); | ||||
| 		startBattle(); | ||||
|  | ||||
| 	expectBattleWinner(0); | ||||
| 		expectBattleWinner(0); | ||||
| 	} | ||||
| 	catch(std::exception e) | ||||
| 	{ | ||||
| 		logGlobal->error(e.what()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| class BattleMatchOwnerTest : public CBattleInfoCallbackTest | ||||
|   | ||||
| @@ -155,7 +155,7 @@ TEST_F(ERM_BU_G, Get) | ||||
| 	source << "!?PI;" << std::endl; | ||||
| 	source << "!!BU:G?v1;" << std::endl; | ||||
|  | ||||
| 	EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("snow_trees"))); | ||||
| 	EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField::fromString("snow_trees"))); | ||||
|  | ||||
|  | ||||
| 	loadScript(VLC->scriptHandler->erm, source.str()); | ||||
| @@ -169,12 +169,14 @@ TEST_F(ERM_BU_G, Get) | ||||
|  | ||||
| TEST_F(ERM_BU_G, Get2) | ||||
| { | ||||
| 	const int EXPECTED_ERM_FOG_CODE = 4; | ||||
|  | ||||
| 	std::stringstream source; | ||||
| 	source << "VERM" << std::endl; | ||||
| 	source << "!?PI;" << std::endl; | ||||
| 	source << "!!BU:G?v1;" << std::endl; | ||||
|  | ||||
| 	EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("evil_fog"))); | ||||
| 	EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField::fromString("evil_fog"))); | ||||
|  | ||||
| 	loadScript(VLC->scriptHandler->erm, source.str()); | ||||
| 	runServer(); | ||||
| @@ -182,7 +184,7 @@ TEST_F(ERM_BU_G, Get2) | ||||
| 	JsonNode actualState = context->saveState(); | ||||
|  | ||||
|  | ||||
| 	EXPECT_EQ(actualState["ERM"]["v"]["1"], JsonUtils::floatNode(4)) << actualState.toJson(true); | ||||
| 	EXPECT_EQ(actualState["ERM"]["v"]["1"], JsonUtils::floatNode(EXPECTED_ERM_FOG_CODE)) << actualState.toJson(true); | ||||
| } | ||||
|  | ||||
| //TODO: ERM_BU_G Set | ||||
|   | ||||
| @@ -194,7 +194,7 @@ public: | ||||
| 		const auto t = gameCallback->getTile(tile); | ||||
|  | ||||
| 		Terrain terrain = t->terType; | ||||
| 		BattleField terType = BattleField("grass_hills"); | ||||
| 		BattleField terType = BattleField::fromString("grass_hills"); | ||||
|  | ||||
| 		//send info about battles | ||||
|  | ||||
|   | ||||
| @@ -132,7 +132,7 @@ TEST(MapManager, DrawTerrain_View) | ||||
| 			const auto & id = patternParts[1]; | ||||
|  | ||||
| 			// Get mapping range | ||||
| 			const auto & pattern = VLC->terviewh->getTerrainViewPatternById(groupStr, id); | ||||
| 			const auto & pattern = VLC->terviewh->getTerrainViewPatternById(groupStr, id);  | ||||
| 			const auto & mapping = (*pattern).mapping; | ||||
|  | ||||
| 			const auto & positionsNode = node["pos"].Vector(); | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
|  | ||||
| #include "MapComparer.h" | ||||
| #include "../JsonComparer.h" | ||||
| #include "mock/ZoneOptionsFake.h" | ||||
|  | ||||
| static const int TEST_RANDOM_SEED = 1337; | ||||
|  | ||||
| @@ -43,10 +44,12 @@ TEST(MapFormat, Random) | ||||
|  | ||||
| 	CMapGenOptions opt; | ||||
| 	CRmgTemplate tmpl; | ||||
| 	std::shared_ptr<ZoneOptionsFake> zoneOptions = std::make_shared<ZoneOptionsFake>(); | ||||
|  | ||||
| 	const_cast<CRmgTemplate::CPlayerCountRange &>(tmpl.getCpuPlayers()).addRange(1, 4); | ||||
| 	const_cast<CRmgTemplate::Zones &>(tmpl.getZones())[0] = std::make_shared<rmg::ZoneOptions>(); | ||||
| 	const_cast<CRmgTemplate::Zones &>(tmpl.getZones())[0] = zoneOptions; | ||||
|  | ||||
| 	zoneOptions->setOwner(1); | ||||
| 	opt.setMapTemplate(&tmpl); | ||||
|  | ||||
| 	opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE); | ||||
|   | ||||
| @@ -92,7 +92,7 @@ void BattleFake::setupEmptyBattlefield() | ||||
| { | ||||
| 	EXPECT_CALL(*this, getDefendedTown()).WillRepeatedly(Return(nullptr)); | ||||
| 	EXPECT_CALL(*this, getAllObstacles()).WillRepeatedly(Return(IBattleInfo::ObstacleCList())); | ||||
| 	EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BattleField::NONE)); | ||||
| 	EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BattleField::fromString("grass_hills"))); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										23
									
								
								test/mock/ZoneOptionsFake.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								test/mock/ZoneOptionsFake.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* | ||||
|  * BattleFake.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 | ||||
|  * | ||||
|  */ | ||||
| #include "../../../lib/mapping/CMap.h" | ||||
| #include "../../../lib/rmg/CMapGenOptions.h" | ||||
| #include "../../../lib/rmg/CMapGenerator.h" | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| class ZoneOptionsFake : public rmg::ZoneOptions | ||||
| { | ||||
| public: | ||||
| 	void setOwner(int ow) | ||||
| 	{ | ||||
| 		this->owner = ow; | ||||
| 	} | ||||
| }; | ||||
| @@ -23,7 +23,8 @@ public: | ||||
| 	MOCK_CONST_METHOD0(heroTypes, const HeroTypeService *()); | ||||
| 	MOCK_CONST_METHOD0(scripts, const scripting::Service *()); | ||||
| 	MOCK_CONST_METHOD0(spells, const spells::Service *()); | ||||
| 	MOCK_CONST_METHOD0(skills, const SkillService *()); | ||||
| 	MOCK_CONST_METHOD0(skills, const SkillService * ()); | ||||
| 	MOCK_CONST_METHOD0(battlefields, const BattleFieldService *()); | ||||
|  | ||||
| 	MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &)); | ||||
|  | ||||
|   | ||||
| @@ -232,7 +232,7 @@ TEST_F(CloneApplyTest, SetsLifetimeMarker) | ||||
| { | ||||
| 	setDefaultExpectations(); | ||||
|  | ||||
| 	EXPECT_CALL(*battleFake, addUnitBonus(_,_)).WillOnce(Invoke(this, &CloneApplyTest::checkCloneLifetimeMarker)); | ||||
| 	EXPECT_CALL(*battleFake, addUnitBonus(_, _)).WillOnce(Invoke(this, &CloneApplyTest::checkCloneLifetimeMarker)); | ||||
|  | ||||
| 	subject->apply(&serverMock, &mechanicsMock, target); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user