Browse Source

Removed remaining usages of std::vector<bool>

Ivan Savenko 1 year ago
parent
commit
0842f5afee
54 changed files with 140 additions and 317 deletions
  1. 1 4
      client/lobby/OptionsTab.cpp
  2. 0 5
      lib/BattleFieldHandler.cpp
  3. 0 1
      lib/BattleFieldHandler.h
  4. 11 8
      lib/CArtHandler.cpp
  5. 2 2
      lib/CArtHandler.h
  6. 0 12
      lib/CCreatureHandler.cpp
  7. 0 1
      lib/CCreatureHandler.h
  8. 12 12
      lib/CGameInfoCallback.cpp
  9. 6 2
      lib/CGameInfoCallback.h
  10. 5 13
      lib/CHeroHandler.cpp
  11. 1 3
      lib/CHeroHandler.h
  12. 7 3
      lib/CSkillHandler.cpp
  13. 1 1
      lib/CSkillHandler.h
  14. 13 16
      lib/CTownHandler.cpp
  15. 1 1
      lib/CTownHandler.h
  16. 1 1
      lib/IGameCallback.cpp
  17. 0 7
      lib/IHandlerBase.h
  18. 4 4
      lib/JsonRandom.cpp
  19. 0 5
      lib/ObstacleHandler.cpp
  20. 0 1
      lib/ObstacleHandler.h
  21. 0 5
      lib/RiverHandler.cpp
  22. 0 1
      lib/RiverHandler.h
  23. 0 5
      lib/RoadHandler.cpp
  24. 0 1
      lib/RoadHandler.h
  25. 0 5
      lib/ScriptHandler.cpp
  26. 0 1
      lib/ScriptHandler.h
  27. 0 5
      lib/TerrainHandler.cpp
  28. 0 1
      lib/TerrainHandler.h
  29. 4 0
      lib/constants/EntityIdentifiers.h
  30. 1 4
      lib/gameState/CGameState.cpp
  31. 0 5
      lib/mapObjectConstructors/CObjectClassesHandler.cpp
  32. 0 2
      lib/mapObjectConstructors/CObjectClassesHandler.h
  33. 3 3
      lib/mapObjects/CGHeroInstance.cpp
  34. 0 14
      lib/mapObjects/CGMarket.cpp
  35. 0 1
      lib/mapObjects/CGMarket.h
  36. 1 2
      lib/mapObjects/CGTownInstance.cpp
  37. 18 41
      lib/mapping/CMap.cpp
  38. 3 3
      lib/mapping/CMap.h
  39. 2 2
      lib/mapping/CMapHeader.h
  40. 8 8
      lib/mapping/MapFormatH3M.cpp
  41. 4 13
      lib/mapping/MapFormatJson.cpp
  42. 7 30
      lib/mapping/MapReaderH3M.cpp
  43. 4 9
      lib/mapping/MapReaderH3M.h
  44. 3 2
      lib/pathfinder/TurnInfo.cpp
  45. 1 1
      lib/pathfinder/TurnInfo.h
  46. 9 12
      lib/rmg/CMapGenerator.cpp
  47. 1 7
      lib/rmg/CRmgTemplate.cpp
  48. 0 6
      lib/rmg/CRmgTemplateStorage.cpp
  49. 0 1
      lib/rmg/CRmgTemplateStorage.h
  50. 1 1
      lib/rmg/RmgMap.cpp
  51. 0 9
      lib/serializer/BinaryDeserializer.h
  52. 0 8
      lib/serializer/BinarySerializer.h
  53. 4 6
      lib/spells/CSpellHandler.cpp
  54. 1 1
      lib/spells/CSpellHandler.h

+ 1 - 4
client/lobby/OptionsTab.cpp

@@ -407,10 +407,7 @@ OptionsTab::SelectionWindow::SelectionWindow(PlayerColor _color, SelType _type)
 	selectedHero = initialHero;
 	selectedBonus = initialBonus;
 	allowedFactions = SEL->getPlayerInfo(color).allowedFactions;
-	std::vector<bool> allowedHeroesFlag = SEL->getMapInfo()->mapHeader->allowedHeroes;
-	for(int i = 0; i < allowedHeroesFlag.size(); i++)
-		if(allowedHeroesFlag[i])
-			allowedHeroes.insert(HeroTypeID(i));
+	allowedHeroes = SEL->getMapInfo()->mapHeader->allowedHeroes;
 
 	for(auto & player : SEL->getStartInfo()->playerInfos)
 	{

+ 0 - 5
lib/BattleFieldHandler.cpp

@@ -54,11 +54,6 @@ const std::vector<std::string> & BattleFieldHandler::getTypeNames() const
 	return types;
 }
 
-std::vector<bool> BattleFieldHandler::getDefaultAllowed() const
-{
-	return std::vector<bool>();
-}
-
 int32_t BattleFieldInfo::getIndex() const
 {
 	return battlefield.getNum();

+ 0 - 1
lib/BattleFieldHandler.h

@@ -71,7 +71,6 @@ public:
 
 	virtual const std::vector<std::string> & getTypeNames() const override;
 	virtual std::vector<JsonNode> loadLegacyData() override;
-	virtual std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 11 - 8
lib/CArtHandler.cpp

@@ -651,24 +651,27 @@ bool CArtHandler::legalArtifact(const ArtifactID & id)
 	return false;
 }
 
-void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
+void CArtHandler::initAllowedArtifactsList(const std::set<ArtifactID> & allowed)
 {
 	allowedArtifacts.clear();
 
-	for (ArtifactID i=ArtifactID::SPELLBOOK; i < ArtifactID(static_cast<si32>(objects.size())); i.advance(1))
+	for (ArtifactID i : allowed)
 	{
-		if (allowed[i] && legalArtifact(ArtifactID(i)))
+		if (legalArtifact(ArtifactID(i)))
 			allowedArtifacts.push_back(objects[i]);
 			//keep im mind that artifact can be worn by more than one type of bearer
 	}
 }
 
