1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-20 20:23:03 +02:00

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

This commit is contained in:
Ivan Savenko 2023-11-05 16:35:51 +02:00
parent 0842f5afee
commit 10e110320b
20 changed files with 95 additions and 344 deletions

View File

@ -182,7 +182,6 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
${MAIN_LIB_DIR}/serializer/JsonSerializeFormat.cpp ${MAIN_LIB_DIR}/serializer/JsonSerializeFormat.cpp
${MAIN_LIB_DIR}/serializer/JsonSerializer.cpp ${MAIN_LIB_DIR}/serializer/JsonSerializer.cpp
${MAIN_LIB_DIR}/serializer/JsonUpdater.cpp ${MAIN_LIB_DIR}/serializer/JsonUpdater.cpp
${MAIN_LIB_DIR}/serializer/ILICReader.cpp
${MAIN_LIB_DIR}/spells/AbilityCaster.cpp ${MAIN_LIB_DIR}/spells/AbilityCaster.cpp
${MAIN_LIB_DIR}/spells/AdventureSpellMechanics.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/JsonSerializeFormat.h
${MAIN_LIB_DIR}/serializer/JsonSerializer.h ${MAIN_LIB_DIR}/serializer/JsonSerializer.h
${MAIN_LIB_DIR}/serializer/JsonUpdater.h ${MAIN_LIB_DIR}/serializer/JsonUpdater.h
${MAIN_LIB_DIR}/serializer/ILICReader.h
${MAIN_LIB_DIR}/serializer/Cast.h ${MAIN_LIB_DIR}/serializer/Cast.h
${MAIN_LIB_DIR}/spells/AbilityCaster.h ${MAIN_LIB_DIR}/spells/AbilityCaster.h

View File

@ -236,6 +236,16 @@ std::string SecondarySkill::encode(const si32 index)
return VLC->skills()->getById(SecondarySkill(index))->getJsonKey(); 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 const CCreature * CreatureIDBase::toCreature() const
{ {
return VLC->creh->objects.at(num); return VLC->creh->objects.at(num);

View File

@ -1201,35 +1201,8 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
} }
{ {
JsonSerializeFormat::LIC spellsLIC(VLC->spellh->getDefaultAllowed(), SpellID::decode, SpellID::encode); handler.serializeIdArray( "possibleSpells", possibleSpells);
handler.serializeIdArray( "obligatorySpells", obligatorySpells);
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);
}
}
} }
} }

View File

@ -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

View File

@ -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

View File

@ -131,75 +131,11 @@ void JsonDeserializer::serializeInternal(int64_t & value)
value = currentObject->Integer(); 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); LICSet lic(standard, decoder, encoder);
serializeLIC(fieldName, lic);
const JsonNode & anyOf = field["anyOf"]; value = lic.any;
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;
}
}
} }
void JsonDeserializer::serializeLIC(const std::string & fieldName, LICSet & value) void JsonDeserializer::serializeLIC(const std::string & fieldName, LICSet & value)

View File

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

View File

@ -91,17 +91,6 @@ size_t JsonArraySerializer::size() const
return thisNode->Vector().size(); 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): JsonSerializeFormat::LICSet::LICSet(const std::set<si32> & Standard, TDecoder Decoder, TEncoder Encoder):
standard(Standard), standard(Standard),
decoder(std::move(Decoder)), decoder(std::move(Decoder)),
@ -140,4 +129,16 @@ void JsonSerializeFormat::serializeBool(const std::string & fieldName, bool & va
serializeBool<bool>(fieldName, value, true, false, defaultValue); 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 VCMI_LIB_NAMESPACE_END

View File

@ -137,18 +137,6 @@ public:
///may assume that object index is valid ///may assume that object index is valid
using TEncoder = std::function<std::string(si32)>; 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 struct LICSet
{ {
LICSet(const std::set<si32> & Standard, TDecoder Decoder, TEncoder Encoder); LICSet(const std::set<si32> & Standard, TDecoder Decoder, TEncoder Encoder);
@ -211,13 +199,28 @@ public:
* @param value target value, must be resized properly * @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 template<typename T>
*/ void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::set<T> & standard, std::set<T> & value)
virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0; {
std::set<int32_t> standardInt;
std::set<int32_t> 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 * Assumes that all values are allowed by default, and standard contains them
*/ */
virtual void serializeLIC(const std::string & fieldName, LICSet & value) = 0; 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(std::string & value) = 0;
virtual void serializeInternal(int64_t & value) = 0; virtual void serializeInternal(int64_t & value) = 0;
void readLICPart(const JsonNode & part, const JsonSerializeFormat::TDecoder & decoder, std::set<si32> & value) const;
private: private:
const IInstanceResolver * instanceResolver; const IInstanceResolver * instanceResolver;

View File

@ -95,7 +95,7 @@ void JsonSerializer::serializeInternal(int64_t & value)
currentObject->Integer() = 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()); assert(standard.size() == value.size());
if(standard == value) if(standard == value)
@ -104,15 +104,6 @@ void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder
writeLICPart(fieldName, "anyOf", encoder, value); 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) void JsonSerializer::serializeLIC(const std::string & fieldName, LICSet & value)
{ {
if(value.any != value.standard) if(value.any != value.standard)

View File

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

View File

@ -105,81 +105,11 @@ void JsonUpdater::serializeInternal(int64_t & value)
value = currentObject->Integer(); 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); LICSet lic(standard, decoder, encoder);
serializeLIC(fieldName, lic);
if(field.isNull()) value = lic.any;
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;
}
}
} }
void JsonUpdater::serializeLIC(const std::string & fieldName, LICSet & value) void JsonUpdater::serializeLIC(const std::string & fieldName, LICSet & value)

