mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Implement async requests for bonus types
This commit is contained in:
@ -30,10 +30,6 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
///CBonusType
|
///CBonusType
|
||||||
|
|
||||||
CBonusType::CBonusType():
|
|
||||||
hidden(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::string CBonusType::getDescriptionTextID() const
|
std::string CBonusType::getDescriptionTextID() const
|
||||||
{
|
{
|
||||||
return TextIdentifier( "core", "bonus", identifier, "description").get();
|
return TextIdentifier( "core", "bonus", identifier, "description").get();
|
||||||
@ -51,6 +47,11 @@ CBonusTypeHandler::CBonusTypeHandler()
|
|||||||
};
|
};
|
||||||
#undef BONUS_NAME
|
#undef BONUS_NAME
|
||||||
|
|
||||||
|
for (int i = 0; i < bonusNames.size(); ++i)
|
||||||
|
{
|
||||||
|
registerObject(ModScope::scopeBuiltin(), "bonus", bonusNames[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
#define BONUS_NAME(x) \
|
#define BONUS_NAME(x) \
|
||||||
do { \
|
do { \
|
||||||
bonusTypes.push_back(CBonusType()); \
|
bonusTypes.push_back(CBonusType()); \
|
||||||
@ -125,7 +126,7 @@ void CBonusTypeHandler::loadObject(std::string scope, std::string name, const Js
|
|||||||
if (vstd::contains(bonusNames, name))
|
if (vstd::contains(bonusNames, name))
|
||||||
{
|
{
|
||||||
//h3 bonus
|
//h3 bonus
|
||||||
BonusType bonus = stringToBonus(name);
|
BonusType bonus = static_cast<BonusType>(vstd::find_pos(bonusNames, name));
|
||||||
CBonusType & bt = bonusTypes[vstd::to_underlying(bonus)];
|
CBonusType & bt = bonusTypes[vstd::to_underlying(bonus)];
|
||||||
loadItem(data, bt, name);
|
loadItem(data, bt, name);
|
||||||
logBonus->trace("Loaded bonus type %s", name);
|
logBonus->trace("Loaded bonus type %s", name);
|
||||||
@ -133,6 +134,7 @@ void CBonusTypeHandler::loadObject(std::string scope, std::string name, const Js
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// new bonus
|
// new bonus
|
||||||
|
registerObject(scope, "bonus", name, bonusNames.size());
|
||||||
bonusNames.push_back(name);
|
bonusNames.push_back(name);
|
||||||
bonusTypes.emplace_back();
|
bonusTypes.emplace_back();
|
||||||
loadItem(data, bonusTypes.back(), name);
|
loadItem(data, bonusTypes.back(), name);
|
||||||
@ -194,15 +196,6 @@ void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BonusType CBonusTypeHandler::stringToBonus(const std::string & name) const
|
|
||||||
{
|
|
||||||
auto it = boost::range::find(bonusNames, name);
|
|
||||||
|
|
||||||
if (it != bonusNames.end())
|
|
||||||
return static_cast<BonusType>(it - bonusNames.begin());
|
|
||||||
return BonusType::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & CBonusTypeHandler::bonusToString(BonusType bonus) const
|
const std::string & CBonusTypeHandler::bonusToString(BonusType bonus) const
|
||||||
{
|
{
|
||||||
return bonusNames.at(static_cast<int>(bonus));
|
return bonusNames.at(static_cast<int>(bonus));
|
||||||
|
@ -22,7 +22,7 @@ class JsonNode;
|
|||||||
class DLL_LINKAGE CBonusType
|
class DLL_LINKAGE CBonusType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBonusType();
|
CBonusType() = default;
|
||||||
|
|
||||||
std::string getDescriptionTextID() const;
|
std::string getDescriptionTextID() const;
|
||||||
|
|
||||||
@ -36,8 +36,8 @@ private:
|
|||||||
std::map<int, std::string> valueDescriptions;
|
std::map<int, std::string> valueDescriptions;
|
||||||
std::string identifier;
|
std::string identifier;
|
||||||
|
|
||||||
bool creatureNature;
|
bool creatureNature = false;
|
||||||
bool hidden;
|
bool hidden = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CBonusTypeHandler : public IBonusTypeHandler
|
class DLL_LINKAGE CBonusTypeHandler : public IBonusTypeHandler
|
||||||
@ -54,7 +54,6 @@ public:
|
|||||||
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||||
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||||
|
|
||||||
BonusType stringToBonus(const std::string & name) const;
|
|
||||||
const std::string & bonusToString(BonusType bonus) const;
|
const std::string & bonusToString(BonusType bonus) const;
|
||||||
|
|
||||||
bool isCreatureNatureBonus(BonusType bonus) const;
|
bool isCreatureNatureBonus(BonusType bonus) const;
|
||||||
|
@ -901,7 +901,6 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph
|
|||||||
|
|
||||||
void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config) const
|
void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config) const
|
||||||
{
|
{
|
||||||
bool hasCreatureNatureBonus = false;
|
|
||||||
creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]);
|
creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]);
|
||||||
|
|
||||||
//FIXME: MOD COMPATIBILITY
|
//FIXME: MOD COMPATIBILITY
|
||||||
@ -915,15 +914,11 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
|||||||
b->source = BonusSource::CREATURE_ABILITY;
|
b->source = BonusSource::CREATURE_ABILITY;
|
||||||
b->sid = BonusSourceID(creature->getId());
|
b->sid = BonusSourceID(creature->getId());
|
||||||
b->duration = BonusDuration::PERMANENT;
|
b->duration = BonusDuration::PERMANENT;
|
||||||
hasCreatureNatureBonus |= LIBRARY->bth->isCreatureNatureBonus(b->type);
|
|
||||||
creature->addNewBonus(b);
|
creature->addNewBonus(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasCreatureNatureBonus)
|
|
||||||
creature->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::LIVING, BonusSource::CREATURE_ABILITY, 0, BonusSourceID(creature->getId())));
|
|
||||||
|
|
||||||
LIBRARY->identifiers()->requestIdentifier("faction", config["faction"], [=](si32 faction)
|
LIBRARY->identifiers()->requestIdentifier("faction", config["faction"], [=](si32 faction)
|
||||||
{
|
{
|
||||||
creature->faction = FactionID(faction);
|
creature->faction = FactionID(faction);
|
||||||
@ -1352,7 +1347,18 @@ CCreatureHandler::~CCreatureHandler()
|
|||||||
|
|
||||||
void CCreatureHandler::afterLoadFinalization()
|
void CCreatureHandler::afterLoadFinalization()
|
||||||
{
|
{
|
||||||
|
for(auto & creature : objects)
|
||||||
|
{
|
||||||
|
if (!creature)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto natureBonuses = creature->getBonuses([](const Bonus * b){
|
||||||
|
return LIBRARY->bth->isCreatureNatureBonus(b->type);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (natureBonuses->empty())
|
||||||
|
creature->addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::LIVING, BonusSource::CREATURE_ABILITY, 0, BonusSourceID(creature->getId())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<CreatureID> CCreatureHandler::getDefaultAllowed() const
|
std::set<CreatureID> CCreatureHandler::getDefaultAllowed() const
|
||||||
|
@ -193,7 +193,7 @@ static void loadBonusSubtype(BonusSubtypeID & subtype, BonusType type, const Jso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadBonusAddInfo(CAddInfo & var, BonusType type, const JsonNode & node)
|
static void loadBonusAddInfo(CAddInfo & var, BonusType type, const JsonNode & value)
|
||||||
{
|
{
|
||||||
const auto & getFirstValue = [](const JsonNode & jsonNode) -> const JsonNode &
|
const auto & getFirstValue = [](const JsonNode & jsonNode) -> const JsonNode &
|
||||||
{
|
{
|
||||||
@ -203,7 +203,6 @@ static void loadBonusAddInfo(CAddInfo & var, BonusType type, const JsonNode & no
|
|||||||
return jsonNode;
|
return jsonNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const JsonNode & value = node["addInfo"];
|
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -432,11 +431,16 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonVector & ability_vec)
|
std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonVector & ability_vec)
|
||||||
{
|
{
|
||||||
auto b = std::make_shared<Bonus>();
|
auto b = std::make_shared<Bonus>();
|
||||||
std::string type = ability_vec[0].String();
|
|
||||||
|
|
||||||
b->type = LIBRARY->bth->stringToBonus(type);
|
const JsonNode & typeNode = ability_vec[0];
|
||||||
|
const JsonNode & subtypeNode = ability_vec[2];
|
||||||
|
|
||||||
|
LIBRARY->identifiers()->requestIdentifier("bonus", typeNode, [b, subtypeNode](si32 bonusID)
|
||||||
|
{
|
||||||
|
b->type = BonusType(bonusID);
|
||||||
|
loadBonusSubtype(b->subtype, b->type, subtypeNode);
|
||||||
|
});
|
||||||
b->val = static_cast<si32>(ability_vec[1].Float());
|
b->val = static_cast<si32>(ability_vec[1].Float());
|
||||||
loadBonusSubtype(b->subtype, b->type, ability_vec[2]);
|
|
||||||
b->additionalInfo = static_cast<si32>(ability_vec[3].Float());
|
b->additionalInfo = static_cast<si32>(ability_vec[3].Float());
|
||||||
b->duration = BonusDuration::PERMANENT; //TODO: handle flags (as integer)
|
b->duration = BonusDuration::PERMANENT; //TODO: handle flags (as integer)
|
||||||
b->turnsRemain = 0;
|
b->turnsRemain = 0;
|
||||||
@ -517,8 +521,10 @@ std::shared_ptr<const ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter
|
|||||||
|
|
||||||
if (!parameters[0].isNull())
|
if (!parameters[0].isNull())
|
||||||
{
|
{
|
||||||
std::string anotherBonusType = parameters[0].String();
|
LIBRARY->identifiers()->requestIdentifier("bonus", parameters[0], [bonusLimiter](si32 bonusID)
|
||||||
bonusLimiter->type = LIBRARY->bth->stringToBonus(anotherBonusType);
|
{
|
||||||
|
bonusLimiter->type = BonusType(bonusID);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto findSource = [&](const JsonNode & parameter)
|
auto findSource = [&](const JsonNode & parameter)
|
||||||
@ -631,10 +637,15 @@ std::shared_ptr<Bonus> JsonUtils::parseBonus(const JsonNode &ability, const Text
|
|||||||
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b, const TextIdentifier & descriptionID)
|
bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b, const TextIdentifier & descriptionID)
|
||||||
{
|
{
|
||||||
const JsonNode * value = nullptr;
|
const JsonNode * value = nullptr;
|
||||||
|
const JsonNode & subtypeNode = ability["subtype"];
|
||||||
|
const JsonNode & addinfoNode = ability["addInfo"];
|
||||||
|
|
||||||
b->type = LIBRARY->bth->stringToBonus(ability["type"].String());
|
LIBRARY->identifiers()->requestIdentifier("bonus", ability["type"], [b, subtypeNode, addinfoNode](si32 bonusID)
|
||||||
|
{
|
||||||
loadBonusSubtype(b->subtype, b->type, ability["subtype"]);
|
b->type = BonusType(bonusID);
|
||||||
|
loadBonusSubtype(b->subtype, b->type, subtypeNode);
|
||||||
|
loadBonusAddInfo(b->additionalInfo, b->type, addinfoNode);
|
||||||
|
});
|
||||||
|
|
||||||
b->val = static_cast<si32>(ability["val"].Float());
|
b->val = static_cast<si32>(ability["val"].Float());
|
||||||
|
|
||||||
@ -643,9 +654,6 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b, const TextIdentifi
|
|||||||
b->valType = static_cast<BonusValueType>(parseByMapN(bonusValueMap, value, "value type "));
|
b->valType = static_cast<BonusValueType>(parseByMapN(bonusValueMap, value, "value type "));
|
||||||
|
|
||||||
b->stacking = ability["stacking"].String();
|
b->stacking = ability["stacking"].String();
|
||||||
|
|
||||||
loadBonusAddInfo(b->additionalInfo, b->type, ability);
|
|
||||||
|
|
||||||
b->turnsRemain = static_cast<si32>(ability["turns"].Float());
|
b->turnsRemain = static_cast<si32>(ability["turns"].Float());
|
||||||
|
|
||||||
if(!ability["description"].isNull())
|
if(!ability["description"].isNull())
|
||||||
@ -768,7 +776,7 @@ CSelector JsonUtils::parseSelector(const JsonNode & ability)
|
|||||||
value = &ability["type"];
|
value = &ability["type"];
|
||||||
if(value->isString())
|
if(value->isString())
|
||||||
{
|
{
|
||||||
ret = ret.And(Selector::type()(LIBRARY->bth->stringToBonus(value->String())));
|
ret = ret.And(Selector::type()(static_cast<BonusType>(*LIBRARY->identifiers()->getIdentifier("bonus", value->String()))));
|
||||||
}
|
}
|
||||||
value = &ability["subtype"];
|
value = &ability["subtype"];
|
||||||
if(!value->isNull() && type != BonusType::NONE)
|
if(!value->isNull() && type != BonusType::NONE)
|
||||||
|
@ -86,21 +86,7 @@ CIdentifierStorage::CIdentifierStorage()
|
|||||||
void CIdentifierStorage::checkIdentifier(std::string & ID)
|
void CIdentifierStorage::checkIdentifier(std::string & ID)
|
||||||
{
|
{
|
||||||
if (boost::algorithm::ends_with(ID, "."))
|
if (boost::algorithm::ends_with(ID, "."))
|
||||||
logMod->warn("BIG WARNING: identifier %s seems to be broken!", ID);
|
logMod->error("BIG WARNING: identifier %s seems to be broken!", ID);
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (std::tolower(ID[pos]) != ID[pos] ) //Not in camelCase
|
|
||||||
{
|
|
||||||
logMod->warn("Warning: identifier %s is not in camelCase!", ID);
|
|
||||||
ID[pos] = std::tolower(ID[pos]);// Try to fix the ID
|
|
||||||
}
|
|
||||||
pos = ID.find('.', pos);
|
|
||||||
}
|
|
||||||
while(pos++ != std::string::npos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIdentifierStorage::requestIdentifier(ObjectCallback callback) const
|
void CIdentifierStorage::requestIdentifier(ObjectCallback callback) const
|
||||||
|
@ -844,11 +844,13 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c
|
|||||||
{
|
{
|
||||||
for(auto bonusData: json[name].Struct())
|
for(auto bonusData: json[name].Struct())
|
||||||
{
|
{
|
||||||
const std::string bonusId = bonusData.first;
|
if(!bonusData.second.Bool())
|
||||||
const bool flag = bonusData.second.Bool();
|
continue;
|
||||||
|
|
||||||
if(flag)
|
LIBRARY->identifiers()->requestIdentifier(bonusData.second.getModScope(), "bonus", bonusData.first, [&vec](si32 bonusID)
|
||||||
vec.push_back(LIBRARY->bth->stringToBonus(bonusId));
|
{
|
||||||
|
vec.push_back(BonusType(bonusID));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -355,7 +355,11 @@ public:
|
|||||||
{
|
{
|
||||||
if(type == "bonus")
|
if(type == "bonus")
|
||||||
{
|
{
|
||||||
return std::make_shared<SelectorCondition>(Selector::type()(LIBRARY->bth->stringToBonus(identifier)));
|
std::optional bonusID(LIBRARY->identifiers()->getIdentifier(scope, "bonus", identifier, true));
|
||||||
|
if (bonusID)
|
||||||
|
return std::make_shared<SelectorCondition>(Selector::type()(BonusType(*bonusID)));
|
||||||
|
else
|
||||||
|
logMod->error("Invalid bonus %s type in spell target condition.", identifier);
|
||||||
}
|
}
|
||||||
else if(type == "creature")
|
else if(type == "creature")
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "../lib/constants/StringConstants.h"
|
#include "../lib/constants/StringConstants.h"
|
||||||
#include "../lib/entities/artifact/CArtifact.h"
|
#include "../lib/entities/artifact/CArtifact.h"
|
||||||
#include "../lib/mapping/CMap.h"
|
#include "../lib/mapping/CMap.h"
|
||||||
|
#include "../lib/modding/IdentifierStorage.h"
|
||||||
|
#include "../lib/modding/ModScope.h"
|
||||||
#include "../lib/rewardable/Configuration.h"
|
#include "../lib/rewardable/Configuration.h"
|
||||||
#include "../lib/rewardable/Limiter.h"
|
#include "../lib/rewardable/Limiter.h"
|
||||||
#include "../lib/rewardable/Reward.h"
|
#include "../lib/rewardable/Reward.h"
|
||||||
@ -341,7 +343,7 @@ void RewardsWidget::saveCurrentVisitInfo(int index)
|
|||||||
for(int i = 0; i < ui->bonuses->rowCount(); ++i)
|
for(int i = 0; i < ui->bonuses->rowCount(); ++i)
|
||||||
{
|
{
|
||||||
auto dur = bonusDurationMap.at(ui->bonuses->item(i, 0)->text().toStdString());
|
auto dur = bonusDurationMap.at(ui->bonuses->item(i, 0)->text().toStdString());
|
||||||
auto typ = LIBRARY->bth->stringToBonus(ui->bonuses->item(i, 1)->text().toStdString());
|
auto typ = static_cast<BonusType>(*LIBRARY->identifiers()->getIdentifier(ModScope::scopeBuiltin(), "bonus", ui->bonuses->item(i, 1)->text().toStdString()));
|
||||||
auto val = ui->bonuses->item(i, 2)->data(Qt::UserRole).toInt();
|
auto val = ui->bonuses->item(i, 2)->data(Qt::UserRole).toInt();
|
||||||
vinfo.reward.heroBonuses.emplace_back(dur, typ, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(object.id));
|
vinfo.reward.heroBonuses.emplace_back(dur, typ, BonusSource::OBJECT_INSTANCE, val, BonusSourceID(object.id));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user