-std::vector<bool> CArtHandler::getDefaultAllowed() const
+std::set<ArtifactID> CArtHandler::getDefaultAllowed() const
 {
-	std::vector<bool> allowedArtifacts;
-	allowedArtifacts.resize(127, true);
-	allowedArtifacts.resize(141, false);
-	allowedArtifacts.resize(size(), true);
+	std::set<ArtifactID> allowedArtifacts;
+
+	for (auto artifact : objects)
+	{
+		if (!artifact->isCombined())
+			allowedArtifacts.insert(artifact->getId());
+	}
 	return allowedArtifacts;
 }
 

+ 2 - 2
lib/CArtHandler.h

@@ -149,7 +149,7 @@ public:
 	static CArtifact::EartClass stringToClass(const std::string & className); //TODO: rework EartClass to make this a constructor
 
 	bool legalArtifact(const ArtifactID & id);
-	void initAllowedArtifactsList(const std::vector<bool> &allowed); //allowed[art_id] -> 0 if not allowed, 1 if allowed
+	void initAllowedArtifactsList(const std::set<ArtifactID> & allowed);
 	static void makeItCreatureArt(CArtifact * a, bool onlyCreature = true);
 	static void makeItCommanderArt(CArtifact * a, bool onlyCommander = true);
 
@@ -161,7 +161,7 @@ public:
 	void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
 	void afterLoadFinalization() override;
 
-	std::vector<bool> getDefaultAllowed() const override;
+	std::set<ArtifactID> getDefaultAllowed() const;
 
 protected:
 	const std::vector<std::string> & getTypeNames() const override;

+ 0 - 12
lib/CCreatureHandler.cpp

@@ -666,18 +666,6 @@ const std::vector<std::string> & CCreatureHandler::getTypeNames() const
 	return typeNames;
 }
 
-std::vector<bool> CCreatureHandler::getDefaultAllowed() const
-{
-	std::vector<bool> ret;
-
-	ret.reserve(objects.size());
-	for(const CCreature * crea : objects)
-	{
-		ret.push_back(crea ? !crea->special : false);
-	}
-	return ret;
-}
-
 void CCreatureHandler::loadCrExpMod()
 {
 	if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) 	//reading default stack experience values

+ 0 - 1
lib/CCreatureHandler.h

@@ -238,7 +238,6 @@ public:
 
 	std::vector<JsonNode> loadLegacyData() override;
 
-	std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 12 - 12
lib/CGameInfoCallback.cpp

@@ -53,19 +53,19 @@ const PlayerSettings * CGameInfoCallback::getPlayerSettings(PlayerColor color) c
 	return &gs->scenarioOps->getIthPlayersSettings(color);
 }
 
-bool CGameInfoCallback::isAllowed(int32_t type, int32_t id) const
+bool CGameInfoCallback::isAllowed(SpellID id) const
 {
-	switch(type)
-	{
-	case 0:
-		return gs->map->allowedSpells[id];
-	case 1:
-		return gs->map->allowedArtifact[id];
-	case 2:
-		return gs->map->allowedAbilities[id];
-	default:
-		ERROR_RET_VAL_IF(1, "Wrong type!", false);
-	}
+	return gs->map->allowedSpells.count(id) != 0;
+}
+
+bool CGameInfoCallback::isAllowed(ArtifactID id) const
+{
+	return gs->map->allowedArtifact.count(id) != 0;
+}
+
+bool CGameInfoCallback::isAllowed(SecondarySkill id) const
+{
+	return gs->map->allowedAbilities.count(id) != 0;
 }
 
 std::optional<PlayerColor> CGameInfoCallback::getPlayerID() const

+ 6 - 2
lib/CGameInfoCallback.h

@@ -57,7 +57,9 @@ public:
 //	//various
 	virtual int getDate(Date mode=Date::DAY) const = 0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
 //	const StartInfo * getStartInfo(bool beforeRandomization = false)const;
-	virtual bool isAllowed(int32_t type, int32_t id) const = 0; //type: 0 - spell; 1- artifact; 2 - secondary skill
+	virtual bool isAllowed(SpellID id) const = 0;
+	virtual bool isAllowed(ArtifactID id) const = 0;
+	virtual bool isAllowed(SecondarySkill id) const = 0;
 
 	//player
 	virtual std::optional<PlayerColor> getPlayerID() const = 0;
@@ -143,7 +145,9 @@ public:
 	//various
 	int getDate(Date mode=Date::DAY)const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
 	virtual const StartInfo * getStartInfo(bool beforeRandomization = false)const;
-	bool isAllowed(int32_t type, int32_t id) const override; //type: 0 - spell; 1- artifact; 2 - secondary skill
+	bool isAllowed(SpellID id) const override;
+	bool isAllowed(ArtifactID id) const override;
+	bool isAllowed(SecondarySkill id) const override;
 
 	//player
 	std::optional<PlayerColor> getPlayerID() const override;

+ 5 - 13
lib/CHeroHandler.cpp

@@ -393,11 +393,6 @@ void CHeroClassHandler::afterLoadFinalization()
 	}
 }
 
-std::vector<bool> CHeroClassHandler::getDefaultAllowed() const
-{
-	return std::vector<bool>(size(), true);
-}
-
 CHeroClassHandler::~CHeroClassHandler() = default;
 
 CHeroHandler::~CHeroHandler() = default;
@@ -763,18 +758,15 @@ ui64 CHeroHandler::reqExp (ui32 level) const
 	}
 }
 
-std::vector<bool> CHeroHandler::getDefaultAllowed() const
+std::set<HeroTypeID> CHeroHandler::getDefaultAllowed() const
 {
-	// Look Data/HOTRAITS.txt for reference
-	std::vector<bool> allowedHeroes;
-	allowedHeroes.reserve(size());
+	std::set<HeroTypeID> result;
 
 	for(const CHero * hero : objects)
-	{
-		allowedHeroes.push_back(hero && !hero->special);
-	}
+		if (hero && !hero->special)
+			result.insert(hero->getId());
 
-	return allowedHeroes;
+	return result;
 }
 
 VCMI_LIB_NAMESPACE_END

+ 1 - 3
lib/CHeroHandler.h

@@ -165,8 +165,6 @@ public:
 
 	void afterLoadFinalization() override;
 
-	std::vector<bool> getDefaultAllowed() const override;
-
 	~CHeroClassHandler();
 
 protected:
@@ -206,7 +204,7 @@ public:
 	CHeroHandler();
 	~CHeroHandler();
 
