mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
Added TIMES_ARMY_SIZE updater
This commit is contained in:
@@ -107,6 +107,54 @@ Example of long form with custom parameters:
|
||||
}
|
||||
```
|
||||
|
||||
## TIMES_ARMY_SIZE
|
||||
|
||||
Effect: Updates val to `val = clamp(val * floor(stackSize / stepSize), minimum, maximum)`, where stackSize is total number of creatures in hero army that fulful filter
|
||||
|
||||
Parameters:
|
||||
- `minimum`: minimum possible value of the bonus value. Unlimited by default
|
||||
- `minimum`: maximum possible value of the bonus value. Unlimited by default
|
||||
- `stepSize`: number of units needed to increase updater multiplier by 1
|
||||
- `filteredCreature`: identifier of specific unit to filter
|
||||
- `filteredLevel`: level of units that need to be counted. Redundant if `filteredCreature` is used
|
||||
- `filteredFaction`: faction of units that need to be counted. Redundant if `filteredCreature` is used
|
||||
|
||||
Filtering for specific unit:
|
||||
|
||||
```json
|
||||
"updater" : {
|
||||
"type" : "TIMES_ARMY_SIZE",
|
||||
"filteredCreature" : "pikeman",
|
||||
|
||||
// Optional, by default - unlimited
|
||||
"minimum" : 0,
|
||||
|
||||
// Optional, by default - unlimited
|
||||
"maximum" : 100,
|
||||
|
||||
// Optional, by default - 1
|
||||
"stepSize" : 2
|
||||
}
|
||||
```
|
||||
|
||||
Filtering for specific faction:
|
||||
|
||||
```json
|
||||
"updater" : {
|
||||
"type" : "TIMES_STACK_SIZE",
|
||||
"filteredFaction" : "castle"
|
||||
}
|
||||
```
|
||||
|
||||
Filtering for specific unit level:
|
||||
|
||||
```json
|
||||
"updater" : {
|
||||
"type" : "TIMES_STACK_SIZE",
|
||||
"filteredLevel" : 2
|
||||
}
|
||||
```
|
||||
|
||||
## BONUS_OWNER_UPDATER
|
||||
|
||||
Helper updater for proper functionality of `OPPOSITE_SIDE` limiter
|
||||
|
||||
@@ -148,6 +148,44 @@ JsonNode TimesStackSizeUpdater::toJsonNode() const
|
||||
return JsonNode("TIMES_STACK_SIZE");
|
||||
}
|
||||
|
||||
std::shared_ptr<Bonus> TimesArmySizeUpdater::createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const
|
||||
{
|
||||
if(context.getNodeType() == BonusNodeType::ARMY || context.getNodeType() == BonusNodeType::HERO || context.getNodeType() == BonusNodeType::TOWN)
|
||||
{
|
||||
const auto & army = dynamic_cast<const CArmedInstance &>(context);
|
||||
int totalSize = 0;
|
||||
for (const auto & unit : army.Slots())
|
||||
{
|
||||
if (filteredCreature.hasValue() && filteredCreature != unit.second->getCreatureID())
|
||||
continue;
|
||||
|
||||
if (filteredFaction.hasValue() && filteredFaction != unit.second->getFactionID())
|
||||
continue;
|
||||
|
||||
if (filteredLevel != -1 && filteredLevel != unit.second->getLevel())
|
||||
continue;
|
||||
|
||||
totalSize += unit.second->getCount();
|
||||
}
|
||||
|
||||
auto newBonus = std::make_shared<Bonus>(*b);
|
||||
newBonus->val *= std::clamp(totalSize / stepSize, minimum, maximum);
|
||||
return newBonus;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
std::string TimesArmySizeUpdater::toString() const
|
||||
{
|
||||
return "TimesArmySizeUpdater";
|
||||
}
|
||||
|
||||
JsonNode TimesArmySizeUpdater::toJsonNode() const
|
||||
{
|
||||
return JsonNode("TIMES_ARMY_SIZE");
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Bonus> TimesStackLevelUpdater::apply(const std::shared_ptr<Bonus> & b, int level) const
|
||||
{
|
||||
auto newBonus = std::make_shared<Bonus>(*b);
|
||||
|
||||
@@ -113,6 +113,30 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE TimesArmySizeUpdater : public IUpdater
|
||||
{
|
||||
public:
|
||||
int minimum = std::numeric_limits<int>::min();
|
||||
int maximum = std::numeric_limits<int>::max();
|
||||
int stepSize = 1;
|
||||
int filteredLevel = -1;
|
||||
CreatureID filteredCreature;
|
||||
FactionID filteredFaction;
|
||||
TimesArmySizeUpdater() = default;
|
||||
|
||||
std::shared_ptr<Bonus> createUpdatedBonus(const std::shared_ptr<Bonus> & b, const CBonusSystemNode & context) const override;
|
||||
std::string toString() const override;
|
||||
JsonNode toJsonNode() const override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h)
|
||||
{
|
||||
h & static_cast<IUpdater &>(*this);
|
||||
h & minimum;
|
||||
h & maximum;
|
||||
h & stepSize;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE TimesStackLevelUpdater : public IUpdater
|
||||
{
|
||||
std::shared_ptr<Bonus> apply(const std::shared_ptr<Bonus> & b, int level) const;
|
||||
|
||||
@@ -428,6 +428,35 @@ static TUpdaterPtr parseUpdater(const JsonNode & updaterJson)
|
||||
}
|
||||
return std::make_shared<TimesStackSizeUpdater>(minimum, maximum, std::max(1, stepSize));
|
||||
}
|
||||
if(updaterJson["type"].String() == "TIMES_ARMY_SIZE")
|
||||
{
|
||||
auto result = std::make_shared<TimesArmySizeUpdater>();
|
||||
|
||||
result->minimum = updaterJson["minimum"].isNull() ? std::numeric_limits<int>::min() : updaterJson["minimum"].Integer();
|
||||
result->maximum = updaterJson["maximum"].isNull() ? std::numeric_limits<int>::max() : updaterJson["maximum"].Integer();
|
||||
result->stepSize = updaterJson["stepSize"].isNull() ? 1 : updaterJson["stepSize"].Integer();
|
||||
result->filteredLevel = updaterJson["filteredLevel"].isNull() ? -1 : updaterJson["filteredLevel"].Integer();
|
||||
if (result->minimum > result->maximum)
|
||||
{
|
||||
logMod->warn("TIMES_ARMY_SIZE updater: minimum value (%d) is above maximum value(%d)!", result->minimum, result->maximum);
|
||||
std::swap(result->minimum, result->maximum);
|
||||
}
|
||||
if (!updaterJson["filteredFaction"].isNull())
|
||||
{
|
||||
LIBRARY->identifiers()->requestIdentifier( "faction", updaterJson["filteredFaction"], [result](int32_t identifier)
|
||||
{
|
||||
result->filteredFaction = FactionID(identifier);
|
||||
});
|
||||
}
|
||||
if (!updaterJson["filteredCreature"].isNull())
|
||||
{
|
||||
LIBRARY->identifiers()->requestIdentifier( "creature", updaterJson["filteredCreature"], [result](int32_t identifier)
|
||||
{
|
||||
result->filteredCreature = CreatureID(identifier);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
|
||||
break;
|
||||
|
||||
@@ -298,6 +298,8 @@ void registerTypes(Serializer &s)
|
||||
s.template registerType<DivideStackLevelUpdater>(246);
|
||||
s.template registerType<SetHeroExperience>(247);
|
||||
s.template registerType<GiveStackExperience>(248);
|
||||
s.template registerType<TimesStackSizeUpdater>(249);
|
||||
s.template registerType<TimesArmySizeUpdater>(250);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
Reference in New Issue
Block a user