diff --git a/Global.h b/Global.h index a1f469eb6..ade90503c 100644 --- a/Global.h +++ b/Global.h @@ -712,13 +712,16 @@ namespace vstd return a + (b - a) * f; } - /// Divides dividend by divisor and rounds result up + /// Divides dividend by divisor and rounds result away from zero /// For use with integer-only arithmetic template Integer1 divideAndCeil(const Integer1 & dividend, const Integer2 & divisor) { static_assert(std::is_integral_v && std::is_integral_v, "This function should only be used with integral types"); - return (dividend + divisor - 1) / divisor; + if (dividend >= 0) + return (dividend + divisor - 1) / divisor; + else + return (dividend - divisor + 1) / divisor; } /// Divides dividend by divisor and rounds result to nearest @@ -727,10 +730,13 @@ namespace vstd Integer1 divideAndRound(const Integer1 & dividend, const Integer2 & divisor) { static_assert(std::is_integral_v && std::is_integral_v, "This function should only be used with integral types"); - return (dividend + divisor / 2 - 1) / divisor; + if (dividend >= 0) + return (dividend + divisor / 2 - 1) / divisor; + else + return (dividend - divisor / 2 + 1) / divisor; } - /// Divides dividend by divisor and rounds result down + /// Divides dividend by divisor and rounds result towards zero /// For use with integer-only arithmetic template Integer1 divideAndFloor(const Integer1 & dividend, const Integer2 & divisor) diff --git a/docs/modders/Bonus/Bonus_Updaters.md b/docs/modders/Bonus/Bonus_Updaters.md index 19124ae48..9bfd1da29 100644 --- a/docs/modders/Bonus/Bonus_Updaters.md +++ b/docs/modders/Bonus/Bonus_Updaters.md @@ -112,8 +112,9 @@ Example of long form with custom parameters: 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 +- `maximum`: 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 diff --git a/lib/bonuses/BonusList.cpp b/lib/bonuses/BonusList.cpp index c1b45610c..092a5a41d 100644 --- a/lib/bonuses/BonusList.cpp +++ b/lib/bonuses/BonusList.cpp @@ -70,7 +70,10 @@ int BonusList::totalValue(int baseValue) const }; auto applyPercentageRoundUp = [](int base, int percent) -> int { - return (static_cast(base) * (100 + percent) + 99) / 100; + if (base >= 0) + return (static_cast(base) * (100 + percent) + 99) / 100; + else + return (static_cast(base) * (100 + percent) - 99) / 100; }; auto applyPercentageRoundDown = [](int base, int percent) -> int { diff --git a/lib/bonuses/Updaters.h b/lib/bonuses/Updaters.h index f764850fe..4a023eecd 100644 --- a/lib/bonuses/Updaters.h +++ b/lib/bonuses/Updaters.h @@ -134,6 +134,9 @@ public: h & minimum; h & maximum; h & stepSize; + h & filteredLevel; + h & filteredCreature; + h & filteredFaction; } };