-	std::vector<bool> getDefaultAllowed() const override;
+	std::set<HeroTypeID> getDefaultAllowed() const;
 
 protected:
 	const std::vector<std::string> & getTypeNames() const override;

+ 7 - 3
lib/CSkillHandler.cpp

@@ -256,10 +256,14 @@ void CSkillHandler::beforeValidate(JsonNode & object)
 	inheritNode("expert");
 }
 
-std::vector<bool> CSkillHandler::getDefaultAllowed() const
+std::set<SecondarySkill> CSkillHandler::getDefaultAllowed() const
 {
-	std::vector<bool> allowedSkills(objects.size(), true);
-	return allowedSkills;
+	std::set<SecondarySkill> result;
+
+	for (auto const & skill : objects)
+		result.insert(skill->getId());
+
+	return result;
 }
 
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/CSkillHandler.h

@@ -90,7 +90,7 @@ public:
 	void afterLoadFinalization() override;
 	void beforeValidate(JsonNode & object) override;
 
-	std::vector<bool> getDefaultAllowed() const override;
+	std::set<SecondarySkill> getDefaultAllowed() const;
 
 protected:
 	const std::vector<std::string> & getTypeNames() const override;

+ 13 - 16
lib/CTownHandler.cpp

@@ -1259,31 +1259,28 @@ void CTownHandler::initializeWarMachines()
 	warMachinesToLoad.clear();
 }
 
-std::vector<bool> CTownHandler::getDefaultAllowed() const
+std::set<FactionID> CTownHandler::getDefaultAllowed() const
 {
-	std::vector<bool> allowedFactions;
-	allowedFactions.reserve(objects.size());
+	std::set<FactionID> allowedFactions;
+
 	for(auto town : objects)
-	{
-		allowedFactions.push_back(town->town != nullptr);
-	}
+		if (town->town != nullptr)
+			allowedFactions.insert(town->getId());
+
 	return allowedFactions;
 }
 
 std::set<FactionID> CTownHandler::getAllowedFactions(bool withTown) const
 {
-	std::set<FactionID> allowedFactions;
-	std::vector<bool> allowed;
-	if (withTown)
-		allowed = getDefaultAllowed();
-	else
-		allowed.resize( objects.size(), true);
+	if (!withTown)
+		return getDefaultAllowed();
 
-	for (size_t i=0; i<allowed.size(); i++)
-		if (allowed[i])
-			allowedFactions.insert(static_cast<FactionID>(i));
+	std::set<FactionID> result;
+	for(auto town : objects)
+		result.insert(town->getId());
+
+	return result;
 
-	return allowedFactions;
 }
 
 const std::vector<std::string> & CTownHandler::getTypeNames() const

+ 1 - 1
lib/CTownHandler.h

@@ -350,7 +350,7 @@ public:
 	void loadCustom() override;
 	void afterLoadFinalization() override;
 
-	std::vector<bool> getDefaultAllowed() const override;
+	std::set<FactionID> getDefaultAllowed() const;
 	std::set<FactionID> getAllowedFactions(bool withTown = true) const;
 
 	static void loadSpecialBuildingBonuses(const JsonNode & source, BonusList & bonusList, CBuilding * building);

+ 1 - 1
lib/IGameCallback.cpp

