mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Implemented basic loading from JSON
This commit is contained in:
		| @@ -16,6 +16,7 @@ | |||||||
| class CBinaryReader; | class CBinaryReader; | ||||||
| class CLegacyConfigParser; | class CLegacyConfigParser; | ||||||
| class JsonNode; | class JsonNode; | ||||||
|  | class CRandomGenerator; | ||||||
|  |  | ||||||
| class DLL_LINKAGE ObjectTemplate | class DLL_LINKAGE ObjectTemplate | ||||||
| { | { | ||||||
| @@ -128,7 +129,7 @@ public: | |||||||
|  |  | ||||||
| 	virtual CGObjectInstance * create(ObjectTemplate tmpl) const = 0; | 	virtual CGObjectInstance * create(ObjectTemplate tmpl) const = 0; | ||||||
|  |  | ||||||
| 	virtual void configureObject(CGObjectInstance * object) const = 0; | 	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0; | ||||||
|  |  | ||||||
| 	virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const = 0; | 	virtual const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const = 0; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -120,6 +120,19 @@ void CIdentifierStorage::tryRequestIdentifier(std::string type, const JsonNode & | |||||||
| 	requestIdentifier(ObjectCallback(name.meta, pair.first, type, pair.second, callback, true)); | 	requestIdentifier(ObjectCallback(name.meta, pair.first, type, pair.second, callback, true)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | boost::optional<si32> CIdentifierStorage::getIdentifier(std::string scope, std::string type, std::string name, bool silent) | ||||||
|  | { | ||||||
|  | 	auto pair = splitString(name, ':'); // remoteScope:name | ||||||
|  | 	auto idList = getPossibleIdentifiers(ObjectCallback(scope, pair.first, type, pair.second, std::function<void(si32)>(), silent)); | ||||||
|  |  | ||||||
|  | 	if (idList.size() == 1) | ||||||
|  | 		return idList.front().id; | ||||||
|  | 	if (!silent) | ||||||
|  | 		logGlobal->errorStream() << "Failed to resolve identifier " << name << " from mod " << scope; | ||||||
|  |  | ||||||
|  | 	return boost::optional<si32>(); | ||||||
|  | } | ||||||
|  |  | ||||||
| boost::optional<si32> CIdentifierStorage::getIdentifier(std::string type, const JsonNode & name, bool silent) | boost::optional<si32> CIdentifierStorage::getIdentifier(std::string type, const JsonNode & name, bool silent) | ||||||
| { | { | ||||||
| 	auto pair = splitString(name.String(), ':'); // remoteScope:name | 	auto pair = splitString(name.String(), ':'); // remoteScope:name | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ public: | |||||||
| 	void tryRequestIdentifier(std::string type, const JsonNode & name, const std::function<void(si32)> & callback); | 	void tryRequestIdentifier(std::string type, const JsonNode & name, const std::function<void(si32)> & callback); | ||||||
|  |  | ||||||
| 	/// get identifier immediately. If identifier is not know and not silent call will result in error message | 	/// get identifier immediately. If identifier is not know and not silent call will result in error message | ||||||
|  | 	boost::optional<si32> getIdentifier(std::string scope, std::string type, std::string name, bool silent = false); | ||||||
| 	boost::optional<si32> getIdentifier(std::string type, const JsonNode & name, bool silent = false); | 	boost::optional<si32> getIdentifier(std::string type, const JsonNode & name, bool silent = false); | ||||||
| 	boost::optional<si32> getIdentifier(const JsonNode & name, bool silent = false); | 	boost::optional<si32> getIdentifier(const JsonNode & name, bool silent = false); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,10 @@ | |||||||
| #include "StdInc.h" | #include "StdInc.h" | ||||||
| #include "CObjectConstructor.h" | #include "CObjectConstructor.h" | ||||||
|  |  | ||||||
|  | #include "CRandomGenerator.h" | ||||||
|  | #include "StringConstants.h" | ||||||
|  | #include "CCreatureHandler.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * CObjectConstructor.cpp, part of VCMI engine |  * CObjectConstructor.cpp, part of VCMI engine | ||||||
|  * |  * | ||||||
| @@ -11,54 +15,224 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  | 	si32 loadValue(const JsonNode & value, CRandomGenerator & rng, si32 defaultValue = 0) | ||||||
|  | 	{ | ||||||
|  | 		if (value.isNull()) | ||||||
|  | 			return defaultValue; | ||||||
|  | 		if (value.getType() == JsonNode::DATA_FLOAT) | ||||||
|  | 			return value.Float(); | ||||||
|  | 		si32 min = value["min"].Float(); | ||||||
|  | 		si32 max = value["max"].Float(); | ||||||
|  | 		return rng.getIntRange(min, max)(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	TResources loadResources(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		TResources ret; | ||||||
|  | 		for (size_t i=0; i<GameConstants::RESOURCE_QUANTITY; i++) | ||||||
|  | 		{ | ||||||
|  | 			ret[i] = loadValue(value[GameConstants::RESOURCE_NAMES[i]], rng); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<si32> loadPrimary(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<si32> ret; | ||||||
|  | 		for (auto & name : PrimarySkill::names) | ||||||
|  | 		{ | ||||||
|  | 			ret.push_back(loadValue(value[name], rng)); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::map<SecondarySkill, si32> loadSecondary(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		std::map<SecondarySkill, si32> ret; | ||||||
|  | 		for (auto & pair : value.Struct()) | ||||||
|  | 		{ | ||||||
|  | 			SecondarySkill id(VLC->modh->identifiers.getIdentifier(pair.second.meta, "skill", pair.first).get()); | ||||||
|  | 			ret[id] = loadValue(pair.second, rng); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<ArtifactID> loadArtifacts(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<ArtifactID> ret; | ||||||
|  | 		for (const JsonNode & entry : value.Vector()) | ||||||
|  | 		{ | ||||||
|  | 			ArtifactID art(VLC->modh->identifiers.getIdentifier("artifact", entry).get()); | ||||||
|  | 			ret.push_back(art); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<SpellID> loadSpells(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<SpellID> ret; | ||||||
|  | 		for (const JsonNode & entry : value.Vector()) | ||||||
|  | 		{ | ||||||
|  | 			SpellID spell(VLC->modh->identifiers.getIdentifier("spell", entry).get()); | ||||||
|  | 			ret.push_back(spell); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<CStackBasicDescriptor> ret; | ||||||
|  | 		for (auto & pair : value.Struct()) | ||||||
|  | 		{ | ||||||
|  | 			CStackBasicDescriptor stack; | ||||||
|  | 			stack.type = VLC->creh->creatures[VLC->modh->identifiers.getIdentifier(pair.second.meta, "creature", pair.first).get()]; | ||||||
|  | 			stack.count = loadValue(pair.second, rng); | ||||||
|  | 			ret.push_back(stack); | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<Bonus> loadBonuses(const JsonNode & value) | ||||||
|  | 	{ | ||||||
|  | 		std::vector<Bonus> ret; | ||||||
|  | 		for (const JsonNode & entry : value.Vector()) | ||||||
|  | 		{ | ||||||
|  | 			Bonus * bonus = JsonUtils::parseBonus(entry); | ||||||
|  | 			ret.push_back(*bonus); | ||||||
|  | 			delete bonus; | ||||||
|  | 		} | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::vector<Component> loadComponents(const JsonNode & value) | ||||||
|  | 	{ | ||||||
|  | 		//TODO | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	MetaString loadMessage(const JsonNode & value) | ||||||
|  | 	{ | ||||||
|  | 		MetaString ret; | ||||||
|  | 		if (value.getType() == JsonNode::DATA_FLOAT) | ||||||
|  | 			ret.addTxt(MetaString::ADVOB_TXT, value.Float()); | ||||||
|  | 		else | ||||||
|  | 			ret << value.String(); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool testForKey(const JsonNode & value, const std::string & key) | ||||||
|  | 	{ | ||||||
|  | 		for( auto & reward : value["rewards"].Vector() ) | ||||||
|  | 		{ | ||||||
|  | 			if (!reward[key].isNull()) | ||||||
|  | 				return true; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| void CRandomRewardObjectInfo::init(const JsonNode & objectConfig) | void CRandomRewardObjectInfo::init(const JsonNode & objectConfig) | ||||||
| { | { | ||||||
| 	parameters = objectConfig; | 	parameters = objectConfig; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CRandomRewardObjectInfo::configureObject(CObjectWithReward * object) const | void CRandomRewardObjectInfo::configureObject(CObjectWithReward * object, CRandomGenerator & rng) const | ||||||
| { | { | ||||||
|  | 	for (const JsonNode & reward : parameters["rewards"].Vector()) | ||||||
|  | 	{ | ||||||
|  | 		const JsonNode & limiter = reward["limiter"]; | ||||||
|  | 		CVisitInfo info; | ||||||
|  | 		// load limiter | ||||||
|  | 		info.limiter.numOfGrants = loadValue(limiter["numOfGrants"], rng); | ||||||
|  | 		info.limiter.dayOfWeek = loadValue(limiter["dayOfWeek"], rng); | ||||||
|  | 		info.limiter.minLevel = loadValue(limiter["minLevel"], rng); | ||||||
|  | 		info.limiter.resources = loadResources(limiter["resources"], rng); | ||||||
|  |  | ||||||
|  | 		info.limiter.primary = loadPrimary(limiter["primary"], rng); | ||||||
|  | 		info.limiter.secondary = loadSecondary(limiter["secondary"], rng); | ||||||
|  | 		info.limiter.artifacts = loadArtifacts(limiter["artifacts"], rng); | ||||||
|  | 		info.limiter.creatures = loadCreatures(limiter["creatures"], rng); | ||||||
|  |  | ||||||
|  | 		info.reward.resources = loadResources(reward["resources"], rng); | ||||||
|  |  | ||||||
|  | 		info.reward.gainedExp = loadValue(reward["gainedExp"], rng); | ||||||
|  | 		info.reward.gainedLevels = loadValue(reward["gainedLevels"], rng); | ||||||
|  |  | ||||||
|  | 		info.reward.manaDiff = loadValue(reward["manaPoints"], rng); | ||||||
|  | 		info.reward.manaPercentage = loadValue(reward["manaPercentage"], rng, -1); | ||||||
|  |  | ||||||
|  | 		info.reward.movePoints = loadValue(reward["movePoints"], rng); | ||||||
|  | 		info.reward.movePercentage = loadValue(reward["movePercentage"], rng, -1); | ||||||
|  |  | ||||||
|  | 		info.reward.bonuses = loadBonuses(reward["bonuses"]); | ||||||
|  |  | ||||||
|  | 		info.reward.primary = loadPrimary(reward["primary"], rng); | ||||||
|  | 		info.reward.secondary = loadSecondary(reward["secondary"], rng); | ||||||
|  |  | ||||||
|  | 		info.reward.artifacts = loadArtifacts(reward["artifacts"], rng); | ||||||
|  | 		info.reward.spells = loadSpells(reward["spells"], rng); | ||||||
|  | 		info.reward.creatures = loadCreatures(reward["creatures"], rng); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	object->onSelect  = loadMessage(parameters["onSelectMessage"]); | ||||||
|  | 	object->onVisited = loadMessage(parameters["onVisitedMessage"]); | ||||||
|  | 	object->onEmpty   = loadMessage(parameters["onEmptyMessage"]); | ||||||
|  |  | ||||||
|  | 	//TODO: visitMode and selectMode | ||||||
|  |  | ||||||
|  | 	object->soundID = parameters["soundID"].Float(); | ||||||
|  | 	object->resetDuration = parameters["resetDuration"].Float(); | ||||||
|  | 	object->canRefuse =parameters["canRefuse"].Bool(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesResources() const | bool CRandomRewardObjectInfo::givesResources() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "resources"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesExperience() const | bool CRandomRewardObjectInfo::givesExperience() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "gainedExp") || testForKey(parameters, "gainedLevels"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesMana() const | bool CRandomRewardObjectInfo::givesMana() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "manaPoints") || testForKey(parameters, "manaPercentage"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesMovement() const | bool CRandomRewardObjectInfo::givesMovement() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "movePoints") || testForKey(parameters, "movePercentage"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesPrimarySkills() const | bool CRandomRewardObjectInfo::givesPrimarySkills() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "primary"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesSecondarySkills() const | bool CRandomRewardObjectInfo::givesSecondarySkills() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "secondary"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesArtifacts() const | bool CRandomRewardObjectInfo::givesArtifacts() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "artifacts"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesCreatures() const | bool CRandomRewardObjectInfo::givesCreatures() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "spells"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesSpells() const | bool CRandomRewardObjectInfo::givesSpells() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "creatures"); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CRandomRewardObjectInfo::givesBonuses() const | bool CRandomRewardObjectInfo::givesBonuses() const | ||||||
| { | { | ||||||
|  | 	return testForKey(parameters, "bonuses"); | ||||||
| } | } | ||||||
|  |  | ||||||
| CObjectWithRewardConstructor::CObjectWithRewardConstructor() | CObjectWithRewardConstructor::CObjectWithRewardConstructor() | ||||||
| @@ -77,9 +251,9 @@ CGObjectInstance * CObjectWithRewardConstructor::create(ObjectTemplate tmpl) con | |||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CObjectWithRewardConstructor::configureObject(CGObjectInstance * object) const | void CObjectWithRewardConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const | ||||||
| { | { | ||||||
| 	objectInfo.configureObject(dynamic_cast<CObjectWithReward*>(object)); | 	objectInfo.configureObject(dynamic_cast<CObjectWithReward*>(object), rng); | ||||||
| } | } | ||||||
|  |  | ||||||
| const IObjectInfo * CObjectWithRewardConstructor::getObjectInfo(ObjectTemplate tmpl) const | const IObjectInfo * CObjectWithRewardConstructor::getObjectInfo(ObjectTemplate tmpl) const | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ public: | |||||||
|  |  | ||||||
| 	bool givesBonuses() const override; | 	bool givesBonuses() const override; | ||||||
|  |  | ||||||
| 	void configureObject(CObjectWithReward * object) const; | 	void configureObject(CObjectWithReward * object, CRandomGenerator & rng) const; | ||||||
|  |  | ||||||
| 	CRandomRewardObjectInfo() | 	CRandomRewardObjectInfo() | ||||||
| 	{} | 	{} | ||||||
| @@ -51,7 +51,7 @@ public: | |||||||
|  |  | ||||||
| 	CGObjectInstance * create(ObjectTemplate tmpl) const override; | 	CGObjectInstance * create(ObjectTemplate tmpl) const override; | ||||||
|  |  | ||||||
| 	void configureObject(CGObjectInstance * object) const override; | 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override; | ||||||
|  |  | ||||||
| 	const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const override; | 	const IObjectInfo * getObjectInfo(ObjectTemplate tmpl) const override; | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user