diff --git a/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs b/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs index 7ce7dc1704..c6c8183bb8 100644 --- a/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs +++ b/OpenRA.Mods.Common/AI/AttackOrFleeFuzzy.cs @@ -198,7 +198,8 @@ namespace OpenRA.Mods.Common.AI if (sumOfMaxHp == 0) return 0.0f; - return (sumOfHp * normalizeByValue) / sumOfMaxHp; + // Cast to long to avoid overflow when multiplying by the health + return (int)((long)sumOfHp * normalizeByValue / sumOfMaxHp); } static float RelativePower(IEnumerable own, IEnumerable enemy) diff --git a/OpenRA.Mods.Common/Activities/CaptureActor.cs b/OpenRA.Mods.Common/Activities/CaptureActor.cs index aa37f629da..91d7295aae 100644 --- a/OpenRA.Mods.Common/Activities/CaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/CaptureActor.cs @@ -58,7 +58,9 @@ namespace OpenRA.Mods.Common.Activities return; var capturesInfo = activeCaptures.Info; - var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP / 100; + + // Cast to long to avoid overflow when multiplying by the health + var lowEnoughHealth = health.HP <= (int)(capturable.Info.CaptureThreshold * (long)health.MaxHP / 100); if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) { var oldOwner = actor.Owner; @@ -80,7 +82,8 @@ namespace OpenRA.Mods.Common.Activities } else { - var damage = health.MaxHP * capturesInfo.SabotageHPRemoval / 100; + // Cast to long to avoid overflow when multiplying by the health + var damage = (int)((long)health.MaxHP * capturesInfo.SabotageHPRemoval / 100); actor.InflictDamage(self, new Damage(damage)); } diff --git a/OpenRA.Mods.Common/Activities/Repair.cs b/OpenRA.Mods.Common/Activities/Repair.cs index 2dd1a6d5da..57e4e86018 100644 --- a/OpenRA.Mods.Common/Activities/Repair.cs +++ b/OpenRA.Mods.Common/Activities/Repair.cs @@ -98,7 +98,9 @@ namespace OpenRA.Mods.Common.Activities { var unitCost = self.Info.TraitInfo().Cost; var hpToRepair = repairsUnits.Info.HpPerStep; - var cost = Math.Max(1, (hpToRepair * unitCost * repairsUnits.Info.ValuePercentage) / (health.MaxHP * 100)); + + // Cast to long to avoid overflow when multiplying by the health + var cost = Math.Max(1, (int)(((long)hpToRepair * unitCost * repairsUnits.Info.ValuePercentage) / (health.MaxHP * 100L))); if (!played) { diff --git a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs index d55484a088..5b51b16713 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/RepairableBuilding.cs @@ -115,7 +115,9 @@ namespace OpenRA.Mods.Common.Traits // The cost is the same regardless of the amount of people repairing var hpToRepair = Math.Min(Info.RepairStep, health.MaxHP - health.HP); - var cost = Math.Max(1, (hpToRepair * Info.RepairPercent * buildingValue) / (health.MaxHP * 100)); + + // Cast to long to avoid overflow when multiplying by the health + var cost = Math.Max(1, (int)(((long)hpToRepair * Info.RepairPercent * buildingValue) / (health.MaxHP * 100L))); // TakeCash will return false if the player can't pay, and will stop him from contributing this Tick var activePlayers = Repairers.Count(player => player.PlayerActor.Trait().TakeCash(cost, true)); diff --git a/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs b/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs index 3e3992801c..5cfb048aa7 100644 --- a/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs +++ b/OpenRA.Mods.Common/Traits/DamagedByTerrain.cs @@ -69,7 +69,8 @@ namespace OpenRA.Mods.Common.Traits if (totalTiles == 0) return; - damageThreshold = (Info.DamageThreshold * health.MaxHP + (100 - Info.DamageThreshold) * safeTiles * health.MaxHP / totalTiles) / 100; + // Cast to long to avoid overflow when multiplying by the health + damageThreshold = (int)((Info.DamageThreshold * (long)health.MaxHP + (100 - Info.DamageThreshold) * safeTiles * (long)health.MaxHP / totalTiles) / 100); // Actors start with maximum damage applied var delta = health.HP - damageThreshold; diff --git a/OpenRA.Mods.Common/Traits/Health.cs b/OpenRA.Mods.Common/Traits/Health.cs index 44097467f4..96491bc8b4 100644 --- a/OpenRA.Mods.Common/Traits/Health.cs +++ b/OpenRA.Mods.Common/Traits/Health.cs @@ -43,7 +43,8 @@ namespace OpenRA.Mods.Common.Traits Info = info; MaxHP = info.HP > 0 ? info.HP : 1; - hp = init.Contains() ? init.Get() * MaxHP / 100 : MaxHP; + // Cast to long to avoid overflow when multiplying by the health + hp = init.Contains() ? (int)(init.Get() * (long)MaxHP / 100) : MaxHP; DisplayHP = hp; }