@@ -160,7 +160,7 @@ void CPrivilegedInfoCallback::getAllowedSpells(std::vector<SpellID> & out, std::
 	{
 		const spells::Spell * spell = SpellID(i).toSpell();
 
-		if (!isAllowed(0, spell->getIndex()))
+		if (!isAllowed(spell->getId()))
 			continue;
 
 		if (level.has_value() && spell->getLevel() != level)

+ 0 - 7
lib/IHandlerBase.h

@@ -44,13 +44,6 @@ public:
 	/// allows handler to do post-loading step for validation or integration of loaded data
 	virtual void afterLoadFinalization(){};
 
-	/**
-	 * Gets a list of objects that are allowed by default on maps
-	 *
-	 * @return a list of allowed objects, the index is the object id
-	 */
-	virtual std::vector<bool> getDefaultAllowed() const = 0;
-
 	virtual ~IHandlerBase(){}
 };
 

+ 4 - 4
lib/JsonRandom.cpp

@@ -164,7 +164,7 @@ namespace JsonRandom
 			if(!allowedClasses.empty() && !allowedClasses.count(art->aClass))
 				continue;
 
-			if(!IObjectInterface::cb->isAllowed(1, art->getIndex()))
+			if(!IObjectInterface::cb->isAllowed(art->getId()))
 				continue;
 
 			if(!allowedPositions.empty())
@@ -344,7 +344,7 @@ namespace JsonRandom
 	{
 		std::set<SecondarySkill> defaultSkills;
 		for(const auto & skill : VLC->skillh->objects)
-			if (IObjectInterface::cb->isAllowed(2, skill->getIndex()))
+			if (IObjectInterface::cb->isAllowed(skill->getId()))
 				defaultSkills.insert(skill->getId());
 
 		std::set<SecondarySkill> potentialPicks = filterKeys(value, defaultSkills, variables);
@@ -366,7 +366,7 @@ namespace JsonRandom
 		{
 			std::set<SecondarySkill> defaultSkills;
 			for(const auto & skill : VLC->skillh->objects)
-				if (IObjectInterface::cb->isAllowed(2, skill->getIndex()))
+				if (IObjectInterface::cb->isAllowed(skill->getId()))
 					defaultSkills.insert(skill->getId());
 
 			for(const auto & element : value.Vector())
@@ -406,7 +406,7 @@ namespace JsonRandom
 	{
 		std::set<SpellID> defaultSpells;
 		for(const auto & spell : VLC->spellh->objects)
-			if (IObjectInterface::cb->isAllowed(0, spell->getIndex()))
+			if (IObjectInterface::cb->isAllowed(spell->getId()))
 				defaultSpells.insert(spell->getId());
 
 		std::set<SpellID> potentialPicks = filterKeys(value, defaultSpells, variables);

+ 0 - 5
lib/ObstacleHandler.cpp

@@ -116,11 +116,6 @@ std::vector<JsonNode> ObstacleHandler::loadLegacyData()
 	return {};
 }
 
-std::vector<bool> ObstacleHandler::getDefaultAllowed() const
-{
-	return {};
-}
-
 const std::vector<std::string> & ObstacleHandler::getTypeNames() const
 {
 	static const std::vector<std::string> types = { "obstacle" };

+ 0 - 1
lib/ObstacleHandler.h

@@ -71,7 +71,6 @@ public:
 	
 	const std::vector<std::string> & getTypeNames() const override;
 	std::vector<JsonNode> loadLegacyData() override;
-	std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 0 - 5
lib/RiverHandler.cpp

@@ -68,11 +68,6 @@ std::vector<JsonNode> RiverTypeHandler::loadLegacyData()
 	return {};
 }
 
-std::vector<bool> RiverTypeHandler::getDefaultAllowed() const
-{
-	return {};
-}
-
 std::string RiverType::getJsonKey() const
 {
 	return modScope + ":" + identifier;

+ 0 - 1
lib/RiverHandler.h

@@ -71,7 +71,6 @@ public:
 
 	virtual const std::vector<std::string> & getTypeNames() const override;
 	virtual std::vector<JsonNode> loadLegacyData() override;
-	virtual std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 0 - 5
lib/RoadHandler.cpp

@@ -59,11 +59,6 @@ std::vector<JsonNode> RoadTypeHandler::loadLegacyData()
 	return {};
 }
 
-std::vector<bool> RoadTypeHandler::getDefaultAllowed() const
-{
-	return {};
-}
-
 std::string RoadType::getJsonKey() const
 {
 	return modScope + ":" + identifier;

+ 0 - 1
lib/RoadHandler.h

@@ -61,7 +61,6 @@ public:
 
 	virtual const std::vector<std::string> & getTypeNames() const override;
 	virtual std::vector<JsonNode> loadLegacyData() override;
-	virtual std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 0 - 5
lib/ScriptHandler.cpp

@@ -217,11 +217,6 @@ const Script * ScriptHandler::resolveScript(const std::string & name) const
 	}
 }
 
-std::vector<bool> ScriptHandler::getDefaultAllowed() const
-{
-	return std::vector<bool>();
-}
-
 std::vector<JsonNode> ScriptHandler::loadLegacyData()
 {
 	return std::vector<JsonNode>();

+ 0 - 1
lib/ScriptHandler.h

@@ -97,7 +97,6 @@ public:
 
 	const Script * resolveScript(const std::string & name) const;
 
-	std::vector<bool> getDefaultAllowed() const override;
 	std::vector<JsonNode> loadLegacyData() override;
 
 	ScriptPtr loadFromJson(vstd::CLoggerBase * logger, const std::string & scope, const JsonNode & json, const std::string & identifier) const;

+ 0 - 5
lib/TerrainHandler.cpp

@@ -140,11 +140,6 @@ std::vector<JsonNode> TerrainTypeHandler::loadLegacyData()
 	return result;
 }
 
-std::vector<bool> TerrainTypeHandler::getDefaultAllowed() const
-{
-	return {};
-}
-
 bool TerrainType::isLand() const
 {
 	return !isWater();

+ 0 - 1
lib/TerrainHandler.h

@@ -109,7 +109,6 @@ public:
 
 	virtual const std::vector<std::string> & getTypeNames() const override;
 	virtual std::vector<JsonNode> loadLegacyData() override;
-	virtual std::vector<bool> getDefaultAllowed() const override;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 4 - 0
lib/constants/EntityIdentifiers.h

@@ -23,6 +23,7 @@ class HeroType;
 class CHero;
 class HeroTypeService;
 class Faction;
+class Skill;
 class RoadType;
 class RiverType;
 class TerrainType;
@@ -308,6 +309,9 @@ public:
 	static std::string entityType();
 	static si32 decode(const std::string& identifier);
 	static std::string encode(const si32 index);
+
+	const CSkill * toSkill() const;
+	const Skill * toEntity(const Services * services) const;
 };
 
 class DLL_LINKAGE PrimarySkill : public Identifier<PrimarySkill>

+ 1 - 4
lib/gameState/CGameState.cpp

@@ -1877,10 +1877,7 @@ bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
 
 std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllowed) const
 {
-	std::set<HeroTypeID> ret;
-	for(int i = 0; i < map->allowedHeroes.size(); i++)
-		if(map->allowedHeroes[i] || alsoIncludeNotAllowed)
-			ret.insert(HeroTypeID(i));
+	std::set<HeroTypeID> ret = map->allowedHeroes;
 
 	for(const auto & playerSettingPair : scenarioOps->playerInfos) //remove uninitialized yet heroes picked for start by other players
 	{

+ 0 - 5
lib/mapObjectConstructors/CObjectClassesHandler.cpp

@@ -304,11 +304,6 @@ void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID
 	objects[ID]->objects[subID] = nullptr;
 }
 
-std::vector<bool> CObjectClassesHandler::getDefaultAllowed() const
-{
-	return std::vector<bool>(); //TODO?
-}
-
 TObjectTypeHandler CObjectClassesHandler::getHandlerFor(MapObjectID type, MapObjectSubID subtype) const
 {
 	try

+ 0 - 2
lib/mapObjectConstructors/CObjectClassesHandler.h

@@ -101,8 +101,6 @@ public:
 	void beforeValidate(JsonNode & object) override;
 	void afterLoadFinalization() override;
 
-	std::vector<bool> getDefaultAllowed() const override;
-
 	/// Queries to detect loaded objects
 	std::set<MapObjectID> knownObjects() const;
 	std::set<MapObjectSubID> knownSubObjects(MapObjectID primaryID) const;

+ 3 - 3
lib/mapObjects/CGHeroInstance.cpp

@@ -212,7 +212,7 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
 	if ( !canLearnSkill())
 		return false;
 
-	if (!cb->isAllowed(2, which))
+	if (!cb->isAllowed(which))
 		return false;
 
 	if (getSecSkillLevel(which) > 0)
@@ -777,7 +777,7 @@ void CGHeroInstance::spendMana(ServerCallback * server, const int spellCost) con
 
 bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const
 {
-	const bool isAllowed = IObjectInterface::cb->isAllowed(0, spell->getIndex());
+	const bool isAllowed = IObjectInterface::cb->isAllowed(spell->getId());
 
 	const bool inSpellBook = vstd::contains(spells, spell->getId()) && hasSpellbook();
 	const bool specificBonus = hasBonusOfType(BonusType::SPELL, BonusSubtypeID(spell->getId()));
@@ -841,7 +841,7 @@ bool CGHeroInstance::canLearnSpell(const spells::Spell * spell, bool allowBanned
 		return false;//creature abilities can not be learned
 	}
 
-	if(!allowBanned && !IObjectInterface::cb->isAllowed(0, spell->getIndex()))
+	if(!allowBanned && !IObjectInterface::cb->isAllowed(spell->getId()))
 	{
 		logGlobal->warn("Hero %s try to learn banned spell %s", nodeName(), spell->getNameTranslated());
 		return false;//banned spells should not be learned

+ 0 - 14
lib/mapObjects/CGMarket.cpp

@@ -96,20 +96,6 @@ void CGBlackMarket::newTurn(CRandomGenerator & rand) const
 	cb->sendAndApply(&saa);
 }
 
-void CGUniversity::initObj(CRandomGenerator & rand)
-{
-	CGMarket::initObj(rand);
-	
-	std::vector<int> toChoose;
-	for(int i = 0; i < VLC->skillh->size(); ++i)
-	{
-		if(!vstd::contains(skills, i) && cb->isAllowed(2, i))
-		{
-			toChoose.push_back(i);
-		}
-	}
-}
-
 std::vector<int> CGUniversity::availableItemsIds(EMarketMode mode) const
 {
 	switch (mode)

+ 0 - 1
lib/mapObjects/CGMarket.h

@@ -67,7 +67,6 @@ public:
 	std::vector<int> skills; //available skills
 
 	std::vector<int> availableItemsIds(EMarketMode mode) const override;
-	void initObj(CRandomGenerator & rand) override;//set skills for trade
 	void onHeroVisit(const CGHeroInstance * h) const override; //open window
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 1 - 2
lib/mapObjects/CGTownInstance.cpp

@@ -1201,8 +1201,7 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
 	}
 
 	{
-		std::vector<bool> standard = VLC->spellh->getDefaultAllowed();
-		JsonSerializeFormat::LIC spellsLIC(standard, SpellID::decode, SpellID::encode);
+		JsonSerializeFormat::LIC spellsLIC(VLC->spellh->getDefaultAllowed(), SpellID::decode, SpellID::encode);
 
 		if(handler.saving)
 		{

+ 18 - 41
lib/mapping/CMap.cpp

@@ -621,67 +621,44 @@ void CMap::banWaterContent()
 
 void CMap::banWaterSpells()
 {
-	for (int j = 0; j < allowedSpells.size(); j++)
+	vstd::erase_if(allowedSpells, [&](SpellID spell)
 	{
-		if (allowedSpells[j])
-		{
-			auto* spell = dynamic_cast<const CSpell*>(VLC->spells()->getByIndex(j));
-			if (spell->onlyOnWaterMap && !isWaterMap())
-			{
-				allowedSpells[j] = false;
-			}
-		}
-	}
+		return spell.toSpell()->onlyOnWaterMap && !isWaterMap();
+	});
 }
 
 void CMap::banWaterArtifacts()
 {
-	for (int j = 0; j < allowedArtifact.size(); j++)
+	vstd::erase_if(allowedArtifact, [&](ArtifactID artifact)
 	{
-		if (allowedArtifact[j])
-		{
-			auto* art = dynamic_cast<const CArtifact*>(VLC->artifacts()->getByIndex(j));
-			if (art->onlyOnWaterMap && !isWaterMap())
-			{
-				allowedArtifact[j] = false;
-			}
-		}
-	}
+		return artifact.toArtifact()->onlyOnWaterMap && !isWaterMap();
+	});
 }
 
 void CMap::banWaterSkills()
 {
-	for (int j = 0; j < allowedAbilities.size(); j++)
+	vstd::erase_if(allowedAbilities, [&](SecondarySkill skill)
 	{
-		if (allowedAbilities[j])
-		{
-			auto* skill = dynamic_cast<const CSkill*>(VLC->skills()->getByIndex(j));
-			if (skill->onlyOnWaterMap && !isWaterMap())
-			{
-				allowedAbilities[j] = false;
-			}
-		}
-	}
+		return skill.toSkill()->onlyOnWaterMap && !isWaterMap();
+	});
 }
 
 void CMap::banWaterHeroes()
 {
-	for (int j = 0; j < allowedHeroes.size(); j++)
+	vstd::erase_if(allowedHeroes, [&](HeroTypeID hero)
 	{
-		if (allowedHeroes[j])
-		{
-			auto* h = dynamic_cast<const CHero*>(VLC->heroTypes()->getByIndex(j));
-			if ((h->onlyOnWaterMap && !isWaterMap()) || (h->onlyOnMapWithoutWater && isWaterMap()))
-			{
-				banHero(HeroTypeID(j));
-			}
-		}
-	}
+		return hero.toHeroType()->onlyOnWaterMap && !isWaterMap();
+	});
+
+	vstd::erase_if(allowedHeroes, [&](HeroTypeID hero)
+	{
+		return hero.toHeroType()->onlyOnMapWithoutWater && isWaterMap();
+	});
 }
 
 void CMap::banHero(const HeroTypeID & id)
 {
-	allowedHeroes.at(id) = false;
+	allowedHeroes.erase(id);
 }
 
 void CMap::initTerrain()

+ 3 - 3
lib/mapping/CMap.h

@@ -129,9 +129,9 @@ public:
 	std::vector<Rumor> rumors;
 	std::vector<DisposedHero> disposedHeroes;
 	std::vector<ConstTransitivePtr<CGHeroInstance> > predefinedHeroes;
-	std::vector<bool> allowedSpells;
-	std::vector<bool> allowedArtifact;
-	std::vector<bool> allowedAbilities;
+	std::set<SpellID> allowedSpells;
+	std::set<ArtifactID> allowedArtifact;
+	std::set<SecondarySkill> allowedAbilities;
 	std::list<CMapEvent> events;
 	int3 grailPos;
 	int grailRadius;

+ 2 - 2
lib/mapping/CMapHeader.h

@@ -238,8 +238,8 @@ public:
 
 	std::vector<PlayerInfo> players; /// The default size of the vector is PlayerColor::PLAYER_LIMIT.
 	ui8 howManyTeams;
-	std::vector<bool> allowedHeroes;
-	std::vector<HeroTypeID> reservedCampaignHeroes; /// Heroes that have placeholders in this map and are reserverd for campaign
+	std::set<HeroTypeID> allowedHeroes;
+	std::set<HeroTypeID> reservedCampaignHeroes; /// Heroes that have placeholders in this map and are reserverd for campaign
 
 	bool areAnyPlayers; /// Unused. True if there are any playable players on the map.
 

+ 8 - 8
lib/mapping/MapFormatH3M.cpp

@@ -692,7 +692,7 @@ void CMapLoaderH3M::readAllowedHeroes()
 		for (uint32_t i = 0; i < placeholdersQty; ++i)
 		{
 			auto heroID = reader->readHero();
-			mapHeader->reservedCampaignHeroes.push_back(heroID);
+			mapHeader->reservedCampaignHeroes.insert(heroID);
 		}
 	}
 }
