mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Partially split CommonConstructors.cpp into few separate files
This commit is contained in:
		| @@ -15,7 +15,7 @@ | ||||
|  | ||||
| #include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h" | ||||
| #include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h" | ||||
| #include "../../../lib/mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h" | ||||
|  | ||||
| namespace NKAI | ||||
| { | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| #include "Nullkiller.h" | ||||
| #include "../../../lib/mapObjectConstructors/AObjectTypeHandler.h" | ||||
| #include "../../../lib/mapObjectConstructors/CObjectClassesHandler.h" | ||||
| #include "../../../lib/mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h" | ||||
| #include "../../../lib/mapObjects/MapObjects.h" | ||||
| #include "../../../lib/CCreatureHandler.h" | ||||
| #include "../../../lib/CPathfinder.h" | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|  | ||||
| #include "../../lib/mapObjectConstructors/AObjectTypeHandler.h" | ||||
| #include "../../lib/mapObjectConstructors/CObjectClassesHandler.h" | ||||
| #include "../../lib/mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../../lib/mapObjectConstructors/CBankInstanceConstructor.h" | ||||
| #include "../../lib/mapObjects/CBank.h" | ||||
| #include "../../lib/mapObjects/CGDwelling.h" | ||||
|  | ||||
|   | ||||
| @@ -66,6 +66,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) | ||||
| 		${MAIN_LIB_DIR}/logging/CLogger.cpp | ||||
|  | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/AObjectTypeHandler.cpp | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CBankInstanceConstructor.cpp | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.cpp | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.cpp | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.cpp | ||||
| @@ -369,6 +370,8 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) | ||||
| 		${MAIN_LIB_DIR}/logging/CLogger.h | ||||
|  | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/AObjectTypeHandler.h | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CBankInstanceConstructor.h | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CDefaultObjectTypeHandler.h | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CObjectClassesHandler.h | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CommonConstructors.h | ||||
| 		${MAIN_LIB_DIR}/mapObjectConstructors/CRewardableConstructor.h | ||||
|   | ||||
							
								
								
									
										255
									
								
								lib/mapObjectConstructors/CBankInstanceConstructor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								lib/mapObjectConstructors/CBankInstanceConstructor.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,255 @@ | ||||
