diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index 93bf03483..bcf8c1979 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/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 diff --git a/lib/constants/EntityIdentifiers.cpp b/lib/constants/EntityIdentifiers.cpp index 2d908b6b7..73efb5b9c 100644 --- a/lib/constants/EntityIdentifiers.cpp +++ b/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(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); diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 49fa6800b..6d3cacbd6 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/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); } } diff --git a/lib/serializer/ILICReader.cpp b/lib/serializer/ILICReader.cpp deleted file mode 100644 index a8bcc3793..000000000 --- a/lib/serializer/ILICReader.cpp +++ /dev/null @@ -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 - -VCMI_LIB_NAMESPACE_BEGIN - -void ILICReader::readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, bool val, std::vector & 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 & 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 diff --git a/lib/serializer/ILICReader.h b/lib/serializer/ILICReader.h deleted file mode 100644 index 83d16b10f..000000000 --- a/lib/serializer/ILICReader.h +++ /dev/null @@ -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 & value) const; - void readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set & value) const; -}; - -VCMI_LIB_NAMESPACE_END diff --git a/lib/serializer/JsonDeserializer.cpp b/lib/serializer/JsonDeserializer.cpp index 0c933aee2..a2b840777 100644 --- a/lib/serializer/JsonDeserializer.cpp +++ b/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 & standard, std::vector & value) +void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set & standard, std::set & 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) diff --git a/lib/serializer/JsonDeserializer.h b/lib/serializer/JsonDeserializer.h index 9a4f52c7f..9a3aab5ee 100644 --- a/lib/serializer/JsonDeserializer.h +++ b/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, public ILICReader +class DLL_LINKAGE JsonDeserializer: public JsonTreeSerializer { public: JsonDeserializer(const IInstanceResolver * instanceResolver_, const JsonNode & root_); - void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector & standard, std::vector & 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 & standard, std::set & value) override; void serializeLIC(const std::string & fieldName, LICSet & value) override; void serializeString(const std::string & fieldName, std::string & value) override; diff --git a/lib/serializer/JsonSerializeFormat.cpp b/lib/serializer/JsonSerializeFormat.cpp index aff5c8eb9..4da52c445 100644 --- a/lib/serializer/JsonSerializeFormat.cpp +++ b/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 & 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 & 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(fieldName, value, true, false, defaultValue); } +void JsonSerializeFormat::readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set & 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 diff --git a/lib/serializer/JsonSerializeFormat.h b/lib/serializer/JsonSerializeFormat.h index 1d5efaeea..93dc2caa9 100644 --- a/lib/serializer/JsonSerializeFormat.h +++ b/lib/serializer/JsonSerializeFormat.h @@ -137,18 +137,6 @@ public: ///may assume that object index is valid using TEncoder = std::function; - using TSerialize = std::function; - - struct LIC - { - LIC(const std::vector & Standard, TDecoder Decoder, TEncoder Encoder); - - const std::vector & standard; - const TDecoder decoder; - const TEncoder encoder; - std::vector all, any, none; - }; - struct LICSet { LICSet(const std::set & 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 & standard, std::vector & value) = 0; + virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set & standard, std::set & value) = 0; - /** @brief Complete serialization of Logical identifier condition - */ - virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0; + template + void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set & standard, std::set & value) + { + std::set standardInt; + std::set valueInt; - /** @brief Complete serialization of Logical identifier condition. (Special version) + for (auto entry : standard) + standardInt.insert(entry.getNum()); + + for (auto entry : value) + valueInt.insert(entry.getNum()); + + 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 & value) const; + private: const IInstanceResolver * instanceResolver; diff --git a/lib/serializer/JsonSerializer.cpp b/lib/serializer/JsonSerializer.cpp index 15a050d0e..aa1553e3a 100644 --- a/lib/serializer/JsonSerializer.cpp +++ b/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 & standard, std::vector & value) +void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set & standard, std::set & 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) diff --git a/lib/serializer/JsonSerializer.h b/lib/serializer/JsonSerializer.h index e4fe9d87e..89bbbf26d 100644 --- a/lib/serializer/JsonSerializer.h +++ b/lib/serializer/JsonSerializer.h @@ -18,8 +18,7 @@ class DLL_LINKAGE JsonSerializer : public JsonTreeSerializer public: JsonSerializer(const IInstanceResolver * instanceResolver_, JsonNode & root_); - void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector & standard, std::vector & 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 & standard, std::set & value) override; void serializeLIC(const std::string & fieldName, LICSet & value) override; void serializeString(const std::string & fieldName, std::string & value) override; diff --git a/lib/serializer/JsonUpdater.cpp b/lib/serializer/JsonUpdater.cpp index f80581f19..6a29bc910 100644 --- a/lib/serializer/JsonUpdater.cpp +++ b/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 & standard, std::vector & value) +void JsonUpdater::serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set & standard, std::set & 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) diff --git a/lib/serializer/JsonUpdater.h b/lib/serializer/JsonUpdater.h index b09fd6044..e0cd5f508 100644 --- a/lib/serializer/JsonUpdater.h +++ b/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, public ILICReader +class DLL_LINKAGE JsonUpdater: public JsonTreeSerializer { public: JsonUpdater(const IInstanceResolver * instanceResolver_, const JsonNode & root_); - void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector & standard, std::vector & 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 & standard, std::set & value) override; void serializeLIC(const std::string & fieldName, LICSet & value) override; void serializeString(const std::string & fieldName, std::string & value) override; diff --git a/mapeditor/inspector/inspector.cpp b/mapeditor/inspector/inspector.cpp index 01839d01c..3587dd1b5 100644 --- a/mapeditor/inspector/inspector.cpp +++ b/mapeditor/inspector/inspector.cpp @@ -186,7 +186,7 @@ void Initializer::initialize(CGArtifact * o) std::vector 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); diff --git a/mapeditor/inspector/questwidget.cpp b/mapeditor/inspector/questwidget.cpp index 97e22f586..982138741 100644 --- a/mapeditor/inspector/questwidget.cpp +++ b/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); diff --git a/mapeditor/inspector/rewardswidget.cpp b/mapeditor/inspector/rewardswidget.cpp index 6ec62d84b..373588a3c 100644 --- a/mapeditor/inspector/rewardswidget.cpp +++ b/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); diff --git a/mapeditor/mapcontroller.cpp b/mapeditor/mapcontroller.cpp index 0ba761307..b26bf03c1 100644 --- a/mapeditor/mapcontroller.cpp +++ b/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(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()); } } } diff --git a/mapeditor/mapsettings/mapsettings.cpp b/mapeditor/mapsettings/mapsettings.cpp index 5b410cb56..369e1007f 100644 --- a/mapeditor/mapsettings/mapsettings.cpp +++ b/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 & 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); } }; diff --git a/mapeditor/validator.cpp b/mapeditor/validator.cpp index daa69ce84..1d7b8455d 100644 --- a/mapeditor/validator.cpp +++ b/mapeditor/validator.cpp @@ -125,7 +125,7 @@ std::list 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::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::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); } diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index e9651f91c..0285f7067 100644 --- a/server/CVCMIServer.cpp +++ b/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 CVCMIServer::getUsedHeroes()