@@ -764,13 +764,13 @@ void CMapLoaderH3M::readAllowedArtifacts()
 	{
 		for(CArtifact * artifact : VLC->arth->objects)
 			if(artifact->isCombined())
-				map->allowedArtifact[artifact->getId()] = false;
+				map->allowedArtifact.erase(artifact->getId());
 	}
 
 	if(!features.levelAB)
 	{
-		map->allowedArtifact[ArtifactID::VIAL_OF_DRAGON_BLOOD] = false;
-		map->allowedArtifact[ArtifactID::ARMAGEDDONS_BLADE] = false;
+		map->allowedArtifact.erase(ArtifactID::VIAL_OF_DRAGON_BLOOD);
+		map->allowedArtifact.erase(ArtifactID::ARMAGEDDONS_BLADE);
 	}
 
 	// Messy, but needed
@@ -780,7 +780,7 @@ void CMapLoaderH3M::readAllowedArtifacts()
 		{
 			if(cond.condition == EventCondition::HAVE_ARTIFACT || cond.condition == EventCondition::TRANSPORT)
 			{
-				map->allowedArtifact[cond.objectType] = false;
+				map->allowedArtifact.erase(cond.objectType);
 			}
 			return cond;
 		};
@@ -1160,7 +1160,7 @@ CGObjectInstance * CMapLoaderH3M::readWitchHut(const int3 & position, std::share
 			auto defaultAllowed = VLC->skillh->getDefaultAllowed();
 
 			for(int skillID = features.skillsCount; skillID < defaultAllowed.size(); ++skillID)
-				if(defaultAllowed[skillID])
+				if(defaultAllowed.count(skillID))
 					allowedAbilities.insert(SecondarySkill(skillID));
 		}
 
