Cache ICrushable traits in actor.

This commit is contained in:
Vapre
2023-12-17 17:57:57 +01:00
committed by Gustas
parent 6026d088c8
commit 64cdfcbeab
10 changed files with 23 additions and 20 deletions

View File

@@ -657,8 +657,7 @@ namespace OpenRA.Mods.Common.Pathfinder
if (isTemporaryBlocker)
return false;
var crushables = actor.TraitsImplementing<ICrushable>();
foreach (var crushable in crushables)
foreach (var crushable in actor.Crushables)
if (world.NoPlayersMask != crushable.CrushableBy(actor, locomotor.Info.Crushes))
return false;

View File

@@ -713,8 +713,7 @@ namespace OpenRA.Mods.Common.Traits
// If the other actor in our way cannot be crushed, we are blocked.
// PERF: Avoid LINQ.
var crushables = otherActor.TraitsImplementing<ICrushable>();
foreach (var crushable in crushables)
foreach (var crushable in otherActor.Crushables)
if (crushable.CrushableBy(otherActor, self, Info.Crushes))
return false;
@@ -857,7 +856,7 @@ namespace OpenRA.Mods.Common.Traits
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
{
var crushables = self.World.ActorMap.GetActorsAt(TopLeft).Where(a => a != self)
.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t)));
.SelectMany(a => a.Crushables.Select(t => new TraitPair<ICrushable>(a, t)));
// Only crush actors that are on the ground level
foreach (var crushable in crushables)

View File

@@ -92,7 +92,7 @@ namespace OpenRA.Mods.Common.Traits
if (target.TraitsImplementing<Cloak>().Any(c => !c.IsTraitDisabled && !c.IsVisible(target, self.Owner)))
return false;
return target.TraitsImplementing<ICrushable>().Any(c => c.CrushableBy(target, self, Info.CrushClasses));
return target.Crushables.Any(c => c.CrushableBy(target, self, Info.CrushClasses));
}
protected override void TraitEnabled(Actor self)

View File

@@ -10,6 +10,7 @@
#endregion
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{

View File

@@ -219,7 +219,7 @@ namespace OpenRA.Mods.Common.Traits
return;
var crushables = self.World.ActorMap.GetActorsAt(self.World.Map.CellContaining(position)).Where(a => a != self)
.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t)));
.SelectMany(a => a.Crushables.Select(t => new TraitPair<ICrushable>(a, t)));
// Only crush actors that are on the ground level.
foreach (var crushable in crushables)

View File

@@ -574,7 +574,7 @@ namespace OpenRA.Mods.Common.Traits
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
{
var crushables = self.World.ActorMap.GetActorsAt(ToCell, ToSubCell).Where(a => a != self)
.SelectMany(a => a.TraitsImplementing<ICrushable>().Select(t => new TraitPair<ICrushable>(a, t)));
.SelectMany(a => a.Crushables.Select(t => new TraitPair<ICrushable>(a, t)));
// Only crush actors that are on the ground level
foreach (var crushable in crushables)

View File

@@ -380,7 +380,7 @@ namespace OpenRA.Mods.Common.Traits
// If the other actor in our way cannot be crushed, we are blocked.
// PERF: Avoid LINQ.
var crushables = otherActor.TraitsImplementing<ICrushable>();
var crushables = otherActor.Crushables;
foreach (var crushable in crushables)
if (crushable.CrushableBy(otherActor, actor, Info.Crushes))
return false;
@@ -493,7 +493,7 @@ namespace OpenRA.Mods.Common.Traits
var actorImmovablePlayers = world.AllPlayersMask;
var actorCrushablePlayers = world.NoPlayersMask;
var crushables = actor.TraitsImplementing<ICrushable>();
var crushables = actor.Crushables;
var mobile = actor.OccupiesSpace as Mobile;
var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable;
var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal);

View File

@@ -93,16 +93,6 @@ namespace OpenRA.Mods.Common.Traits
void Demolish(Actor self, Actor saboteur, int delay, BitSet<DamageType> damageTypes);
}
// Type tag for crush class bits
public class CrushClass { }
[RequireExplicitImplementation]
public interface ICrushable
{
bool CrushableBy(Actor self, Actor crusher, BitSet<CrushClass> crushClasses);
LongBitSet<PlayerBitMask> CrushableBy(Actor self, BitSet<CrushClass> crushClasses);
}
[RequireExplicitImplementation]
public interface INotifyCrushed
{