Bläddra i källkod

Remove std::vector<boo> from Json Serializer, simplify affected code

Ivan Savenko 1 år sedan
förälder
incheckning
10e110320b

+ 0 - 2
cmake_modules/VCMI_lib.cmake

@@ -182,7 +182,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/serializer/JsonSerializeFormat.cpp
 		${MAIN_LIB_DIR}/serializer/JsonSerializer.cpp
 		${MAIN_LIB_DIR}/serializer/JsonUpdater.cpp
-		${MAIN_LIB_DIR}/serializer/ILICReader.cpp
 
 		${MAIN_LIB_DIR}/spells/AbilityCaster.cpp
 		${MAIN_LIB_DIR}/spells/AdventureSpellMechanics.cpp
@@ -555,7 +554,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 		${MAIN_LIB_DIR}/serializer/JsonSerializeFormat.h
 		${MAIN_LIB_DIR}/serializer/JsonSerializer.h
 		${MAIN_LIB_DIR}/serializer/JsonUpdater.h
-		${MAIN_LIB_DIR}/serializer/ILICReader.h
 		${MAIN_LIB_DIR}/serializer/Cast.h
 
 		${MAIN_LIB_DIR}/spells/AbilityCaster.h

+ 10 - 0
lib/constants/EntityIdentifiers.cpp

@@ -236,6 +236,16 @@ std::string SecondarySkill::encode(const si32 index)
 	return VLC->skills()->getById(SecondarySkill(index))->getJsonKey();
 }
 
+const CSkill * SecondarySkill::toSkill() const
+{
+	return dynamic_cast<const CSkill *>(toEntity(VLC));
+}
+
+const Skill * SecondarySkill::toEntity(const Services * services) const
+{
+	return services->skills()->getByIndex(num);
+}
+
 const CCreature * CreatureIDBase::toCreature() const
 {
 	return VLC->creh->objects.at(num);

+ 2 - 29
lib/mapObjects/CGTownInstance.cpp

@@ -1201,35 +1201,8 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
 	}
 
 	{
-		JsonSerializeFormat::LIC spellsLIC(VLC->spellh->getDefaultAllowed(), SpellID::decode, SpellID::encode);
-
-		if(handler.saving)
-		{
-			for(const SpellID & id : possibleSpells)
-				spellsLIC.any[id.num] = true;
-
-			for(const SpellID & id : obligatorySpells)
-				spellsLIC.all[id.num] = true;
-		}
-
-		handler.serializeLIC("spells", spellsLIC);
-
-		if(!handler.saving)
-		{
-			possibleSpells.clear();
-			for(si32 idx = 0; idx < spellsLIC.any.size(); idx++)
-			{
-				if(spellsLIC.any[idx])
-					possibleSpells.emplace_back(idx);
-			}
-
-			obligatorySpells.clear();
-			for(si32 idx = 0; idx < spellsLIC.all.size(); idx++)
-			{
-				if(spellsLIC.all[idx])
-					obligatorySpells.emplace_back(idx);
-			}
-		}
+		handler.serializeIdArray( "possibleSpells", possibleSpells);
+		handler.serializeIdArray( "obligatorySpells", obligatorySpells);
 	}
 }
 

+ 0 - 49
lib/serializer/ILICReader.cpp