@@ -2085,7 +2085,7 @@ int CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position)
 			{
 				auto artid = reader->readArtifact();
 				guard->quest->mission.artifacts.push_back(artid);
-				map->allowedArtifact[artid] = false; //these are unavailable for random generation
+				map->allowedArtifact.erase(artid); //these are unavailable for random generation
 			}
 			break;
 		}
@@ -2212,7 +2212,7 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
 
 		//add all spells from mods
 		for(int i = features.spellsCount; i < defaultAllowed.size(); ++i)
-			if(defaultAllowed[i])
+			if(defaultAllowed.count(i))
 				object->possibleSpells.emplace_back(i);
 	}
 

+ 4 - 13
lib/mapping/MapFormatJson.cpp

@@ -389,28 +389,19 @@ RoadType * CMapFormatJson::getRoadByCode(const std::string & code)
 
 void CMapFormatJson::serializeAllowedFactions(JsonSerializeFormat & handler, std::set<FactionID> & value) const
 {
-	//TODO: unify allowed factions with others - make them std::vector<bool>
-
-	std::vector<bool> temp;
-	temp.resize(VLC->townh->size(), false);
-	auto standard = VLC->townh->getDefaultAllowed();
+	std::set<FactionID> temp;
 
 	if(handler.saving)
 	{
 		for(auto faction : VLC->townh->objects)
 			if(faction->town && vstd::contains(value, faction->getId()))
-				temp[static_cast<std::size_t>(faction->getIndex())] = true;
+				temp.insert(faction->getId());
 	}
 
-	handler.serializeLIC("allowedFactions", &FactionID::decode, &FactionID::encode, standard, temp);
+	handler.serializeLIC("allowedFactions", &FactionID::decode, &FactionID::encode, VLC->townh->getDefaultAllowed(), temp);
 
 	if(!handler.saving)
-	{
-		value.clear();
-		for (std::size_t i=0; i<temp.size(); i++)
-			if(temp[i])
-				value.insert(static_cast<FactionID>(i));
-	}
+		value = temp;
 }
 
 void CMapFormatJson::serializeHeader(JsonSerializeFormat & handler)

+ 7 - 30
lib/mapping/MapReaderH3M.cpp

@@ -266,12 +266,12 @@ void MapReaderH3M::readBitmaskHeroClassesSized(std::set<HeroClassID> & dest, boo
 	readBitmask(dest, classesBytes, classesCount, invert);
 }
 
-void MapReaderH3M::readBitmaskHeroes(std::vector<bool> & dest, bool invert)
+void MapReaderH3M::readBitmaskHeroes(std::set<HeroTypeID> & dest, bool invert)
 {
 	readBitmask<HeroTypeID>(dest, features.heroesBytes, features.heroesCount, invert);
 }
 
-void MapReaderH3M::readBitmaskHeroesSized(std::vector<bool> & dest, bool invert)
+void MapReaderH3M::readBitmaskHeroesSized(std::set<HeroTypeID> & dest, bool invert)
 {
 	uint32_t heroesCount = readUInt32();
 	uint32_t heroesBytes = (heroesCount + 7) / 8;
@@ -280,12 +280,12 @@ void MapReaderH3M::readBitmaskHeroesSized(std::vector<bool> & dest, bool invert)
 	readBitmask<HeroTypeID>(dest, heroesBytes, heroesCount, invert);
 }
 
-void MapReaderH3M::readBitmaskArtifacts(std::vector<bool> &dest, bool invert)
+void MapReaderH3M::readBitmaskArtifacts(std::set<ArtifactID> &dest, bool invert)
 {
 	readBitmask<ArtifactID>(dest, features.artifactsBytes, features.artifactsCount, invert);
 }
 
