mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Advance map header serialization
This commit is contained in:
		| @@ -203,7 +203,7 @@ std::vector<JsonNode> CArtHandler::loadLegacyData(size_t dataSize) | ||||
|  | ||||
| void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->id = ArtifactID(artifacts.size()); | ||||
| 	object->iconIndex = object->id + 5; | ||||
|  | ||||
| @@ -231,12 +231,12 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode | ||||
| 			VLC->objtypeh->removeSubObject(Obj::ARTIFACT, object->id); | ||||
| 	}); | ||||
|  | ||||
| 	registerObject(scope, "artifact", object->identifier, object->id); | ||||
| 	registerObject(scope, "artifact", name, object->id); | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->id = ArtifactID(index); | ||||
| 	object->iconIndex = object->id; | ||||
|  | ||||
| @@ -264,7 +264,7 @@ void CArtHandler::loadObject(std::string scope, std::string name, const JsonNode | ||||
| 		if (VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, object->id)->getTemplates().empty()) | ||||
| 			VLC->objtypeh->removeSubObject(Obj::ARTIFACT, object->id); | ||||
| 	}); | ||||
| 	registerObject(scope, "artifact", object->identifier, object->id); | ||||
| 	registerObject(scope, "artifact", name, object->id); | ||||
| } | ||||
|  | ||||
| CArtifact * CArtHandler::loadFromJson(const JsonNode & node, const std::string & identifier) | ||||
| @@ -674,7 +674,7 @@ std::vector<bool> CArtHandler::getDefaultAllowed() const | ||||
| 	std::vector<bool> allowedArtifacts; | ||||
| 	allowedArtifacts.resize(127, true); | ||||
| 	allowedArtifacts.resize(141, false); | ||||
| 	allowedArtifacts.resize(GameConstants::ARTIFACTS_QUANTITY, true); | ||||
| 	allowedArtifacts.resize(artifacts.size(), true); | ||||
| 	return allowedArtifacts; | ||||
| } | ||||
|  | ||||
| @@ -742,6 +742,20 @@ void CArtHandler::afterLoadFinalization() | ||||
| 	CBonusSystemNode::treeHasChanged(); | ||||
| } | ||||
|  | ||||
| si32 CArtHandler::decodeArfifact(const std::string& identifier) | ||||
| { | ||||
| 	auto rawId = VLC->modh->identifiers.getIdentifier("core", "artifact", identifier); | ||||
| 	if(rawId) | ||||
| 		return rawId.get(); | ||||
| 	else | ||||
| 		return -1; | ||||
| } | ||||
|  | ||||
| std::string CArtHandler::encodeArtifact(const si32 index) | ||||
| { | ||||
| 	return VLC->arth->artifacts[index]->identifier; | ||||
| } | ||||
|  | ||||
| CArtifactInstance::CArtifactInstance() | ||||
| { | ||||
| 	init(); | ||||
|   | ||||
| @@ -255,6 +255,12 @@ public: | ||||
|  | ||||
| 	std::vector<bool> getDefaultAllowed() const override; | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static si32 decodeArfifact(const std::string & identifier); | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static std::string encodeArtifact(const si32 index); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & artifacts & allowedArtifacts & treasures & minors & majors & relics | ||||
|   | ||||
| @@ -368,7 +368,7 @@ std::vector<JsonNode> CCreatureHandler::loadLegacyData(size_t dataSize) | ||||
|  | ||||
| void CCreatureHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->setId(CreatureID(creatures.size())); | ||||
| 	object->iconIndex = object->idNumber + 2; | ||||
|  | ||||
| @@ -402,7 +402,7 @@ void CCreatureHandler::loadObject(std::string scope, std::string name, const Jso | ||||
|  | ||||
| void CCreatureHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->setId(CreatureID(index)); | ||||
| 	object->iconIndex = object->idNumber + 2; | ||||
|  | ||||
|   | ||||
| @@ -192,7 +192,7 @@ std::vector<JsonNode> CHeroClassHandler::loadLegacyData(size_t dataSize) | ||||
|  | ||||
| void CHeroClassHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->id = heroClasses.size(); | ||||
|  | ||||
| 	heroClasses.push_back(object); | ||||
| @@ -205,19 +205,12 @@ void CHeroClassHandler::loadObject(std::string scope, std::string name, const Js | ||||
| 		VLC->objtypeh->loadSubObject(name, classConf, index, object->id); | ||||
| 	}); | ||||
|  | ||||
| //	VLC->modh->identifiers.requestIdentifier(scope, "object", "prison", [=](si32 index) | ||||
| //	{ | ||||
| //		JsonNode conf; | ||||
| //		conf.setMeta(scope); | ||||
| //		VLC->objtypeh->loadSubObject(name, conf, index, object->id); | ||||
| //	}); | ||||
|  | ||||
| 	VLC->modh->identifiers.registerObject(scope, "heroClass", name, object->id); | ||||
| } | ||||
|  | ||||
| void CHeroClassHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->id = index; | ||||
|  | ||||
| 	assert(heroClasses[index] == nullptr); // ensure that this id was not loaded before | ||||
| @@ -547,7 +540,7 @@ std::vector<JsonNode> CHeroHandler::loadLegacyData(size_t dataSize) | ||||
|  | ||||
| void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->ID = HeroTypeID(heroes.size()); | ||||
| 	object->imageIndex = heroes.size() + 30; // 2 special frames + some extra portraits | ||||
|  | ||||
| @@ -558,7 +551,7 @@ void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
|  | ||||
| void CHeroHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->ID = HeroTypeID(index); | ||||
| 	object->imageIndex = index; | ||||
|  | ||||
| @@ -618,3 +611,17 @@ std::vector<bool> CHeroHandler::getDefaultAllowedAbilities() const | ||||
| 	allowedAbilities.resize(GameConstants::SKILL_QUANTITY, true); | ||||
| 	return allowedAbilities; | ||||
| } | ||||
|  | ||||
| si32 CHeroHandler::decodeSkill(const std::string& identifier) | ||||
| { | ||||
| 	auto rawId = VLC->modh->identifiers.getIdentifier("core", "skill", identifier); | ||||
| 	if(rawId) | ||||
| 		return rawId.get(); | ||||
| 	else | ||||
| 		return -1; | ||||
| } | ||||
|  | ||||
| std::string CHeroHandler::encodeSkill(const si32 index) | ||||
| { | ||||
| 	return NSecondarySkill::names[index]; | ||||
| } | ||||
|   | ||||
| @@ -257,6 +257,12 @@ public: | ||||
| 	 */ | ||||
| 	std::vector<bool> getDefaultAllowedAbilities() const; | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static si32 decodeSkill(const std::string & identifier); | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static std::string encodeSkill(const si32 index); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & classes & heroes & expPerLevel & ballistics & terrCosts; | ||||
|   | ||||
| @@ -187,7 +187,6 @@ void CIdentifierStorage::registerObject(std::string scope, std::string type, std | ||||
| 	checkIdentifier(fullID); | ||||
|  | ||||
| 	registeredObjects.insert(std::make_pair(fullID, data)); | ||||
| 	logGlobal->traceStream() << scope << "::" << fullID; | ||||
| } | ||||
|  | ||||
| std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdentifiers(const ObjectCallback & request) | ||||
| @@ -206,10 +205,21 @@ std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdent | ||||
| 	else | ||||
| 	{ | ||||
| 		//...unless destination mod was specified explicitly | ||||
| 		auto myDeps = VLC->modh->getModData(request.localScope).dependencies; | ||||
| 		if (request.remoteScope == "core" ||   // allow only available to all core mod | ||||
| 		    myDeps.count(request.remoteScope)) // or dependencies | ||||
| 		//note: getModData does not work for "core" by design | ||||
|  | ||||
| 		//for map format support core mod has access to any mod | ||||
| 		//TODO: better solution for access from map? | ||||
| 		if(request.localScope == "core" || request.localScope == "") | ||||
| 		{ | ||||
| 			allowedScopes.insert(request.remoteScope); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// allow only available to all core mod or dependencies | ||||
| 			auto myDeps = VLC->modh->getModData(request.localScope).dependencies; | ||||
| 			if (request.remoteScope == "core" || myDeps.count(request.remoteScope)) | ||||
| 				allowedScopes.insert(request.remoteScope); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	std::string fullID = request.type + '.' + request.name; | ||||
| @@ -845,9 +855,16 @@ void CModHandler::loadModFilesystems() | ||||
|  | ||||
| CModInfo & CModHandler::getModData(TModID modId) | ||||
| { | ||||
| 	CModInfo & mod = allMods.at(modId); | ||||
| 	assert(vstd::contains(activeMods, modId)); // not really necessary but won't hurt | ||||
| 	return mod; | ||||
| 	auto it = allMods.find(modId); | ||||
|  | ||||
| 	if(it == allMods.end()) | ||||
| 	{ | ||||
| 		throw std::runtime_error("Mod not found '" + modId+"'"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return it->second; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CModHandler::initializeConfig() | ||||
|   | ||||
| @@ -682,7 +682,7 @@ CFaction * CTownHandler::loadFromJson(const JsonNode &source, const std::string | ||||
|  | ||||
| void CTownHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
|  | ||||
| 	object->index = factions.size(); | ||||
| 	factions.push_back(object); | ||||
| @@ -699,7 +699,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| 		{ | ||||
| 			// register town once objects are loaded | ||||
| 			JsonNode config = data["town"]["mapObject"]; | ||||
| 			config["faction"].String() = object->identifier; | ||||
| 			config["faction"].String() = name; | ||||
| 			config["faction"].meta = scope; | ||||
| 			if (config.meta.empty())// MODS COMPATIBILITY FOR 0.96 | ||||
| 				config.meta = scope; | ||||
| @@ -722,7 +722,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
|  | ||||
| void CTownHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	object->index = index; | ||||
| 	assert(factions[index] == nullptr); // ensure that this id was not loaded before | ||||
| 	factions[index] = object; | ||||
| @@ -739,7 +739,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod | ||||
| 		{ | ||||
| 			// register town once objects are loaded | ||||
| 			JsonNode config = data["town"]["mapObject"]; | ||||
| 			config["faction"].String() = object->identifier; | ||||
| 			config["faction"].String() = name; | ||||
| 			config["faction"].meta = scope; | ||||
| 			VLC->objtypeh->loadSubObject(object->identifier, config, index, object->index); | ||||
| 		}); | ||||
|   | ||||
| @@ -17,3 +17,8 @@ void IHandlerBase::registerObject(std::string scope, std::string type_name, std: | ||||
| { | ||||
| 	return VLC->modh->identifiers.registerObject(scope, type_name, name, index); | ||||
| } | ||||
|  | ||||
| std::string IHandlerBase::normalizeIdentifier(const std::string& scope, const std::string& remoteScope, const std::string& identifier) const | ||||
| { | ||||
| 	return VLC->modh->normalizeIdentifier(scope, remoteScope, identifier); | ||||
| } | ||||
|   | ||||
| @@ -25,6 +25,7 @@ class DLL_LINKAGE IHandlerBase | ||||
| protected: | ||||
| 	/// Calls modhandler. Mostly needed to avoid large number of includes in headers | ||||
| 	void registerObject(std::string scope, std::string type_name, std::string name, si32 index); | ||||
| 	std::string normalizeIdentifier(const std::string & scope, const std::string & remoteScope, const std::string & identifier) const; | ||||
|  | ||||
| public: | ||||
| 	/// loads all original game data in vector of json nodes | ||||
| @@ -65,7 +66,7 @@ public: | ||||
| 	void loadObject(std::string scope, std::string name, const JsonNode & data) override | ||||
| 	{ | ||||
| 		auto type_name = getTypeName(); | ||||
| 		auto object = loadFromJson(data, name); | ||||
| 		auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 		object->id = _ObjectID(objects.size()); | ||||
|  | ||||
| 		objects.push_back(object); | ||||
| @@ -75,7 +76,7 @@ public: | ||||
| 	void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override | ||||
| 	{ | ||||
| 		auto type_name = getTypeName(); | ||||
| 		auto object = loadFromJson(data, name); | ||||
| 		auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 		object->id = _ObjectID(index); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -201,14 +201,14 @@ CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(co | ||||
|  | ||||
| void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	objects[object->id] = object; | ||||
| 	VLC->modh->identifiers.registerObject(scope, "object", name, object->id); | ||||
| } | ||||
|  | ||||
| void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | ||||
| { | ||||
| 	auto object = loadFromJson(data, name); | ||||
| 	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name)); | ||||
| 	assert(objects[index] == nullptr); // ensure that this id was not loaded before | ||||
| 	objects[index] = object; | ||||
| 	VLC->modh->identifiers.registerObject(scope, "object", name, object->id); | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "../mapObjects/CObjectClassesHandler.h" | ||||
| #include "../mapObjects/CGHeroInstance.h" | ||||
| #include "../mapObjects/CGTownInstance.h" | ||||
| #include "../spells/CSpellHandler.h" | ||||
| #include "../StringConstants.h" | ||||
| #include "../serializer/JsonDeserializer.h" | ||||
| #include "../serializer/JsonSerializer.h" | ||||
| @@ -432,6 +433,35 @@ void CMapFormatJson::writeTriggeredEvent(const TriggeredEvent& event, JsonNode& | ||||
| 	dest["condition"] = event.trigger.toJson(ConditionToJson); | ||||
| } | ||||
|  | ||||
| void CMapFormatJson::serializeOptions(JsonSerializeFormat & handler) | ||||
| { | ||||
| 	//rumors | ||||
|  | ||||
| 	//disposedHeroes | ||||
|  | ||||
| 	//predefinedHeroes | ||||
|  | ||||
| 	handler.serializeLIC("allowedAbilities", &CHeroHandler::decodeSkill, &CHeroHandler::encodeSkill, VLC->heroh->getDefaultAllowedAbilities(), map->allowedAbilities); | ||||
|  | ||||
| 	handler.serializeLIC("allowedArtifacts", &CArtHandler::decodeArfifact, &CArtHandler::encodeArtifact, VLC->arth->getDefaultAllowed(), map->allowedArtifact); | ||||
|  | ||||
| 	handler.serializeLIC("allowedSpells", &CSpellHandler::decodeSpell, &CSpellHandler::encodeSpell, VLC->spellh->getDefaultAllowed(), map->allowedSpell); | ||||
|  | ||||
|  | ||||
| 	//events | ||||
| } | ||||
|  | ||||
| void CMapFormatJson::readOptions(JsonDeserializer & handler) | ||||
| { | ||||
| 	serializeOptions(handler); | ||||
| } | ||||
|  | ||||
| void CMapFormatJson::writeOptions(JsonSerializer & handler) | ||||
| { | ||||
| 	serializeOptions(handler); | ||||
| } | ||||
|  | ||||
|  | ||||
| ///CMapPatcher | ||||
| CMapPatcher::CMapPatcher(JsonNode stream): | ||||
| 	input(stream) | ||||
| @@ -490,7 +520,7 @@ std::unique_ptr<CMapHeader> CMapLoaderJson::loadMapHeader() | ||||
| 	map = nullptr; | ||||
| 	std::unique_ptr<CMapHeader> result = std::unique_ptr<CMapHeader>(new CMapHeader()); | ||||
| 	mapHeader = result.get(); | ||||
| 	readHeader(); | ||||
| 	readHeader(false); | ||||
| 	return std::move(result); | ||||
| } | ||||
|  | ||||
| @@ -512,7 +542,7 @@ const JsonNode CMapLoaderJson::getFromArchive(const std::string & archiveFilenam | ||||
| void CMapLoaderJson::readMap() | ||||
| { | ||||
| 	LOG_TRACE(logGlobal); | ||||
| 	readHeader(); | ||||
| 	readHeader(true); | ||||
| 	map->initTerrain(); | ||||
| 	readTerrain(); | ||||
| 	readObjects(); | ||||
| @@ -525,7 +555,7 @@ void CMapLoaderJson::readMap() | ||||
| 	map->calculateGuardingGreaturePositions(); | ||||
| } | ||||
|  | ||||
| void CMapLoaderJson::readHeader() | ||||
| void CMapLoaderJson::readHeader(const bool complete) | ||||
| { | ||||
| 	//do not use map field here, use only mapHeader | ||||
| 	JsonNode header = getFromArchive(HEADER_FILE_NAME); | ||||
| @@ -575,6 +605,9 @@ void CMapLoaderJson::readHeader() | ||||
|  | ||||
| 	readTeams(handler); | ||||
| 	//TODO: readHeader | ||||
|  | ||||
| 	if(complete) | ||||
| 		readOptions(handler); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -900,6 +933,8 @@ void CMapSaverJson::writeHeader() | ||||
| 	//todo:	allowedHeroes; | ||||
| 	//todo: placeholdedHeroes; | ||||
|  | ||||
| 	writeOptions(handler); | ||||
|  | ||||
| 	addToArchive(header, HEADER_FILE_NAME); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -56,13 +56,11 @@ protected: | ||||
|  | ||||
| 	/** | ||||
| 	 * Reads team settings to header | ||||
| 	 * @param input serialized header | ||||
| 	 */ | ||||
| 	void readTeams(JsonDeserializer & handler); | ||||
|  | ||||
| 	/** | ||||
| 	 * Saves team settings to header | ||||
| 	 * @param output serialized header | ||||
| 	 */ | ||||
| 	void writeTeams(JsonSerializer & handler); | ||||
|  | ||||
| @@ -89,6 +87,21 @@ protected: | ||||
| 	 * Writes one of triggered events | ||||
| 	 */ | ||||
| 	void writeTriggeredEvent(const TriggeredEvent & event, JsonNode & dest); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	///common part of map attributes saving/loading | ||||
| 	void serializeOptions(JsonSerializeFormat & handler); | ||||
|  | ||||
| 	/** | ||||
| 	 * Loads map attributes except header ones | ||||
| 	 */ | ||||
| 	void readOptions(JsonDeserializer & handler); | ||||
|  | ||||
| 	/** | ||||
| 	 * Saves map attributes except header ones | ||||
| 	 */ | ||||
| 	void writeOptions(JsonSerializer & handler); | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CMapPatcher : public CMapFormatJson, public IMapPatcher | ||||
| @@ -166,7 +179,7 @@ private: | ||||
| 	/** | ||||
| 	 * Reads the map header. | ||||
| 	 */ | ||||
| 	void readHeader(); | ||||
| 	void readHeader(const bool complete); | ||||
|  | ||||
| 	/** | ||||
| 	 * Reads complete map. | ||||
|   | ||||
| @@ -54,11 +54,33 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode | ||||
| 	if(field.isNull()) | ||||
| 		return; | ||||
|  | ||||
| 	auto loadPart = [&](const JsonVector & part, const bool val) | ||||
| 	{ | ||||
| 		for(size_t index = 0; index < part.size(); index++) | ||||
| 		{ | ||||
| 			const std::string & identifier = part[index].String(); | ||||
|  | ||||
| 			logGlobal->debugStream() << "serializeLIC: " << fieldName << " " << identifier; | ||||
|  | ||||
| 			si32 rawId = decoder(identifier); | ||||
| 			if(rawId >= 0) | ||||
| 			{ | ||||
| 				if(rawId < value.size()) | ||||
| 					value[rawId] = val; | ||||
| 				else | ||||
| 					logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" id out of bounds " << rawId; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" identifier not resolved " << identifier; | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	const JsonVector & anyOf = field["anyOf"].Vector(); | ||||
| 	const JsonVector & allOf = field["allOf"].Vector(); | ||||
| 	const JsonVector & noneOf = field["noneOf"].Vector(); | ||||
|  | ||||
|  | ||||
| 	if(anyOf.empty() && allOf.empty()) | ||||
| 	{ | ||||
| 		//permissive mode | ||||
| @@ -70,35 +92,11 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode | ||||
| 		value.clear(); | ||||
| 		value.resize(standard.size(), false); | ||||
|  | ||||
| 		for(size_t index = 0; index < anyOf.size(); index++) | ||||
| 		{ | ||||
| 			const std::string & identifier = anyOf[index].String(); | ||||
|  | ||||
| 			si32 rawId = decoder(identifier); | ||||
| 			if(rawId >= 0) | ||||
| 				value[rawId] = true; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		for(size_t index = 0; index < allOf.size(); index++) | ||||
| 		{ | ||||
| 			const std::string & identifier = allOf[index].String(); | ||||
|  | ||||
| 			si32 rawId = decoder(identifier); | ||||
| 			if(rawId >=0) | ||||
| 				value[rawId] = true; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for(size_t index = 0; index < noneOf.size(); index++) | ||||
| 	{ | ||||
| 		const std::string & identifier = noneOf[index].String(); | ||||
|  | ||||
| 		si32 rawId = decoder(identifier); | ||||
| 		if(rawId >=0 ) | ||||
| 			value[rawId] = false; | ||||
| 		loadPart(anyOf, true); | ||||
| 		loadPart(allOf, true); | ||||
| 	} | ||||
|  | ||||
| 	loadPart(noneOf, false); | ||||
| } | ||||
|  | ||||
| void JsonDeserializer::serializeString(const std::string & fieldName, std::string & value) | ||||
|   | ||||
| @@ -1078,6 +1078,27 @@ CSpellHandler::~CSpellHandler() | ||||
| std::vector<bool> CSpellHandler::getDefaultAllowed() const | ||||
| { | ||||
| 	std::vector<bool> allowedSpells; | ||||
| 	allowedSpells.resize(GameConstants::SPELLS_QUANTITY, true); | ||||
| 	allowedSpells.reserve(objects.size()); | ||||
|  | ||||
| 	for(const CSpell * s : objects) | ||||
| 	{ | ||||
| 		allowedSpells.push_back( !(s->isSpecialSpell() || s->isCreatureAbility())); | ||||
| 	} | ||||
|  | ||||
| 	return allowedSpells; | ||||
| } | ||||
|  | ||||
| si32 CSpellHandler::decodeSpell(const std::string& identifier) | ||||
| { | ||||
| 	auto rawId = VLC->modh->identifiers.getIdentifier("core", "spell", identifier); | ||||
| 	if(rawId) | ||||
| 		return rawId.get(); | ||||
| 	else | ||||
| 		return -1; | ||||
| } | ||||
|  | ||||
| std::string CSpellHandler::encodeSpell(const si32 index) | ||||
| { | ||||
| 	return VLC->spellh->objects[index]->identifier; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -360,6 +360,12 @@ public: | ||||
|  | ||||
| 	const std::string getTypeName() const override; | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static si32 decodeSpell(const std::string & identifier); | ||||
|  | ||||
| 	///json serialization helper | ||||
| 	static std::string encodeSpell(const si32 index); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & objects ; | ||||
|   | ||||
| @@ -26,6 +26,16 @@ void checkEqual(const T & actual, const T & expected) | ||||
| 	BOOST_CHECK_EQUAL(actual, expected)	; | ||||
| } | ||||
|  | ||||
| void checkEqual(const std::vector<bool> & actual, const std::vector<bool> & expected) | ||||
| { | ||||
| 	BOOST_CHECK_EQUAL(actual.size(), expected.size()); | ||||
|  | ||||
| 	for(auto actualIt = actual.begin(), expectedIt = expected.begin(); actualIt != actual.end() && expectedIt != expected.end(); actualIt++, expectedIt++) | ||||
| 	{ | ||||
| 		checkEqual(*actualIt, *expectedIt); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template <class Element> | ||||
| void checkEqual(const std::vector<Element> & actual, const std::vector<Element> & expected) | ||||
| { | ||||
| @@ -89,6 +99,20 @@ void checkEqual(const TriggeredEvent & actual,  const TriggeredEvent & expected) | ||||
| 	checkEqual(actual.trigger, expected.trigger); | ||||
| } | ||||
|  | ||||
| void checkEqual(const Rumor & actual, const Rumor & expected) | ||||
| { | ||||
| 	VCMI_CHECK_FIELD_EQUAL(name); | ||||
| 	VCMI_CHECK_FIELD_EQUAL(text); | ||||
| } | ||||
|  | ||||
| void checkEqual(const DisposedHero & actual, const DisposedHero & expected) | ||||
| { | ||||
| 	VCMI_CHECK_FIELD_EQUAL(heroId); | ||||
| 	VCMI_CHECK_FIELD_EQUAL(portrait); | ||||
| 	VCMI_CHECK_FIELD_EQUAL(name); | ||||
| 	VCMI_CHECK_FIELD_EQUAL(players); | ||||
| } | ||||
|  | ||||
| void checkEqual(const TerrainTile & actual, const TerrainTile & expected) | ||||
| { | ||||
| 	//fatal fail here on any error | ||||
| @@ -138,14 +162,16 @@ void MapComparer::compareHeader() | ||||
|  | ||||
| void MapComparer::compareOptions() | ||||
| { | ||||
| 	//rumors | ||||
| 	//disposedHeroes | ||||
| 	//predefinedHeroes | ||||
| 	//allowedSpell | ||||
| 	//allowedArtifact | ||||
| 	//allowedAbilities | ||||
| 	checkEqual(actual->rumors, expected->rumors); | ||||
| 	checkEqual(actual->disposedHeroes, expected->disposedHeroes); | ||||
| 	//todo: compareOptions predefinedHeroes | ||||
|  | ||||
| 	BOOST_ERROR("Not implemented compareOptions()"); | ||||
| 	checkEqual(actual->allowedAbilities, expected->allowedAbilities); | ||||
| 	checkEqual(actual->allowedArtifact, expected->allowedArtifact); | ||||
| 	checkEqual(actual->allowedSpell, expected->allowedSpell); | ||||
| 	//checkEqual(actual->allowedAbilities, expected->allowedAbilities); | ||||
|  | ||||
| 	//todo: compareOptions  events | ||||
| } | ||||
|  | ||||
| void MapComparer::compareObject(const CGObjectInstance * actual, const CGObjectInstance * expected) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user