@@ -1,49 +0,0 @@
-/*
- * JsonTreeSerializer.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 "ILICReader.h"
-
-#include "../JsonNode.h"
-
-#include <vstd/StringUtils.h>
-
-VCMI_LIB_NAMESPACE_BEGIN
-
-void ILICReader::readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, bool val, std::vector<bool> & value) const
-{
-	for(const auto & index : part.Vector())
-	{
-		const std::string & identifier = index.String();
-		const std::string type = typeid(decltype(this)).name();
-
-		const si32 rawId = decoder(identifier);
-		if(rawId >= 0)
-		{
-			if(rawId < value.size())
-				value[rawId] = val;
-			else
-				logGlobal->error("%s::serializeLIC: id out of bounds %d", type, rawId);
-		}
-	}
-}
-
-void ILICReader::readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set<si32> & value) const
-{
-	for(const auto & index : part.Vector())
-	{
-		const std::string & identifier = index.String();
-
-		const si32 rawId = decoder(identifier);
-		if(rawId != -1)
-			value.insert(rawId);
-	}
-}
-
-VCMI_LIB_NAMESPACE_END

+ 0 - 23
lib/serializer/ILICReader.h

@@ -1,23 +0,0 @@
-/*
- * ILICReader.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 "JsonTreeSerializer.h"
-
-VCMI_LIB_NAMESPACE_BEGIN
-
-class DLL_LINKAGE ILICReader
-{
-protected:
-	void readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, bool val, std::vector<bool> & value) const;
-	void readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set<si32> & value) const;
-};
-
-VCMI_LIB_NAMESPACE_END

+ 4 - 68
lib/serializer/JsonDeserializer.cpp

@@ -131,75 +131,11 @@ void JsonDeserializer::serializeInternal(int64_t & value)
 	value = currentObject->Integer();
 }
 
-void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value)
+void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value)
 {
-	const JsonNode & field = currentObject->operator[](fieldName);
-
-	const JsonNode & anyOf = field["anyOf"];
-	const JsonNode & allOf = field["allOf"];
-	const JsonNode & noneOf = field["noneOf"];
-
-	if(anyOf.Vector().empty() && allOf.Vector().empty())
-	{
-		//permissive mode
-		value = standard;
-	}
-	else
-	{
-		//restrictive mode
-		value.clear();
-		value.resize(standard.size(), false);
-
-		readLICPart(anyOf, decoder, true, value);
-		readLICPart(allOf, decoder, true, value);
-	}
-
-	readLICPart(noneOf, decoder, false, value);
-}
-
-void JsonDeserializer::serializeLIC(const std::string & fieldName, LIC & value)
-{
-	const JsonNode & field = currentObject->operator[](fieldName);
-
-	const JsonNode & anyOf = field["anyOf"];
-	const JsonNode & allOf = field["allOf"];
-	const JsonNode & noneOf = field["noneOf"];
-
-	if(anyOf.Vector().empty())
-	{
-		//permissive mode
-		value.any = value.standard;
-	}
-	else
-	{
-		//restrictive mode
-		value.any.clear();
-		value.any.resize(value.standard.size(), false);
-
-		readLICPart(anyOf, value.decoder, true, value.any);
-	}
-
-	readLICPart(allOf, value.decoder, true, value.all);
-	readLICPart(noneOf, value.decoder, true, value.none);
-
-	//remove any banned from allowed and required
-	for(si32 idx = 0; idx < value.none.size(); idx++)
-	{
-		if(value.none[idx])
-		{
-			value.all[idx] = false;
-			value.any[idx] = false;
-		}
-	}
-
-	//add all required to allowed
-	for(si32 idx = 0; idx < value.all.size(); idx++)
-	{
-		if(value.all[idx])
-		{
-			value.any[idx] = true;
-		}
-	}
+	LICSet lic(standard, decoder, encoder);
+	serializeLIC(fieldName, lic);
+	value = lic.any;
 }
 
 void JsonDeserializer::serializeLIC(const std::string & fieldName, LICSet & value)

+ 2 - 4
lib/serializer/JsonDeserializer.h

@@ -9,18 +9,16 @@
  */
 #pragma once
 
-#include "ILICReader.h"
 #include "JsonTreeSerializer.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-class DLL_LINKAGE JsonDeserializer: public JsonTreeSerializer<const JsonNode *>, public ILICReader
+class DLL_LINKAGE JsonDeserializer: public JsonTreeSerializer<const JsonNode *>
 {
 public:
 	JsonDeserializer(const IInstanceResolver * instanceResolver_, const JsonNode & root_);
 
-	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
-	void serializeLIC(const std::string & fieldName, LIC & value) override;
+	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value) override;
 	void serializeLIC(const std::string & fieldName, LICSet & value) override;
 	void serializeString(const std::string & fieldName, std::string & value) override;
 