-void MapReaderH3M::readBitmaskArtifactsSized(std::vector<bool> &dest, bool invert)
+void MapReaderH3M::readBitmaskArtifactsSized(std::set<ArtifactID> &dest, bool invert)
 {
 	uint32_t artifactsCount = reader->readUInt32();
 	uint32_t artifactsBytes = (artifactsCount + 7) / 8;
@@ -294,28 +294,18 @@ void MapReaderH3M::readBitmaskArtifactsSized(std::vector<bool> &dest, bool inver
 	readBitmask<ArtifactID>(dest, artifactsBytes, artifactsCount, invert);
 }
 
-void MapReaderH3M::readBitmaskSpells(std::vector<bool> & dest, bool invert)
-{
-	readBitmask<SpellID>(dest, features.spellsBytes, features.spellsCount, invert);
-}
-
 void MapReaderH3M::readBitmaskSpells(std::set<SpellID> & dest, bool invert)
 {
 	readBitmask(dest, features.spellsBytes, features.spellsCount, invert);
 }
 
-void MapReaderH3M::readBitmaskSkills(std::vector<bool> & dest, bool invert)
-{
-	readBitmask<SecondarySkill>(dest, features.skillsBytes, features.skillsCount, invert);
-}
-
 void MapReaderH3M::readBitmaskSkills(std::set<SecondarySkill> & dest, bool invert)
 {
 	readBitmask(dest, features.skillsBytes, features.skillsCount, invert);
 }
 
 template<class Identifier>
-void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead, const int objectsToRead, bool invert)
+void MapReaderH3M::readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert)
 {
 	for(int byte = 0; byte < bytesToRead; ++byte)
 	{
@@ -331,26 +321,13 @@ void MapReaderH3M::readBitmask(std::vector<bool> & dest, const int bytesToRead,
 				Identifier h3mID(index);
 				Identifier vcmiID = remapIdentifier(h3mID);
 
-				if (vcmiID.getNum() >= dest.size())
-					dest.resize(vcmiID.getNum() + 1);
-				dest[vcmiID.getNum()] = result;
+				if (result)
+					dest.insert(vcmiID);
 			}
 		}
 	}
 }
 
-template<class Identifier>
-void MapReaderH3M::readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert)
-{
-	std::vector<bool> bitmap;
-	bitmap.resize(objectsToRead, false);
-	readBitmask<Identifier>(bitmap, bytesToRead, objectsToRead, invert);
-
-	for(int i = 0; i < bitmap.size(); i++)
-		if(bitmap[i])
-			dest.insert(static_cast<Identifier>(i));
-}
-
 int3 MapReaderH3M::readInt3()
 {
 	int3 p;

+ 4 - 9
lib/mapping/MapReaderH3M.h

@@ -50,13 +50,11 @@ public:
 	void readBitmaskPlayers(std::set<PlayerColor> & dest, bool invert);
 	void readBitmaskResources(std::set<GameResID> & dest, bool invert);
 	void readBitmaskHeroClassesSized(std::set<HeroClassID> & dest, bool invert);
-	void readBitmaskHeroes(std::vector<bool> & dest, bool invert);
-	void readBitmaskHeroesSized(std::vector<bool> & dest, bool invert);
-	void readBitmaskArtifacts(std::vector<bool> & dest, bool invert);
-	void readBitmaskArtifactsSized(std::vector<bool> & dest, bool invert);
-	void readBitmaskSpells(std::vector<bool> & dest, bool invert);
+	void readBitmaskHeroes(std::set<HeroTypeID> & dest, bool invert);
+	void readBitmaskHeroesSized(std::set<HeroTypeID> & dest, bool invert);
+	void readBitmaskArtifacts(std::set<ArtifactID> & dest, bool invert);
+	void readBitmaskArtifactsSized(std::set<ArtifactID> & dest, bool invert);
 	void readBitmaskSpells(std::set<SpellID> & dest, bool invert);
-	void readBitmaskSkills(std::vector<bool> & dest, bool invert);
 	void readBitmaskSkills(std::set<SecondarySkill> & dest, bool invert);
 
 	int3 readInt3();
@@ -88,9 +86,6 @@ private:
 	template<class Identifier>
 	void readBitmask(std::set<Identifier> & dest, int bytesToRead, int objectsToRead, bool invert);
 
-	template<class Identifier>
-	void readBitmask(std::vector<bool> & dest, int bytesToRead, int objectsToRead, bool invert);
-
 	MapFormatFeaturesH3M features;
 	MapIdentifiersH3M remapper;
 

+ 3 - 2
lib/pathfinder/TurnInfo.cpp

@@ -23,7 +23,8 @@ TurnInfo::BonusCache::BonusCache(const TConstBonusListPtr & bl)
 	for(const auto & terrain : VLC->terrainTypeHandler->objects)
 	{
 		auto selector = Selector::typeSubtype(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(terrain->getId()));
-		noTerrainPenalty.push_back(static_cast<bool>(bl->getFirst(selector)));
+		if (bl->getFirst(selector))
+			noTerrainPenalty.insert(terrain->getId());
 	}
 
 	freeShipBoarding = static_cast<bool>(bl->getFirst(Selector::type()(BonusType::FREE_SHIP_BOARDING)));
@@ -87,7 +88,7 @@ bool TurnInfo::hasBonusOfType(BonusType type, BonusSubtypeID subtype) const
 	case BonusType::WATER_WALKING:
 		return bonusCache->waterWalking;
 	case BonusType::NO_TERRAIN_PENALTY:
-		return bonusCache->noTerrainPenalty[subtype.getNum()];
+		return bonusCache->noTerrainPenalty.count(subtype.as<TerrainId>());
 	}
 
 	return static_cast<bool>(

+ 1 - 1
lib/pathfinder/TurnInfo.h

@@ -21,7 +21,7 @@ struct DLL_LINKAGE TurnInfo
 	/// This is certainly not the best design ever and certainly can be improved
 	/// Unfortunately for pathfinder that do hundreds of thousands calls onus system add too big overhead
 	struct BonusCache {
-		std::vector<bool> noTerrainPenalty;
+		std::set<TerrainId> noTerrainPenalty;
 		bool freeShipBoarding;
 		bool flyingMovement;
 		int flyingMovementVal;

+ 9 - 12
lib/rmg/CMapGenerator.cpp

@@ -493,19 +493,16 @@ const std::vector<HeroTypeID> CMapGenerator::getAllPossibleHeroes() const
 	auto isWaterMap = map->getMap(this).isWaterMap();
 	//Skip heroes that were banned, including the ones placed in prisons
 	std::vector<HeroTypeID> ret;
-	for (int j = 0; j < map->getMap(this).allowedHeroes.size(); j++)
+	for (HeroTypeID hero : map->getMap(this).allowedHeroes)
 	{
-		if (map->getMap(this).allowedHeroes[j])
+		auto * h = dynamic_cast<const CHero*>(VLC->heroTypes()->getById(hero));
+		if ((h->onlyOnWaterMap && !isWaterMap) || (h->onlyOnMapWithoutWater && isWaterMap))
 		{
-			auto * h = dynamic_cast<const CHero*>(VLC->heroTypes()->getByIndex(j));
-			if ((h->onlyOnWaterMap && !isWaterMap) || (h->onlyOnMapWithoutWater && isWaterMap))
-			{
-				continue;
-			}
-			else
-			{
-				ret.push_back(HeroTypeID(j));
-			}
+			continue;
+		}
+		else
+		{
+			ret.push_back(hero);
 		}
 	}
 	return ret;
@@ -514,7 +511,7 @@ const std::vector<HeroTypeID> CMapGenerator::getAllPossibleHeroes() const
 void CMapGenerator::banQuestArt(const ArtifactID & id)
 {
 	//TODO: Protect with mutex
-	map->getMap(this).allowedArtifact[id] = false;
+	map->getMap(this).allowedArtifact.erase(id);
 }
 
 void CMapGenerator::banHero(const HeroTypeID & id)

+ 1 - 7
lib/rmg/CRmgTemplate.cpp

@@ -188,13 +188,7 @@ std::set<TerrainId> ZoneOptions::getDefaultTerrainTypes() const
 
 std::set<FactionID> ZoneOptions::getDefaultTownTypes() const
 {
-	std::set<FactionID> defaultTowns;
-	auto towns = VLC->townh->getDefaultAllowed();
-	for(int i = 0; i < towns.size(); ++i)
-	{
-		if(towns[i]) defaultTowns.insert(FactionID(i));
-	}
-	return defaultTowns;
+	return VLC->townh->getDefaultAllowed();
 }
 
 const std::set<FactionID> ZoneOptions::getTownTypes() const

+ 0 - 6
lib/rmg/CRmgTemplateStorage.cpp

@@ -51,12 +51,6 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const
 	}
 }
 
