Merge pull request #7834 from RoosterDragon/avoid-preventable-allocations
Avoid preventable allocations
This commit is contained in:
@@ -33,6 +33,18 @@ namespace OpenRA.GameRules
|
|||||||
[Desc("Delay in ticks before applying the warhead effect.", "0 = instant (old model).")]
|
[Desc("Delay in ticks before applying the warhead effect.", "0 = instant (old model).")]
|
||||||
public readonly int Delay = 0;
|
public readonly int Delay = 0;
|
||||||
|
|
||||||
|
HashSet<string> validTargetSet;
|
||||||
|
HashSet<string> invalidTargetSet;
|
||||||
|
|
||||||
|
public bool IsValidTarget(IEnumerable<string> targetTypes)
|
||||||
|
{
|
||||||
|
if (validTargetSet == null)
|
||||||
|
validTargetSet = new HashSet<string>(ValidTargets);
|
||||||
|
if (invalidTargetSet == null)
|
||||||
|
invalidTargetSet = new HashSet<string>(InvalidTargets);
|
||||||
|
return validTargetSet.Overlaps(targetTypes) && !invalidTargetSet.Overlaps(targetTypes);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Applies the warhead's effect against the target.</summary>
|
/// <summary>Applies the warhead's effect against the target.</summary>
|
||||||
public abstract void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers);
|
public abstract void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers);
|
||||||
|
|
||||||
@@ -52,8 +64,7 @@ namespace OpenRA.GameRules
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var cellInfo = world.Map.GetTerrainInfo(cell);
|
var cellInfo = world.Map.GetTerrainInfo(cell);
|
||||||
if (!ValidTargets.Intersect(cellInfo.TargetTypes).Any()
|
if (!IsValidTarget(cellInfo.TargetTypes))
|
||||||
|| InvalidTargets.Intersect(cellInfo.TargetTypes).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -81,8 +92,7 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
// A target type is valid if it is in the valid targets list, and not in the invalid targets list.
|
// A target type is valid if it is in the valid targets list, and not in the invalid targets list.
|
||||||
var targetable = victim.TraitOrDefault<ITargetable>();
|
var targetable = victim.TraitOrDefault<ITargetable>();
|
||||||
if (targetable == null || !ValidTargets.Intersect(targetable.TargetTypes).Any()
|
if (targetable == null || !IsValidTarget(targetable.TargetTypes))
|
||||||
|| InvalidTargets.Intersect(targetable.TargetTypes).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -101,8 +111,7 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
// A target type is valid if it is in the valid targets list, and not in the invalid targets list.
|
// A target type is valid if it is in the valid targets list, and not in the invalid targets list.
|
||||||
var targetable = victim.Info.Traits.GetOrDefault<ITargetableInfo>();
|
var targetable = victim.Info.Traits.GetOrDefault<ITargetableInfo>();
|
||||||
if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any()
|
if (targetable == null || !IsValidTarget(targetable.GetTargetTypes()))
|
||||||
|| InvalidTargets.Intersect(targetable.GetTargetTypes()).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace OpenRA.GameRules
|
|||||||
|
|
||||||
public interface IProjectileInfo { IEffect Create(ProjectileArgs args); }
|
public interface IProjectileInfo { IEffect Create(ProjectileArgs args); }
|
||||||
|
|
||||||
public class WeaponInfo
|
public sealed class WeaponInfo
|
||||||
{
|
{
|
||||||
[Desc("The maximum range the weapon can fire.")]
|
[Desc("The maximum range the weapon can fire.")]
|
||||||
public readonly WRange Range = WRange.Zero;
|
public readonly WRange Range = WRange.Zero;
|
||||||
@@ -64,9 +64,14 @@ namespace OpenRA.GameRules
|
|||||||
[FieldLoader.LoadUsing("LoadWarheads")]
|
[FieldLoader.LoadUsing("LoadWarheads")]
|
||||||
public readonly List<Warhead> Warheads = new List<Warhead>();
|
public readonly List<Warhead> Warheads = new List<Warhead>();
|
||||||
|
|
||||||
|
readonly HashSet<string> validTargetSet;
|
||||||
|
readonly HashSet<string> invalidTargetSet;
|
||||||
|
|
||||||
public WeaponInfo(string name, MiniYaml content)
|
public WeaponInfo(string name, MiniYaml content)
|
||||||
{
|
{
|
||||||
FieldLoader.Load(this, content);
|
FieldLoader.Load(this, content);
|
||||||
|
validTargetSet = new HashSet<string>(ValidTargets);
|
||||||
|
invalidTargetSet = new HashSet<string>(InvalidTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static object LoadProjectile(MiniYaml yaml)
|
static object LoadProjectile(MiniYaml yaml)
|
||||||
@@ -92,6 +97,11 @@ namespace OpenRA.GameRules
|
|||||||
return retList;
|
return retList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsValidTarget(IEnumerable<string> targetTypes)
|
||||||
|
{
|
||||||
|
return validTargetSet.Overlaps(targetTypes) && !invalidTargetSet.Overlaps(targetTypes);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Checks if the weapon is valid against (can target) the target.</summary>
|
/// <summary>Checks if the weapon is valid against (can target) the target.</summary>
|
||||||
public bool IsValidAgainst(Target target, World world, Actor firedBy)
|
public bool IsValidAgainst(Target target, World world, Actor firedBy)
|
||||||
{
|
{
|
||||||
@@ -108,8 +118,7 @@ namespace OpenRA.GameRules
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var cellInfo = world.Map.GetTerrainInfo(cell);
|
var cellInfo = world.Map.GetTerrainInfo(cell);
|
||||||
if (!ValidTargets.Intersect(cellInfo.TargetTypes).Any()
|
if (!IsValidTarget(cellInfo.TargetTypes))
|
||||||
|| InvalidTargets.Intersect(cellInfo.TargetTypes).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -122,8 +131,7 @@ namespace OpenRA.GameRules
|
|||||||
public bool IsValidAgainst(Actor victim, Actor firedBy)
|
public bool IsValidAgainst(Actor victim, Actor firedBy)
|
||||||
{
|
{
|
||||||
var targetable = victim.TraitOrDefault<ITargetable>();
|
var targetable = victim.TraitOrDefault<ITargetable>();
|
||||||
if (targetable == null || !ValidTargets.Intersect(targetable.TargetTypes).Any()
|
if (targetable == null || !IsValidTarget(targetable.TargetTypes))
|
||||||
|| InvalidTargets.Intersect(targetable.TargetTypes).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy)))
|
if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy)))
|
||||||
@@ -136,8 +144,7 @@ namespace OpenRA.GameRules
|
|||||||
public bool IsValidAgainst(FrozenActor victim, Actor firedBy)
|
public bool IsValidAgainst(FrozenActor victim, Actor firedBy)
|
||||||
{
|
{
|
||||||
var targetable = victim.Info.Traits.GetOrDefault<ITargetableInfo>();
|
var targetable = victim.Info.Traits.GetOrDefault<ITargetableInfo>();
|
||||||
if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any()
|
if (targetable == null || !IsValidTarget(targetable.GetTargetTypes()))
|
||||||
|| InvalidTargets.Intersect(targetable.GetTargetTypes()).Any())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy)))
|
if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy)))
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
abstract class AirStateBase : StateBase
|
abstract class AirStateBase : StateBase
|
||||||
{
|
{
|
||||||
|
static readonly string[] AirTargetTypes = new[] { "Air" };
|
||||||
|
|
||||||
protected const int MissileUnitMultiplier = 3;
|
protected const int MissileUnitMultiplier = 3;
|
||||||
|
|
||||||
protected static int CountAntiAirUnits(IEnumerable<Actor> units)
|
protected static int CountAntiAirUnits(IEnumerable<Actor> units)
|
||||||
@@ -34,7 +36,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var arms = unit.TraitsImplementing<Armament>();
|
var arms = unit.TraitsImplementing<Armament>();
|
||||||
foreach (var a in arms)
|
foreach (var a in arms)
|
||||||
{
|
{
|
||||||
if (a.Weapon.ValidTargets.Contains("Air"))
|
if (a.Weapon.IsValidTarget(AirTargetTypes))
|
||||||
{
|
{
|
||||||
missileUnitsCount++;
|
missileUnitsCount++;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
var arms = a.TraitsImplementing<Armament>();
|
var arms = a.TraitsImplementing<Armament>();
|
||||||
foreach (var arm in arms)
|
foreach (var arm in arms)
|
||||||
if (arm.Weapon.ValidTargets.Intersect(targetable.TargetTypes).Any())
|
if (arm.Weapon.IsValidTarget(targetable.TargetTypes))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -34,15 +34,18 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
[Sync]
|
[Sync]
|
||||||
public int RepairersHash { get { return Repairers.Aggregate(0, (code, player) => code ^ Sync.HashPlayer(player)); } }
|
public int RepairersHash { get { return Repairers.Aggregate(0, (code, player) => code ^ Sync.HashPlayer(player)); } }
|
||||||
public List<Player> Repairers = new List<Player>();
|
public readonly List<Player> Repairers = new List<Player>();
|
||||||
|
|
||||||
readonly Health health;
|
readonly Health health;
|
||||||
public bool RepairActive = false;
|
public bool RepairActive = false;
|
||||||
|
|
||||||
|
readonly Predicate<Player> isNotActiveAlly;
|
||||||
|
|
||||||
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
|
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
|
||||||
: base(info)
|
: base(info)
|
||||||
{
|
{
|
||||||
health = self.Trait<Health>();
|
health = self.Trait<Health>();
|
||||||
|
isNotActiveAlly = player => player.WinState != WinState.Undefined || player.Stances[self.Owner] != Stance.Ally;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RepairBuilding(Actor self, Player player)
|
public void RepairBuilding(Actor self, Player player)
|
||||||
@@ -81,8 +84,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
if (remainingTicks == 0)
|
if (remainingTicks == 0)
|
||||||
{
|
{
|
||||||
Repairers = Repairers.Where(player => player.WinState == WinState.Undefined
|
Repairers.RemoveAll(isNotActiveAlly);
|
||||||
&& player.Stances[self.Owner] == Stance.Ally).ToList();
|
|
||||||
|
|
||||||
// If after the previous operation there's no repairers left, stop
|
// If after the previous operation there's no repairers left, stop
|
||||||
if (!Repairers.Any()) return;
|
if (!Repairers.Any()) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user