+ 12 - 11
lib/serializer/JsonSerializeFormat.cpp

@@ -91,17 +91,6 @@ size_t JsonArraySerializer::size() const
     return thisNode->Vector().size();
 }
 
-//JsonSerializeFormat::LIC
-JsonSerializeFormat::LIC::LIC(const std::vector<bool> & Standard, TDecoder Decoder, TEncoder Encoder):
-	standard(Standard),
-	decoder(std::move(Decoder)),
-	encoder(std::move(Encoder))
-{
-	any.resize(standard.size(), false);
-	all.resize(standard.size(), false);
-	none.resize(standard.size(), false);
-}
-
 JsonSerializeFormat::LICSet::LICSet(const std::set<si32> & Standard, TDecoder Decoder, TEncoder Encoder):
 	standard(Standard),
 	decoder(std::move(Decoder)),
@@ -140,4 +129,16 @@ void JsonSerializeFormat::serializeBool(const std::string & fieldName, bool & va
 	serializeBool<bool>(fieldName, value, true, false, defaultValue);
 }
 
+void JsonSerializeFormat::readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set<si32> & value) const
+{
+	for(const auto & index : part.Vector())
+	{
+		const std::string & identifier = index.String();
+
+		const si32 rawId = decoder(identifier);
+		if(rawId != -1)
+			value.insert(rawId);
+	}
+}
+
 VCMI_LIB_NAMESPACE_END

+ 22 - 17
lib/serializer/JsonSerializeFormat.h

@@ -137,18 +137,6 @@ public:
 	///may assume that object index is valid
 	using TEncoder = std::function<std::string(si32)>;
 
-	using TSerialize = std::function<void(JsonSerializeFormat &)>;
-
-	struct LIC
-	{
-		LIC(const std::vector<bool> & Standard, TDecoder Decoder, TEncoder Encoder);
-
-		const std::vector<bool> & standard;
-		const TDecoder decoder;
-		const TEncoder encoder;
-		std::vector<bool> all, any, none;
-	};
-
 	struct LICSet
 	{
 		LICSet(const std::set<si32> & Standard, TDecoder Decoder, TEncoder Encoder);
@@ -211,13 +199,28 @@ public:
 	 * @param value target value, must be resized properly
 	 *
 	 */
-	virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) = 0;
+	virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value) = 0;
 
-	/** @brief Complete serialization of Logical identifier condition
-	 */
-	virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0;
+	template<typename T>
+	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<T> & standard, std::set<T> & value)
+	{
+		std::set<int32_t> standardInt;
+		std::set<int32_t> valueInt;
+
+		for (auto entry : standard)
+			standardInt.insert(entry.getNum());
+
+		for (auto entry : value)
+			valueInt.insert(entry.getNum());
 
-	/** @brief Complete serialization of Logical identifier condition. (Special version)
+		serializeLIC(fieldName, decoder, encoder, standard, value);
+
+		value.clear();
+		for (auto entry : valueInt)
+			value.insert(T(entry));
+	}
+
+	/** @brief Complete serialization of Logical identifier condition.
 	 * Assumes that all values are allowed by default, and standard contains them
 	 */
 	virtual void serializeLIC(const std::string & fieldName, LICSet & value) = 0;
@@ -454,6 +457,8 @@ protected:
 	virtual void serializeInternal(std::string & value) = 0;
 	virtual void serializeInternal(int64_t & value) = 0;
 
+	void readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set<si32> & value) const;
+
 private:
 	const IInstanceResolver * instanceResolver;
 

+ 1 - 10
lib/serializer/JsonSerializer.cpp

@@ -95,7 +95,7 @@ void JsonSerializer::serializeInternal(int64_t & value)
 	currentObject->Integer() = value;
 }
 
-void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value)
+void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value)
 {
 	assert(standard.size() == value.size());
 	if(standard == value)
@@ -104,15 +104,6 @@ void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder
 	writeLICPart(fieldName, "anyOf", encoder, value);
 }
 