-std::vector<bool> CRmgTemplateStorage::getDefaultAllowed() const
-{
-	//all templates are allowed
-	return std::vector<bool>();
-}
-
 std::vector<JsonNode> CRmgTemplateStorage::loadLegacyData()
 {
 	return std::vector<JsonNode>();

+ 0 - 1
lib/rmg/CRmgTemplateStorage.h

@@ -24,7 +24,6 @@ class DLL_LINKAGE CRmgTemplateStorage : public IHandlerBase
 public:
 	CRmgTemplateStorage() = default;
 	
-	std::vector<bool> getDefaultAllowed() const override;
 	std::vector<JsonNode> loadLegacyData() override;
 
 	/// loads single object into game. Scope is namespace of this object, same as name of source mod

+ 1 - 1
lib/rmg/RmgMap.cpp

@@ -345,7 +345,7 @@ bool RmgMap::isAllowedSpell(const SpellID & sid) const
 	assert(sid.getNum() >= 0);
 	if (sid.getNum() < mapInstance->allowedSpells.size())
 	{
-		return mapInstance->allowedSpells[sid];
+		return mapInstance->allowedSpells.count(sid);
 	}
 	else
 		return false;

+ 0 - 9
lib/serializer/BinaryDeserializer.h

@@ -197,15 +197,6 @@ public:
 		data = static_cast<bool>(read);
 	}
 
-	template < typename T, typename std::enable_if < std::is_same<T, std::vector<bool> >::value, int  >::type = 0 >
-	void load(T & data)
-	{
-		std::vector<ui8> convData;
-		load(convData);
-		convData.resize(data.size());
-		range::copy(convData, data.begin());
-	}
-
 	template <typename T, typename std::enable_if < !std::is_same<T, bool >::value, int  >::type = 0>
 	void load(std::vector<T> &data)
 	{

+ 0 - 8
lib/serializer/BinarySerializer.h

@@ -137,14 +137,6 @@ public:
 		save(writ);
 	}
 
-	template < typename T, typename std::enable_if < std::is_same<T, std::vector<bool> >::value, int  >::type = 0 >
-	void save(const T &data)
-	{
-		std::vector<ui8> convData;
-		std::copy(data.begin(), data.end(), std::back_inserter(convData));
-		save(convData);
-	}
-
 	template < class T, typename std::enable_if < std::is_fundamental<T>::value && !std::is_same<T, bool>::value, int  >::type = 0 >
 	void save(const T &data)
 	{

+ 4 - 6
lib/spells/CSpellHandler.cpp

@@ -986,15 +986,13 @@ void CSpellHandler::beforeValidate(JsonNode & object)
 	inheritNode("expert");
 }
 
-std::vector<bool> CSpellHandler::getDefaultAllowed() const
+std::set<SpellID> CSpellHandler::getDefaultAllowed() const
 {
-	std::vector<bool> allowedSpells;
-	allowedSpells.reserve(objects.size());
+	std::set<SpellID> allowedSpells;
 
 	for(const CSpell * s : objects)
-	{
-		allowedSpells.push_back( !(s->isSpecial() || s->isCreatureAbility()));
-	}
+		if (!s->isSpecial() && !s->isCreatureAbility())
+			allowedSpells.insert(s->getId());
 
 	return allowedSpells;
 }

+ 1 - 1
lib/spells/CSpellHandler.h

@@ -349,7 +349,7 @@ public:
 	 * Gets a list of default allowed spells. OH3 spells are all allowed by default.
 	 *
 	 */
-	std::vector<bool> getDefaultAllowed() const override;
+	std::set<SpellID> getDefaultAllowed() const;
 
 protected:
 	const std::vector<std::string> & getTypeNames() const override;