mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fix handling of bonuses with negative values
This commit is contained in:
		
							
								
								
									
										14
									
								
								Global.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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<typename Integer1, typename Integer2> | ||||
| 	Integer1 divideAndCeil(const Integer1 & dividend, const Integer2 & divisor) | ||||
| 	{ | ||||
| 		static_assert(std::is_integral_v<Integer1> && std::is_integral_v<Integer2>, "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<Integer1> && std::is_integral_v<Integer2>, "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<typename Integer1, typename Integer2> | ||||
| 	Integer1 divideAndFloor(const Integer1 & dividend, const Integer2 & divisor) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -70,7 +70,10 @@ int BonusList::totalValue(int baseValue) const | ||||
| 	}; | ||||
|  | ||||
| 	auto applyPercentageRoundUp = [](int base, int percent) -> int { | ||||
| 		return (static_cast<int64_t>(base) * (100 + percent) + 99) / 100; | ||||
| 		if (base >= 0) | ||||
| 			return (static_cast<int64_t>(base) * (100 + percent) + 99) / 100; | ||||
| 		else | ||||
| 			return (static_cast<int64_t>(base) * (100 + percent) - 99) / 100; | ||||
| 	}; | ||||
|  | ||||
| 	auto applyPercentageRoundDown = [](int base, int percent) -> int { | ||||
|   | ||||
| @@ -134,6 +134,9 @@ public: | ||||
| 		h & minimum; | ||||
| 		h & maximum; | ||||
| 		h & stepSize; | ||||
| 		h & filteredLevel; | ||||
| 		h & filteredCreature; | ||||
| 		h & filteredFaction; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user