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
|
## BONUS_OWNER_UPDATER
|
||||||
|
|
||||||
Helper updater for proper functionality of `OPPOSITE_SIDE` limiter
|
Helper updater for proper functionality of `OPPOSITE_SIDE` limiter
|
||||||
|
|||||||
@@ -148,6 +148,44 @@ JsonNode TimesStackSizeUpdater::toJsonNode() const
|
|||||||
return JsonNode("TIMES_STACK_SIZE");
|
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
|
std::shared_ptr<Bonus> TimesStackLevelUpdater::apply(const std::shared_ptr<Bonus> & b, int level) const
|
||||||
{
|
{
|
||||||
auto newBonus = std::make_shared<Bonus>(*b);
|
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
|
class DLL_LINKAGE TimesStackLevelUpdater : public IUpdater
|
||||||
{
|
{
|
||||||
std::shared_ptr<Bonus> apply(const std::shared_ptr<Bonus> & b, int level) const;
|
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));
|
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
|
else
|
||||||
logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
|
logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -298,6 +298,8 @@ void registerTypes(Serializer &s)
|
|||||||
s.template registerType<DivideStackLevelUpdater>(246);
|
s.template registerType<DivideStackLevelUpdater>(246);
|
||||||
s.template registerType<SetHeroExperience>(247);
|
s.template registerType<SetHeroExperience>(247);
|
||||||
s.template registerType<GiveStackExperience>(248);
|
s.template registerType<GiveStackExperience>(248);
|
||||||
|
s.template registerType<TimesStackSizeUpdater>(249);
|
||||||
|
s.template registerType<TimesArmySizeUpdater>(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
Reference in New Issue
Block a user