-void JsonSerializer::serializeLIC(const std::string & fieldName, LIC & value)
-{
-	if(value.any != value.standard)
-		writeLICPart(fieldName, "anyOf", value.encoder, value.any);
-
-	writeLICPart(fieldName, "allOf", value.encoder, value.all);
-	writeLICPart(fieldName, "noneOf", value.encoder, value.none);
-}
-
 void JsonSerializer::serializeLIC(const std::string & fieldName, LICSet & value)
 {
 	if(value.any != value.standard)

+ 1 - 2
lib/serializer/JsonSerializer.h

@@ -18,8 +18,7 @@ class DLL_LINKAGE JsonSerializer : public JsonTreeSerializer<JsonNode *>
 public:
 	JsonSerializer(const IInstanceResolver * instanceResolver_, JsonNode & root_);
 
-	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
-	void serializeLIC(const std::string & fieldName, LIC & value) override;
+	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value) override;
 	void serializeLIC(const std::string & fieldName, LICSet & value) override;
 	void serializeString(const std::string & fieldName, std::string & value) override;
 

+ 4 - 74
lib/serializer/JsonUpdater.cpp

@@ -105,81 +105,11 @@ void JsonUpdater::serializeInternal(int64_t & value)
 	value = currentObject->Integer();
 }
 
-void JsonUpdater::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value)
+void JsonUpdater::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value)
 {
-	const JsonNode & field = currentObject->operator[](fieldName);
-
-	if(field.isNull())
-		return;
-
-	const JsonNode & anyOf = field["anyOf"];
-	const JsonNode & allOf = field["allOf"];
-	const JsonNode & noneOf = field["noneOf"];
-
-	if(anyOf.Vector().empty() && allOf.Vector().empty())
-	{
-		//permissive mode
-		value = standard;
-	}
-	else
-	{
-		//restrictive mode
-		value.clear();
-		value.resize(standard.size(), false);
-
-		readLICPart(anyOf, decoder, true, value);
-		readLICPart(allOf, decoder, true, value);
-	}
-
-	readLICPart(noneOf, decoder, false, value);
-}
-
-void JsonUpdater::serializeLIC(const std::string & fieldName, LIC & value)
-{
-	const JsonNode & field = currentObject->operator[](fieldName);
-
-	if(field.isNull())
-		return;
-
-	const JsonNode & anyOf = field["anyOf"];
-	const JsonNode & allOf = field["allOf"];
-	const JsonNode & noneOf = field["noneOf"];
-
-	if(anyOf.Vector().empty())
-	{
-		//permissive mode
-		value.any = value.standard;
-	}
-	else
-	{
-		//restrictive mode
-		value.any.clear();
-		value.any.resize(value.standard.size(), false);
-
-		readLICPart(anyOf, value.decoder, true, value.any);
-	}
-
-	readLICPart(allOf, value.decoder, true, value.all);
-	readLICPart(noneOf, value.decoder, true, value.none);
-
-	//remove any banned from allowed and required
-	for(si32 idx = 0; idx < value.none.size(); idx++)
-	{
-		if(value.none[idx])
-		{
-			value.all[idx] = false;
-			value.any[idx] = false;
-		}
-	}
-
-	//add all required to allowed
-	for(si32 idx = 0; idx < value.all.size(); idx++)
-	{
-		if(value.all[idx])
-		{
-			value.any[idx] = true;
-		}
-	}
+	LICSet lic(standard, decoder, encoder);
+	serializeLIC(fieldName, lic);
+	value = lic.any;
 }
 
 void JsonUpdater::serializeLIC(const std::string & fieldName, LICSet & value)

+ 2 - 4
lib/serializer/JsonUpdater.h

@@ -9,20 +9,18 @@
  */
 #pragma once
 
-#include "ILICReader.h"
 #include "JsonTreeSerializer.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CBonusSystemNode;
 