View File

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

View File

@ -186,7 +186,7 @@ void Initializer::initialize(CGArtifact * o)
std::vector<SpellID> out; std::vector<SpellID> out;
for(auto spell : VLC->spellh->objects) //spellh size appears to be greater (?) 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); out.push_back(spell->id);
} }
@ -319,7 +319,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
auto * delegate = new InspectorDelegate; auto * delegate = new InspectorDelegate;
for(int i = 0; i < VLC->heroh->objects.size(); ++i) 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())) 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; auto * delegate = new InspectorDelegate;
for(auto spell : VLC->spellh->objects) 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()))}); delegate->options.push_back({QObject::tr(spell->getNameTranslated().c_str()), QVariant::fromValue(int(spell->getId()))});
} }
addProperty("Spell", VLC->spellh->getById(spellId)->getNameTranslated(), delegate, false); addProperty("Spell", VLC->spellh->getById(spellId)->getNameTranslated(), delegate, false);

View File

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

View File

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

View File

@ -94,24 +94,6 @@ void MapController::repairMap(CMap * map) const
if(!map) if(!map)
return; 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 //make sure events/rumors has name to have proper identifiers
int emptyNameId = 1; int emptyNameId = 1;
for(auto & e : map->events) for(auto & e : map->events)
@ -149,7 +131,7 @@ void MapController::repairMap(CMap * map) const
//fix hero instance //fix hero instance
if(auto * nih = dynamic_cast<CGHeroInstance*>(obj.get())) 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]; auto type = VLC->heroh->objects[nih->subID];
assert(type->heroClass); assert(type->heroClass);
//TODO: find a way to get proper type name //TODO: find a way to get proper type name
@ -217,7 +199,7 @@ void MapController::repairMap(CMap * map) const
art->storedArtifact = a; art->storedArtifact = a;
} }
else else
map->allowedArtifact.at(art->getArtifact()) = true; map->allowedArtifact.insert(art->getArtifact());
} }
} }
} }

View File

@ -30,36 +30,36 @@ MapSettings::MapSettings(MapController & ctrl, QWidget *parent) :
show(); 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())); auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); 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); 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())); auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); 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); 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())); auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); 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); 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())); auto * item = new QListWidgetItem(QString::fromStdString(objectPtr->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(i)); item->setData(Qt::UserRole, QVariant::fromValue(objectPtr->getIndex()));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); 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); ui->listHeroes->addItem(item);
} }
@ -78,12 +78,14 @@ MapSettings::~MapSettings()
void MapSettings::on_pushButton_clicked() 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) for(int i = 0; i < arr.size(); ++i)
{ {
auto * item = widget->item(i); auto * item = widget->item(i);
arr[i] = item->checkState() == Qt::Checked; if (item->checkState() == Qt::Checked)
arr.emplace(i);
} }
}; };

View File

@ -125,7 +125,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
} }
if(ins->type) 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); 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) if(!allHeroesOnMap.insert(ins->type).second)
@ -142,7 +142,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
{ {
if(ins->storedArtifact) 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); 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 else
@ -150,7 +150,7 @@ std::list<Validator::Issue> Validator::validate(const CMap * map)
} }
else 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); issues.emplace_back(QString(tr("Artifact %1 is prohibited by map settings")).arg(ins->getObjectName().c_str()), false);
} }

View File

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