Explodes performance optimization
Cache armaments on creation, avoid LINQ. Also merge and put first the DamageThreshold == 0 check in Damaged, because the common default IS 0, so most of the time the IsTraitDisabled and IsInWorld checks are redundant.
This commit is contained in:
@@ -82,6 +82,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
readonly IHealth health;
|
readonly IHealth health;
|
||||||
BuildingInfo buildingInfo;
|
BuildingInfo buildingInfo;
|
||||||
|
Armament[] armaments;
|
||||||
|
|
||||||
|
bool anyArmaments;
|
||||||
|
|
||||||
public Explodes(ExplodesInfo info, Actor self)
|
public Explodes(ExplodesInfo info, Actor self)
|
||||||
: base(info)
|
: base(info)
|
||||||
@@ -92,6 +95,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
protected override void Created(Actor self)
|
protected override void Created(Actor self)
|
||||||
{
|
{
|
||||||
buildingInfo = self.Info.TraitInfoOrDefault<BuildingInfo>();
|
buildingInfo = self.Info.TraitInfoOrDefault<BuildingInfo>();
|
||||||
|
armaments = self.TraitsImplementing<Armament>().ToArray();
|
||||||
|
anyArmaments = armaments.Length > 0;
|
||||||
|
|
||||||
base.Created(self);
|
base.Created(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,13 +106,14 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (IsTraitDisabled || !self.IsInWorld)
|
if (IsTraitDisabled || !self.IsInWorld)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (self.World.SharedRandom.Next(100) > Info.Chance)
|
var sharedRandom = self.World.SharedRandom.Next(100);
|
||||||
|
if (sharedRandom > Info.Chance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
|
if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var weapon = ChooseWeaponForExplosion(self);
|
var weapon = ChooseWeaponForExplosion(self, sharedRandom);
|
||||||
if (weapon == null)
|
if (weapon == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -127,24 +134,24 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
weapon.Impact(Target.FromPos(self.CenterPosition), source);
|
weapon.Impact(Target.FromPos(self.CenterPosition), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponInfo ChooseWeaponForExplosion(Actor self)
|
WeaponInfo ChooseWeaponForExplosion(Actor self, int sharedRandom)
|
||||||
{
|
{
|
||||||
var armaments = self.TraitsImplementing<Armament>();
|
if (!anyArmaments)
|
||||||
if (!armaments.Any())
|
|
||||||
return Info.WeaponInfo;
|
return Info.WeaponInfo;
|
||||||
|
else if (sharedRandom > Info.LoadedChance)
|
||||||
|
return Info.EmptyWeaponInfo;
|
||||||
|
|
||||||
// TODO: EmptyWeapon should be removed in favour of conditions
|
// PERF: Avoid LINQ
|
||||||
var shouldExplode = !armaments.All(a => a.IsReloading);
|
foreach (var a in armaments)
|
||||||
var useFullExplosion = self.World.SharedRandom.Next(100) <= Info.LoadedChance;
|
if (!a.IsReloading)
|
||||||
return (shouldExplode && useFullExplosion) ? Info.WeaponInfo : Info.EmptyWeaponInfo;
|
return Info.WeaponInfo;
|
||||||
|
|
||||||
|
return Info.EmptyWeaponInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyDamage.Damaged(Actor self, AttackInfo e)
|
void INotifyDamage.Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
if (IsTraitDisabled || !self.IsInWorld)
|
if (Info.DamageThreshold == 0 || IsTraitDisabled || !self.IsInWorld)
|
||||||
return;
|
|
||||||
|
|
||||||
if (Info.DamageThreshold == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
|
if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
|
||||||
|
|||||||
Reference in New Issue
Block a user