| /* | ||||
| * CBankInstanceConstructor.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 "CBankInstanceConstructor.h" | ||||
|  | ||||
| #include "../JsonRandom.h" | ||||
| #include "../CGeneralTextHandler.h" | ||||
| #include "../IGameCallback.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| bool CBankInstanceConstructor::hasNameTextID() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void CBankInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| { | ||||
| 	if (input.Struct().count("name") == 0) | ||||
| 		logMod->warn("Bank %s missing name!", getJsonKey()); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(input.meta, getNameTextID(), input["name"].String()); | ||||
|  | ||||
| 	levels = input["levels"].Vector(); | ||||
| 	bankResetDuration = static_cast<si32>(input["resetDuration"].Float()); | ||||
| } | ||||
|  | ||||
| CGObjectInstance *CBankInstanceConstructor::create(std::shared_ptr<const ObjectTemplate> tmpl) const | ||||
| { | ||||
| 	return createTyped(tmpl); | ||||
| } | ||||
|  | ||||
| BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRandomGenerator & rng) const | ||||
| { | ||||
| 	BankConfig bc; | ||||
|  | ||||
| 	bc.chance = static_cast<ui32>(level["chance"].Float()); | ||||
|  | ||||
| 	bc.guards = JsonRandom::loadCreatures(level["guards"], rng); | ||||
| 	bc.upgradeChance = static_cast<ui32>(level["upgrade_chance"].Float()); | ||||
| 	bc.combatValue = static_cast<ui32>(level["combat_value"].Float()); | ||||
|  | ||||
| 	std::vector<SpellID> spells; | ||||
| 	IObjectInterface::cb->getAllowedSpells(spells); | ||||
|  | ||||
| 	bc.resources = ResourceSet(level["reward"]["resources"]); | ||||
| 	bc.creatures = JsonRandom::loadCreatures(level["reward"]["creatures"], rng); | ||||
| 	bc.artifacts = JsonRandom::loadArtifacts(level["reward"]["artifacts"], rng); | ||||
| 	bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, spells); | ||||
|  | ||||
| 	bc.value = static_cast<ui32>(level["value"].Float()); | ||||
|  | ||||
| 	return bc; | ||||
| } | ||||
|  | ||||
| void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const | ||||
| { | ||||
| 	auto * bank = dynamic_cast<CBank *>(object); | ||||
|  | ||||
| 	bank->resetDuration = bankResetDuration; | ||||
|  | ||||
| 	si32 totalChance = 0; | ||||
| 	for(const auto & node : levels) | ||||
| 		totalChance += static_cast<si32>(node["chance"].Float()); | ||||
|  | ||||
| 	assert(totalChance != 0); | ||||
|  | ||||
| 	si32 selectedChance = rng.nextInt(totalChance - 1); | ||||
|  | ||||
| 	int cumulativeChance = 0; | ||||
| 	for(const auto & node : levels) | ||||
| 	{ | ||||
| 		cumulativeChance += static_cast<int>(node["chance"].Float()); | ||||
| 		if(selectedChance < cumulativeChance) | ||||
| 		{ | ||||
| 			bank->setConfig(generateConfig(node, rng)); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CBankInfo::CBankInfo(const JsonVector & Config) : | ||||
| 	config(Config) | ||||
| { | ||||
| 	assert(!Config.empty()); | ||||
| } | ||||
|  | ||||
| static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount) | ||||
| { | ||||
| 	army.totalStrength += crea->getFightValue() * amount; | ||||
|  | ||||
| 	bool walker = true; | ||||
| 	if(crea->hasBonusOfType(BonusType::SHOOTER)) | ||||
| 	{ | ||||
| 		army.shootersStrength += crea->getFightValue() * amount; | ||||
| 		walker = false; | ||||
| 	} | ||||
| 	if(crea->hasBonusOfType(BonusType::FLYING)) | ||||
| 	{ | ||||
| 		army.flyersStrength += crea->getFightValue() * amount; | ||||
| 		walker = false; | ||||
| 	} | ||||
| 	if(walker) | ||||
| 		army.walkersStrength += crea->getFightValue() * amount; | ||||
| } | ||||
|  | ||||
| IObjectInfo::CArmyStructure CBankInfo::minGuards() const | ||||
| { | ||||
| 	std::vector<IObjectInfo::CArmyStructure> armies; | ||||
| 	for(auto configEntry : config) | ||||
| 	{ | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
| 		for(auto & stack : stacks) | ||||
| 		{ | ||||
| 			assert(!stack.allowedCreatures.empty()); | ||||
| 			auto weakest = boost::range::min_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) | ||||
| 			{ | ||||
| 				return a->getFightValue() < b->getFightValue(); | ||||
| 			}); | ||||
| 			addStackToArmy(army, *weakest, stack.minAmount); | ||||
| 		} | ||||
| 		armies.push_back(army); | ||||
| 	} | ||||
| 	return *boost::range::min_element(armies); | ||||
| } | ||||
|  | ||||
| IObjectInfo::CArmyStructure CBankInfo::maxGuards() const | ||||
| { | ||||
| 	std::vector<IObjectInfo::CArmyStructure> armies; | ||||
| 	for(auto configEntry : config) | ||||
| 	{ | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
| 		for(auto & stack : stacks) | ||||
| 		{ | ||||
| 			assert(!stack.allowedCreatures.empty()); | ||||
| 			auto strongest = boost::range::max_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) | ||||
| 			{ | ||||
| 				return a->getFightValue() < b->getFightValue(); | ||||
| 			}); | ||||
| 			addStackToArmy(army, *strongest, stack.maxAmount); | ||||
| 		} | ||||
| 		armies.push_back(army); | ||||
| 	} | ||||
| 	return *boost::range::max_element(armies); | ||||
| } | ||||
|  | ||||
| TPossibleGuards CBankInfo::getPossibleGuards() const | ||||
| { | ||||
| 	TPossibleGuards out; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & guardsInfo = configEntry["guards"]; | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(guardsInfo); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
|  | ||||
|  | ||||
| 		for(auto stack : stacks) | ||||
| 		{ | ||||
| 			army.totalStrength += stack.allowedCreatures.front()->getAIValue() * (stack.minAmount + stack.maxAmount) / 2; | ||||
| 			//TODO: add fields for flyers, walkers etc... | ||||
| 		} | ||||
|  | ||||
| 		ui8 chance = static_cast<ui8>(configEntry["chance"].Float()); | ||||
| 		out.push_back(std::make_pair(chance, army)); | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| std::vector<PossibleReward<TResources>> CBankInfo::getPossibleResourcesReward() const | ||||
| { | ||||
| 	std::vector<PossibleReward<TResources>> result; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & resourcesInfo = configEntry["reward"]["resources"]; | ||||
|  | ||||
| 		if(!resourcesInfo.isNull()) | ||||
| 		{ | ||||
| 			result.emplace_back(configEntry["chance"].Integer(), TResources(resourcesInfo)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::vector<PossibleReward<CStackBasicDescriptor>> CBankInfo::getPossibleCreaturesReward() const | ||||
| { | ||||
| 	std::vector<PossibleReward<CStackBasicDescriptor>> aproximateReward; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & guardsInfo = configEntry["reward"]["creatures"]; | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(guardsInfo); | ||||
|  | ||||
| 		for(auto stack : stacks) | ||||
| 		{ | ||||
| 			const auto * creature = stack.allowedCreatures.front(); | ||||
|  | ||||
| 			aproximateReward.emplace_back(configEntry["chance"].Integer(), CStackBasicDescriptor(creature, (stack.minAmount + stack.maxAmount) / 2)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return aproximateReward; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesResources() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["resources"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesArtifacts() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["artifacts"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesCreatures() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["creatures"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesSpells() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["spells"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| std::unique_ptr<IObjectInfo> CBankInstanceConstructor::getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const | ||||
| { | ||||
| 	return std::unique_ptr<IObjectInfo>(new CBankInfo(levels)); | ||||
| } | ||||
|  | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
							
								
								
									
										105
									
								
								lib/mapObjectConstructors/CBankInstanceConstructor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								lib/mapObjectConstructors/CBankInstanceConstructor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| /* | ||||
| * CBankInstanceConstructor.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 "CDefaultObjectTypeHandler.h" | ||||
| #include "IObjectInfo.h" | ||||
|  | ||||
| #include "../CCreatureSet.h" | ||||
| #include "../ResourceSet.h" | ||||
| #include "../mapObjects/CBank.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| struct BankConfig | ||||
| { | ||||
| 	ui32 value = 0; //overall value of given things | ||||
| 	ui32 chance = 0; //chance for this level being chosen | ||||
| 	ui32 upgradeChance = 0; //chance for creatures to be in upgraded versions | ||||
| 	ui32 combatValue = 0; //how hard are guards of this level | ||||
| 	std::vector<CStackBasicDescriptor> guards; //creature ID, amount | ||||
| 	ResourceSet resources; //resources given in case of victory | ||||
| 	std::vector<CStackBasicDescriptor> creatures; //creatures granted in case of victory (creature ID, amount) | ||||
| 	std::vector<ArtifactID> artifacts; //artifacts given in case of victory | ||||
| 	std::vector<SpellID> spells; // granted spell(s), for Pyramid | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & chance; | ||||
| 		h & upgradeChance; | ||||
| 		h & guards; | ||||
| 		h & combatValue; | ||||
| 		h & resources; | ||||
| 		h & creatures; | ||||
| 		h & artifacts; | ||||
| 		h & value; | ||||
| 		h & spells; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| using TPossibleGuards = std::vector<std::pair<ui8, IObjectInfo::CArmyStructure>>; | ||||
|  | ||||
| template <typename T> | ||||
| struct DLL_LINKAGE PossibleReward | ||||
| { | ||||
| 	int chance; | ||||
| 	T data; | ||||
|  | ||||
| 	PossibleReward(int chance, const T & data) : chance(chance), data(data) {} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CBankInfo : public IObjectInfo | ||||
| { | ||||
| 	const JsonVector & config; | ||||
| public: | ||||
| 	CBankInfo(const JsonVector & Config); | ||||
|  | ||||
| 	TPossibleGuards getPossibleGuards() const; | ||||
| 	std::vector<PossibleReward<TResources>> getPossibleResourcesReward() const; | ||||
| 	std::vector<PossibleReward<CStackBasicDescriptor>> getPossibleCreaturesReward() const; | ||||
|  | ||||
| 	// These functions should try to evaluate minimal possible/max possible guards to give provide information on possible thread to AI | ||||
| 	CArmyStructure minGuards() const override; | ||||
| 	CArmyStructure maxGuards() const override; | ||||
|  | ||||
| 	bool givesResources() const override; | ||||
| 	bool givesArtifacts() const override; | ||||
| 	bool givesCreatures() const override; | ||||
| 	bool givesSpells() const override; | ||||
| }; | ||||
|  | ||||
| class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank> | ||||
| { | ||||
| 	BankConfig generateConfig(const JsonNode & conf, CRandomGenerator & rng) const; | ||||
|  | ||||
| 	JsonVector levels; | ||||
| protected: | ||||
| 	void initTypeData(const JsonNode & input) override; | ||||
|  | ||||
| public: | ||||
| 	// all banks of this type will be reset N days after clearing, | ||||
| 	si32 bankResetDuration = 0; | ||||
|  | ||||
| 	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override; | ||||
| 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override; | ||||
|  | ||||
| 	bool hasNameTextID() const override; | ||||
|  | ||||
| 	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & levels; | ||||
| 		h & bankResetDuration; | ||||
| 		h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
							
								
								
									
										52
									
								
								lib/mapObjectConstructors/CDefaultObjectTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								lib/mapObjectConstructors/CDefaultObjectTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
| * CDefaultObjectTypeHandler.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 "AObjectTypeHandler.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| /// Class that is used for objects that do not have dedicated handler | ||||
| template<class ObjectType> | ||||
| class CDefaultObjectTypeHandler : public AObjectTypeHandler | ||||
| { | ||||
| protected: | ||||
| 	ObjectType * createTyped(std::shared_ptr<const ObjectTemplate> tmpl /* = nullptr */) const | ||||
| 	{ | ||||
| 		auto obj = new ObjectType(); | ||||
| 		preInitObject(obj); | ||||
|  | ||||
| 		//Set custom template or leave null | ||||
| 		if (tmpl) | ||||
| 		{ | ||||
| 			obj->appearance = tmpl; | ||||
| 		} | ||||
|  | ||||
| 		return obj; | ||||
| 	} | ||||
| public: | ||||
| 	CDefaultObjectTypeHandler() {} | ||||
|  | ||||
| 	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override | ||||
| 	{ | ||||
| 		return createTyped(tmpl); | ||||
| 	} | ||||
|  | ||||
| 	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
| @@ -23,6 +23,7 @@ | ||||
|  | ||||
| #include "../mapObjectConstructors/CRewardableConstructor.h" | ||||
| #include "../mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../mapObjectConstructors/CBankInstanceConstructor.h" | ||||
| #include "../mapObjects/CQuest.h" | ||||
| #include "../mapObjects/CGPandoraBox.h" | ||||
| #include "../mapObjects/ObjectTemplate.h" | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
| #include "../mapObjects/CGTownInstance.h" | ||||
| #include "../mapObjects/ObjectTemplate.h" | ||||
| #include "../mapping/CMapDefines.h" | ||||
| #include "JsonRandom.h" | ||||
| #include "../JsonRandom.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| @@ -356,241 +356,4 @@ void MarketInstanceConstructor::configureObject(CGObjectInstance * object, CRand | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| bool CBankInstanceConstructor::hasNameTextID() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void CBankInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| { | ||||
| 	if (input.Struct().count("name") == 0) | ||||
| 		logMod->warn("Bank %s missing name!", getJsonKey()); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(input.meta, getNameTextID(), input["name"].String()); | ||||
|  | ||||
| 	levels = input["levels"].Vector(); | ||||
| 	bankResetDuration = static_cast<si32>(input["resetDuration"].Float()); | ||||
| } | ||||
|  | ||||
| CGObjectInstance *CBankInstanceConstructor::create(std::shared_ptr<const ObjectTemplate> tmpl) const | ||||
| { | ||||
| 	return createTyped(tmpl); | ||||
| } | ||||
|  | ||||
| BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRandomGenerator & rng) const | ||||
| { | ||||
| 	BankConfig bc; | ||||
|  | ||||
| 	bc.chance = static_cast<ui32>(level["chance"].Float()); | ||||
|  | ||||
| 	bc.guards = JsonRandom::loadCreatures(level["guards"], rng); | ||||
| 	bc.upgradeChance = static_cast<ui32>(level["upgrade_chance"].Float()); | ||||
| 	bc.combatValue = static_cast<ui32>(level["combat_value"].Float()); | ||||
|  | ||||
| 	std::vector<SpellID> spells; | ||||
| 	for (size_t i=0; i<6; i++) | ||||
| 		IObjectInterface::cb->getAllowedSpells(spells, static_cast<ui16>(i)); | ||||
|  | ||||
| 	bc.resources = ResourceSet(level["reward"]["resources"]); | ||||
| 	bc.creatures = JsonRandom::loadCreatures(level["reward"]["creatures"], rng); | ||||
| 	bc.artifacts = JsonRandom::loadArtifacts(level["reward"]["artifacts"], rng); | ||||
| 	bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, spells); | ||||
|  | ||||
| 	bc.value = static_cast<ui32>(level["value"].Float()); | ||||
|  | ||||
| 	return bc; | ||||
| } | ||||
|  | ||||
| void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const | ||||
| { | ||||
| 	auto * bank = dynamic_cast<CBank *>(object); | ||||
|  | ||||
| 	bank->resetDuration = bankResetDuration; | ||||
|  | ||||
| 	si32 totalChance = 0; | ||||
| 	for(const auto & node : levels) | ||||
| 		totalChance += static_cast<si32>(node["chance"].Float()); | ||||
|  | ||||
| 	assert(totalChance != 0); | ||||
|  | ||||
| 	si32 selectedChance = rng.nextInt(totalChance - 1); | ||||
|  | ||||
| 	int cumulativeChance = 0; | ||||
| 	for(const auto & node : levels) | ||||
| 	{ | ||||
| 		cumulativeChance += static_cast<int>(node["chance"].Float()); | ||||
| 		if(selectedChance < cumulativeChance) | ||||
| 		{ | ||||
| 			bank->setConfig(generateConfig(node, rng)); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CBankInfo::CBankInfo(const JsonVector & Config) : | ||||
| 	config(Config) | ||||
| { | ||||
| 	assert(!Config.empty()); | ||||
| } | ||||
|  | ||||
| static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount) | ||||
| { | ||||
| 	army.totalStrength += crea->getFightValue() * amount; | ||||
|  | ||||
| 	bool walker = true; | ||||
| 	if(crea->hasBonusOfType(BonusType::SHOOTER)) | ||||
| 	{ | ||||
| 		army.shootersStrength += crea->getFightValue() * amount; | ||||
| 		walker = false; | ||||
| 	} | ||||
| 	if(crea->hasBonusOfType(BonusType::FLYING)) | ||||
| 	{ | ||||
| 		army.flyersStrength += crea->getFightValue() * amount; | ||||
| 		walker = false; | ||||
| 	} | ||||
| 	if(walker) | ||||
| 		army.walkersStrength += crea->getFightValue() * amount; | ||||
| } | ||||
|  | ||||
| IObjectInfo::CArmyStructure CBankInfo::minGuards() const | ||||
| { | ||||
| 	std::vector<IObjectInfo::CArmyStructure> armies; | ||||
| 	for(auto configEntry : config) | ||||
| 	{ | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
| 		for(auto & stack : stacks) | ||||
| 		{ | ||||
| 			assert(!stack.allowedCreatures.empty()); | ||||
| 			auto weakest = boost::range::min_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) | ||||
| 			{ | ||||
| 				return a->getFightValue() < b->getFightValue(); | ||||
| 			}); | ||||
| 			addStackToArmy(army, *weakest, stack.minAmount); | ||||
| 		} | ||||
| 		armies.push_back(army); | ||||
| 	} | ||||
| 	return *boost::range::min_element(armies); | ||||
| } | ||||
|  | ||||
| IObjectInfo::CArmyStructure CBankInfo::maxGuards() const | ||||
| { | ||||
| 	std::vector<IObjectInfo::CArmyStructure> armies; | ||||
| 	for(auto configEntry : config) | ||||
| 	{ | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
| 		for(auto & stack : stacks) | ||||
| 		{ | ||||
| 			assert(!stack.allowedCreatures.empty()); | ||||
| 			auto strongest = boost::range::max_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) | ||||
| 			{ | ||||
| 				return a->getFightValue() < b->getFightValue(); | ||||
| 			}); | ||||
| 			addStackToArmy(army, *strongest, stack.maxAmount); | ||||
| 		} | ||||
| 		armies.push_back(army); | ||||
| 	} | ||||
| 	return *boost::range::max_element(armies); | ||||
| } | ||||
|  | ||||
| TPossibleGuards CBankInfo::getPossibleGuards() const | ||||
| { | ||||
| 	TPossibleGuards out; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & guardsInfo = configEntry["guards"]; | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(guardsInfo); | ||||
| 		IObjectInfo::CArmyStructure army; | ||||
|  | ||||
|  | ||||
| 		for(auto stack : stacks) | ||||
| 		{ | ||||
| 			army.totalStrength += stack.allowedCreatures.front()->getAIValue() * (stack.minAmount + stack.maxAmount) / 2; | ||||
| 			//TODO: add fields for flyers, walkers etc... | ||||
| 		} | ||||
|  | ||||
| 		ui8 chance = static_cast<ui8>(configEntry["chance"].Float()); | ||||
| 		out.push_back(std::make_pair(chance, army)); | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| std::vector<PossibleReward<TResources>> CBankInfo::getPossibleResourcesReward() const | ||||
| { | ||||
| 	std::vector<PossibleReward<TResources>> result; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & resourcesInfo = configEntry["reward"]["resources"]; | ||||
|  | ||||
| 		if(!resourcesInfo.isNull()) | ||||
| 		{ | ||||
| 			result.emplace_back(configEntry["chance"].Integer(), TResources(resourcesInfo)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::vector<PossibleReward<CStackBasicDescriptor>> CBankInfo::getPossibleCreaturesReward() const | ||||
| { | ||||
| 	std::vector<PossibleReward<CStackBasicDescriptor>> aproximateReward; | ||||
|  | ||||
| 	for(const JsonNode & configEntry : config) | ||||
| 	{ | ||||
| 		const JsonNode & guardsInfo = configEntry["reward"]["creatures"]; | ||||
| 		auto stacks = JsonRandom::evaluateCreatures(guardsInfo); | ||||
|  | ||||
| 		for(auto stack : stacks) | ||||
| 		{ | ||||
| 			const auto * creature = stack.allowedCreatures.front(); | ||||
|  | ||||
| 			aproximateReward.emplace_back(configEntry["chance"].Integer(), CStackBasicDescriptor(creature, (stack.minAmount + stack.maxAmount) / 2)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return aproximateReward; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesResources() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["resources"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesArtifacts() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["artifacts"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesCreatures() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["creatures"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool CBankInfo::givesSpells() const | ||||
| { | ||||
| 	for(const JsonNode & node : config) | ||||
| 		if(!node["reward"]["spells"].isNull()) | ||||
| 			return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
|  | ||||
| std::unique_ptr<IObjectInfo> CBankInstanceConstructor::getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const | ||||
| { | ||||
| 	return std::unique_ptr<IObjectInfo>(new CBankInfo(levels)); | ||||
| } | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|   | ||||
| @@ -10,14 +10,13 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "AObjectTypeHandler.h" | ||||
| #include "CDefaultObjectTypeHandler.h" | ||||
|  | ||||
| #include "../mapObjects/CGMarket.h" | ||||
| #include "../mapObjects/MiscObjects.h" | ||||
| #include "../mapObjects/CGHeroInstance.h" | ||||
| #include "../mapObjects/CGTownInstance.h" | ||||
| #include "../mapObjects/CBank.h" | ||||
| #include "../LogicalExpression.h" | ||||
| #include "IObjectInfo.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| @@ -30,42 +29,6 @@ class CBank; | ||||
| class CFaction; | ||||
| class CStackBasicDescriptor; | ||||
|  | ||||
| /// Class that is used for objects that do not have dedicated handler | ||||
| template<class ObjectType> | ||||
| class CDefaultObjectTypeHandler : public AObjectTypeHandler | ||||
| { | ||||
| protected: | ||||
| 	ObjectType * createTyped(std::shared_ptr<const ObjectTemplate> tmpl /* = nullptr */) const | ||||
| 	{ | ||||
| 		auto obj = new ObjectType(); | ||||
| 		preInitObject(obj); | ||||
|  | ||||
| 		//Set custom template or leave null | ||||
| 		if (tmpl) | ||||
| 		{ | ||||
| 			obj->appearance = tmpl; | ||||
| 		} | ||||
|  | ||||
| 		return obj; | ||||
| 	} | ||||
| public: | ||||
| 	CDefaultObjectTypeHandler() {} | ||||
|  | ||||
| 	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override | ||||
| 	{ | ||||
| 		return createTyped(tmpl); | ||||
| 	} | ||||
|  | ||||
| 	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	virtual std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class CObstacleConstructor : public CDefaultObjectTypeHandler<CGObjectInstance> | ||||
| { | ||||
| public: | ||||
| @@ -178,90 +141,6 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| struct BankConfig | ||||
| { | ||||
| 	ui32 value = 0; //overall value of given things | ||||
| 	ui32 chance = 0; //chance for this level being chosen | ||||
| 	ui32 upgradeChance = 0; //chance for creatures to be in upgraded versions | ||||
| 	ui32 combatValue = 0; //how hard are guards of this level | ||||
| 	std::vector<CStackBasicDescriptor> guards; //creature ID, amount | ||||
| 	ResourceSet resources; //resources given in case of victory | ||||
| 	std::vector<CStackBasicDescriptor> creatures; //creatures granted in case of victory (creature ID, amount) | ||||
| 	std::vector<ArtifactID> artifacts; //artifacts given in case of victory | ||||
| 	std::vector<SpellID> spells; // granted spell(s), for Pyramid | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & chance; | ||||
| 		h & upgradeChance; | ||||
| 		h & guards; | ||||
| 		h & combatValue; | ||||
| 		h & resources; | ||||
| 		h & creatures; | ||||
| 		h & artifacts; | ||||
| 		h & value; | ||||
| 		h & spells; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| using TPossibleGuards = std::vector<std::pair<ui8, IObjectInfo::CArmyStructure>>; | ||||
|  | ||||
| template <typename T> | ||||
| struct DLL_LINKAGE PossibleReward | ||||
| { | ||||
| 	int chance; | ||||
| 	T data; | ||||
|  | ||||
| 	PossibleReward(int chance, const T & data) : chance(chance), data(data) {} | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CBankInfo : public IObjectInfo | ||||
| { | ||||
| 	const JsonVector & config; | ||||
| public: | ||||
| 	CBankInfo(const JsonVector & Config); | ||||
|  | ||||
| 	TPossibleGuards getPossibleGuards() const; | ||||
| 	std::vector<PossibleReward<TResources>> getPossibleResourcesReward() const; | ||||
| 	std::vector<PossibleReward<CStackBasicDescriptor>> getPossibleCreaturesReward() const; | ||||
|  | ||||
| 	// These functions should try to evaluate minimal possible/max possible guards to give provide information on possible thread to AI | ||||
| 	CArmyStructure minGuards() const override; | ||||
| 	CArmyStructure maxGuards() const override; | ||||
|  | ||||
| 	bool givesResources() const override; | ||||
| 	bool givesArtifacts() const override; | ||||
| 	bool givesCreatures() const override; | ||||
| 	bool givesSpells() const override; | ||||
| }; | ||||
|  | ||||
| class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank> | ||||
| { | ||||
| 	BankConfig generateConfig(const JsonNode & conf, CRandomGenerator & rng) const; | ||||
|  | ||||
| 	JsonVector levels; | ||||
| protected: | ||||
| 	void initTypeData(const JsonNode & input) override; | ||||
|  | ||||
| public: | ||||
| 	// all banks of this type will be reset N days after clearing, | ||||
| 	si32 bankResetDuration = 0; | ||||
|  | ||||
| 	CGObjectInstance * create(std::shared_ptr<const ObjectTemplate> tmpl = nullptr) const override; | ||||
| 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override; | ||||
|  | ||||
| 	bool hasNameTextID() const override; | ||||
|  | ||||
| 	std::unique_ptr<IObjectInfo> getObjectInfo(std::shared_ptr<const ObjectTemplate> tmpl) const override; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & levels; | ||||
| 		h & bankResetDuration; | ||||
| 		h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class MarketInstanceConstructor : public CDefaultObjectTypeHandler<CGMarket> | ||||
| { | ||||
| protected: | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| #include "../CGeneralTextHandler.h" | ||||
| #include "../CSoundBase.h" | ||||
| #include "../mapObjectConstructors/CObjectClassesHandler.h" | ||||
| #include "../mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../mapObjectConstructors/CBankInstanceConstructor.h" | ||||
| #include "../IGameCallback.h" | ||||
| #include "../CGameState.h" | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
| #include "../CModHandler.h" //needed? | ||||
| #include "../mapObjectConstructors/CRewardableConstructor.h" | ||||
| #include "../mapObjectConstructors/CommonConstructors.h" | ||||
| #include "../mapObjectConstructors/CBankInstanceConstructor.h" | ||||
| #include "../mapObjects/MapObjects.h" | ||||
| #include "../mapObjects/CGTownBuilding.h" | ||||
| #include "../mapObjects/ObjectTemplate.h" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user