-class DLL_LINKAGE JsonUpdater: public JsonTreeSerializer<const JsonNode *>, public ILICReader
+class DLL_LINKAGE JsonUpdater: public JsonTreeSerializer<const JsonNode *>
 {
 public:
 	JsonUpdater(const IInstanceResolver * instanceResolver_, const JsonNode & root_);
 
-	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
-	void serializeLIC(const std::string & fieldName, LIC & value) override;
+	void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<int32_t> & standard, std::set<int32_t> & value) override;
 	void serializeLIC(const std::string & fieldName, LICSet & value) override;
 	void serializeString(const std::string & fieldName, std::string & value) override;
 

+ 3 - 3
mapeditor/inspector/inspector.cpp

@@ -186,7 +186,7 @@ void Initializer::initialize(CGArtifact * o)
 		std::vector<SpellID> out;
 		for(auto spell : VLC->spellh->objects) //spellh size appears to be greater (?)
 		{
-			if(VLC->spellh->getDefaultAllowed().at(spell->id))
+			if(VLC->spellh->getDefaultAllowed().count(spell->id) != 0)
 			{
 				out.push_back(spell->id);
 			}
@@ -319,7 +319,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
 		auto * delegate = new InspectorDelegate;
 		for(int i = 0; i < VLC->heroh->objects.size(); ++i)
 		{
-			if(controller.map()->allowedHeroes.at(i))
+			if(controller.map()->allowedHeroes.count(HeroTypeID(i)) != 0)
 			{
 				if(o->ID == Obj::PRISON || (o->type && VLC->heroh->objects[i]->heroClass->getIndex() == o->type->heroClass->getIndex()))
 				{
@@ -356,7 +356,7 @@ void Inspector::updateProperties(CGArtifact * o)
 			auto * delegate = new InspectorDelegate;
 			for(auto spell : VLC->spellh->objects)
 			{
-				if(controller.map()->allowedSpells.at(spell->id))
+				if(controller.map()->allowedSpells.count(spell->id) != 0)
 					delegate->options.push_back({QObject::tr(spell->getNameTranslated().c_str()), QVariant::fromValue(int(spell->getId()))});
 			}
 			addProperty("Spell", VLC->spellh->getById(spellId)->getNameTranslated(), delegate, false);

+ 3 - 3
mapeditor/inspector/questwidget.cpp

@@ -54,7 +54,7 @@ QuestWidget::QuestWidget(MapController & _controller, CQuest & _sh, QWidget *par
 		item->setData(Qt::UserRole, QVariant::fromValue(i));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 		item->setCheckState(Qt::Unchecked);
-		if(!controller.map()->allowedArtifact[i])
+		if(controller.map()->allowedArtifact.count(i) == 0)
 			item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 		ui->lArtifacts->addItem(item);
 	}
@@ -66,7 +66,7 @@ QuestWidget::QuestWidget(MapController & _controller, CQuest & _sh, QWidget *par
 		item->setData(Qt::UserRole, QVariant::fromValue(i));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 		item->setCheckState(Qt::Unchecked);
-		if(!controller.map()->allowedSpells[i])
+		if(controller.map()->allowedSpells.count(i) == 0)
 			item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 		ui->lSpells->addItem(item);
 	}
@@ -82,7 +82,7 @@ QuestWidget::QuestWidget(MapController & _controller, CQuest & _sh, QWidget *par
 		for(auto & s : NSecondarySkill::levels)
 			widget->addItem(QString::fromStdString(s));
 		
-		if(!controller.map()->allowedAbilities[i])
+		if(controller.map()->allowedAbilities.count(i) == 0)
 		{
 			item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 			widget->setEnabled(false);

+ 3 - 3
mapeditor/inspector/rewardswidget.cpp

@@ -73,7 +73,7 @@ RewardsWidget::RewardsWidget(CMap & m, CRewardableObject & p, QWidget *parent) :
 			item->setData(Qt::UserRole, QVariant::fromValue(i));
 			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 			item->setCheckState(Qt::Unchecked);
-			if(!map.allowedArtifact[i])
+			if(map.allowedArtifact.count(i) == 0)
 				item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 			w->addItem(item);
 		}
@@ -88,7 +88,7 @@ RewardsWidget::RewardsWidget(CMap & m, CRewardableObject & p, QWidget *parent) :
 			item->setData(Qt::UserRole, QVariant::fromValue(i));
 			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
 			item->setCheckState(Qt::Unchecked);
-			if(!map.allowedSpells[i])
+			if(map.allowedSpells.count(i) == 0)
 				item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 			w->addItem(item);
 		}
@@ -115,7 +115,7 @@ RewardsWidget::RewardsWidget(CMap & m, CRewardableObject & p, QWidget *parent) :
 			for(auto & s : NSecondarySkill::levels)
 				widget->addItem(QString::fromStdString(s));
 			
-			if(!map.allowedAbilities[i])
+			if(map.allowedAbilities.count(i) == 0)
 			{
 				item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
 				widget->setEnabled(false);

+ 2 - 20
mapeditor/mapcontroller.cpp

@@ -94,24 +94,6 @@ void MapController::repairMap(CMap * map) const
 	if(!map)
 		return;
 	
-	//there might be extra skills, arts and spells not imported from map
-	if(VLC->skillh->getDefaultAllowed().size() > map->allowedAbilities.size())
-	{
-		map->allowedAbilities.resize(VLC->skillh->getDefaultAllowed().size());
-	}
-	if(VLC->arth->getDefaultAllowed().size() > map->allowedArtifact.size())
-	{
-		map->allowedArtifact.resize(VLC->arth->getDefaultAllowed().size());
-	}
-	if(VLC->spellh->getDefaultAllowed().size() > map->allowedSpells.size())
-	{
-		map->allowedSpells.resize(VLC->spellh->getDefaultAllowed().size());
-	}
-	if(VLC->heroh->getDefaultAllowed().size() > map->allowedHeroes.size())
-	{
-		map->allowedHeroes.resize(VLC->heroh->getDefaultAllowed().size());
-	}
-	
 	//make sure events/rumors has name to have proper identifiers
 	int emptyNameId = 1;
 	for(auto & e : map->events)
@@ -149,7 +131,7 @@ void MapController::repairMap(CMap * map) const
 		//fix hero instance
 		if(auto * nih = dynamic_cast<CGHeroInstance*>(obj.get()))
 		{
-			map->allowedHeroes.at(nih->subID) = true;
+			map->allowedHeroes.insert(nih->getHeroType());
 			auto type = VLC->heroh->objects[nih->subID];
 			assert(type->heroClass);
 			//TODO: find a way to get proper type name
@@ -217,7 +199,7 @@ void MapController::repairMap(CMap * map) const
 				art->storedArtifact = a;
 			}
 			else
-				map->allowedArtifact.at(art->getArtifact()) = true;
+				map->allowedArtifact.insert(art->getArtifact());
 		}
 	}
 }

+ 20 - 18
mapeditor/mapsettings/mapsettings.cpp

@@ -30,36 +30,36 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) :
 	
 	show();
 
-	for(int i = 0; i < controller.map()->allowedAbilities.size(); ++i)
+	for(auto objectPtr : VLC->skillh->objects)
 	{
-		auto * item = new QListWidgetItem(QString::fromStdString(VLC->skillh->objects[i]->getNameTranslated()));
-		item->setData(Qt::UserRole, QVariant::fromValue(i));
+		auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
+		item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
-		item->setCheckState(controller.map()->allowedAbilities[i] ? Qt::Checked : Qt::Unchecked);
+		item->setCheckState(controller.map()->allowedAbilities.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
 		ui->listAbilities->addItem(item);
 	}
-	for(int i = 0; i < controller.map()->allowedSpells.size(); ++i)
+	for(auto objectPtr : VLC->spellh->objects)
 	{
-		auto * item = new QListWidgetItem(QString::fromStdString(VLC->spellh->objects[i]->getNameTranslated()));
-		item->setData(Qt::UserRole, QVariant::fromValue(i));
+		auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
+		item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
-		item->setCheckState(controller.map()->allowedSpells[i] ? Qt::Checked : Qt::Unchecked);
+		item->setCheckState(controller.map()->allowedSpells.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
 		ui->listSpells->addItem(item);
 	}
-	for(int i = 0; i < controller.map()->allowedArtifact.size(); ++i)
+	for(auto objectPtr : VLC->arth->objects)
 	{
-		auto * item = new QListWidgetItem(QString::fromStdString(VLC->arth->objects[i]->getNameTranslated()));
-		item->setData(Qt::UserRole, QVariant::fromValue(i));
+		auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
+		item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
-		item->setCheckState(controller.map()->allowedArtifact[i] ? Qt::Checked : Qt::Unchecked);
+		item->setCheckState(controller.map()->allowedArtifact.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
 		ui->listArts->addItem(item);
 	}
-	for(int i = 0; i < controller.map()->allowedHeroes.size(); ++i)
+	for(auto objectPtr : VLC->heroh->objects)
 	{
-		auto * item = new QListWidgetItem(QString::fromStdString(VLC->heroh->objects[i]->getNameTranslated()));
-		item->setData(Qt::UserRole, QVariant::fromValue(i));
+		auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
+		item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
 		item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
-		item->setCheckState(controller.map()->allowedHeroes[i] ? Qt::Checked : Qt::Unchecked);
+		item->setCheckState(controller.map()->allowedHeroes.count(objectPtr->getId()) ? Qt::Checked : Qt::Unchecked);
 		ui->listHeroes->addItem(item);
 	}
 
@@ -78,12 +78,14 @@ MapSettings::~MapSettings()
 
 void MapSettings::on_pushButton_clicked()
 {	
-	auto updateMapArray = [](const QListWidget * widget, std::vector<bool> & arr)
+	auto updateMapArray = [](const QListWidget * widget, auto & arr)
 	{
+		arr.clear();
 		for(int i = 0; i < arr.size(); ++i)
 		{
 			auto * item = widget->item(i);
-			arr[i] = item->checkState() == Qt::Checked;
+			if (item->checkState() == Qt::Checked)
+				arr.emplace(i);
 		}
 	};
 	

+ 3 - 3
mapeditor/validator.cpp

@@ -125,7 +125,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
 				}
 				if(ins->type)
 				{
-					if(!map->allowedHeroes[ins->type->getId().getNum()])
+					if(map->allowedHeroes.count(ins->getHeroType()) == 0)
 						issues.emplace_back(QString(tr("Hero %1 is prohibited by map settings")).arg(ins->type->getNameTranslated().c_str()), false);
 					
 					if(!allHeroesOnMap.insert(ins->type).second)
@@ -142,7 +142,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
 				{
 					if(ins->storedArtifact)
 					{
-						if(!map->allowedSpells[ins->storedArtifact->getScrollSpellID()])
+						if(map->allowedSpells.count(ins->storedArtifact->getScrollSpellID()) == 0)
 							issues.emplace_back(QString(tr("Spell scroll %1 is prohibited by map settings")).arg(ins->storedArtifact->getScrollSpellID().toEntity(VLC->spells())->getNameTranslated().c_str()), false);
 					}
 					else
@@ -150,7 +150,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
 				}
 				else
 				{
-					if(ins->ID == Obj::ARTIFACT && !map->allowedArtifact[ins->subID])
+					if(ins->ID == Obj::ARTIFACT && map->allowedArtifact.count(ins->getArtifact()) == 0)
 					{
 						issues.emplace_back(QString(tr("Artifact %1 is prohibited by map settings")).arg(ins->getObjectName().c_str()), false);
 					}

+ 1 - 1
server/CVCMIServer.cpp

@@ -1058,7 +1058,7 @@ bool CVCMIServer::canUseThisHero(PlayerColor player, HeroTypeID ID)
 	return VLC->heroh->size() > ID
 		&& si->playerInfos[player].castle == VLC->heroh->objects[ID]->heroClass->faction
 		&& !vstd::contains(getUsedHeroes(), ID)
-		&& mi->mapHeader->allowedHeroes[ID];
+		&& mi->mapHeader->allowedHeroes.count(ID);
 }
 
 std::vector<HeroTypeID> CVCMIServer::getUsedHeroes()