Cache ICrushable traits in actor.
This commit is contained in:
@@ -72,6 +72,7 @@ namespace OpenRA
|
|||||||
public IOccupySpace OccupiesSpace { get; }
|
public IOccupySpace OccupiesSpace { get; }
|
||||||
public ITargetable[] Targetables { get; }
|
public ITargetable[] Targetables { get; }
|
||||||
public IEnumerable<ITargetablePositions> EnabledTargetablePositions { get; }
|
public IEnumerable<ITargetablePositions> EnabledTargetablePositions { get; }
|
||||||
|
public ICrushable[] Crushables { get; }
|
||||||
|
|
||||||
public bool IsIdle => CurrentActivity == null;
|
public bool IsIdle => CurrentActivity == null;
|
||||||
public bool IsDead => Disposed || (health != null && health.IsDead);
|
public bool IsDead => Disposed || (health != null && health.IsDead);
|
||||||
@@ -155,6 +156,7 @@ namespace OpenRA
|
|||||||
var targetablesList = new List<ITargetable>();
|
var targetablesList = new List<ITargetable>();
|
||||||
var targetablePositionsList = new List<ITargetablePositions>();
|
var targetablePositionsList = new List<ITargetablePositions>();
|
||||||
var syncHashesList = new List<SyncHash>();
|
var syncHashesList = new List<SyncHash>();
|
||||||
|
var crushablesList = new List<ICrushable>();
|
||||||
|
|
||||||
foreach (var traitInfo in Info.TraitsInConstructOrder())
|
foreach (var traitInfo in Info.TraitsInConstructOrder())
|
||||||
{
|
{
|
||||||
@@ -181,6 +183,7 @@ namespace OpenRA
|
|||||||
{ if (trait is ITargetable t) targetablesList.Add(t); }
|
{ if (trait is ITargetable t) targetablesList.Add(t); }
|
||||||
{ if (trait is ITargetablePositions t) targetablePositionsList.Add(t); }
|
{ if (trait is ITargetablePositions t) targetablePositionsList.Add(t); }
|
||||||
{ if (trait is ISync t) syncHashesList.Add(new SyncHash(t)); }
|
{ if (trait is ISync t) syncHashesList.Add(new SyncHash(t)); }
|
||||||
|
{ if (trait is ICrushable t) crushablesList.Add(t); }
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveOrders = resolveOrdersList.ToArray();
|
resolveOrders = resolveOrdersList.ToArray();
|
||||||
@@ -195,6 +198,7 @@ namespace OpenRA
|
|||||||
EnabledTargetablePositions = targetablePositions.Where(Exts.IsTraitEnabled);
|
EnabledTargetablePositions = targetablePositions.Where(Exts.IsTraitEnabled);
|
||||||
enabledTargetableWorldPositions = EnabledTargetablePositions.SelectMany(tp => tp.TargetablePositions(this));
|
enabledTargetableWorldPositions = EnabledTargetablePositions.SelectMany(tp => tp.TargetablePositions(this));
|
||||||
SyncHashes = syncHashesList.ToArray();
|
SyncHashes = syncHashesList.ToArray();
|
||||||
|
Crushables = crushablesList.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -649,4 +649,14 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
void PlayerDisconnected(Actor self, Player p);
|
void PlayerDisconnected(Actor self, Player p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -657,8 +657,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
|||||||
if (isTemporaryBlocker)
|
if (isTemporaryBlocker)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var crushables = actor.TraitsImplementing<ICrushable>();
|
foreach (var crushable in actor.Crushables)
|
||||||
foreach (var crushable in crushables)
|
|
||||||
if (world.NoPlayersMask != crushable.CrushableBy(actor, locomotor.Info.Crushes))
|
if (world.NoPlayersMask != crushable.CrushableBy(actor, locomotor.Info.Crushes))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -713,8 +713,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
// If the other actor in our way cannot be crushed, we are blocked.
|
// If the other actor in our way cannot be crushed, we are blocked.
|
||||||
// PERF: Avoid LINQ.
|
// PERF: Avoid LINQ.
|
||||||
var crushables = otherActor.TraitsImplementing<ICrushable>();
|
foreach (var crushable in otherActor.Crushables)
|
||||||
foreach (var crushable in crushables)
|
|
||||||
if (crushable.CrushableBy(otherActor, self, Info.Crushes))
|
if (crushable.CrushableBy(otherActor, self, Info.Crushes))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -857,7 +856,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
|
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
|
||||||
{
|
{
|
||||||
var crushables = self.World.ActorMap.GetActorsAt(TopLeft).Where(a => a != self)
|
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
|
// Only crush actors that are on the ground level
|
||||||
foreach (var crushable in crushables)
|
foreach (var crushable in crushables)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (target.TraitsImplementing<Cloak>().Any(c => !c.IsTraitDisabled && !c.IsVisible(target, self.Owner)))
|
if (target.TraitsImplementing<Cloak>().Any(c => !c.IsTraitDisabled && !c.IsVisible(target, self.Owner)))
|
||||||
return false;
|
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)
|
protected override void TraitEnabled(Actor self)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var crushables = self.World.ActorMap.GetActorsAt(self.World.Map.CellContaining(position)).Where(a => a != self)
|
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.
|
// Only crush actors that are on the ground level.
|
||||||
foreach (var crushable in crushables)
|
foreach (var crushable in crushables)
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
|
void CrushAction(Actor self, Func<INotifyCrushed, Action<Actor, Actor, BitSet<CrushClass>>> action)
|
||||||
{
|
{
|
||||||
var crushables = self.World.ActorMap.GetActorsAt(ToCell, ToSubCell).Where(a => a != self)
|
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
|
// Only crush actors that are on the ground level
|
||||||
foreach (var crushable in crushables)
|
foreach (var crushable in crushables)
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
// If the other actor in our way cannot be crushed, we are blocked.
|
// If the other actor in our way cannot be crushed, we are blocked.
|
||||||
// PERF: Avoid LINQ.
|
// PERF: Avoid LINQ.
|
||||||
var crushables = otherActor.TraitsImplementing<ICrushable>();
|
var crushables = otherActor.Crushables;
|
||||||
foreach (var crushable in crushables)
|
foreach (var crushable in crushables)
|
||||||
if (crushable.CrushableBy(otherActor, actor, Info.Crushes))
|
if (crushable.CrushableBy(otherActor, actor, Info.Crushes))
|
||||||
return false;
|
return false;
|
||||||
@@ -493,7 +493,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var actorImmovablePlayers = world.AllPlayersMask;
|
var actorImmovablePlayers = world.AllPlayersMask;
|
||||||
var actorCrushablePlayers = world.NoPlayersMask;
|
var actorCrushablePlayers = world.NoPlayersMask;
|
||||||
|
|
||||||
var crushables = actor.TraitsImplementing<ICrushable>();
|
var crushables = actor.Crushables;
|
||||||
var mobile = actor.OccupiesSpace as Mobile;
|
var mobile = actor.OccupiesSpace as Mobile;
|
||||||
var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable;
|
var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable;
|
||||||
var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal);
|
var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal);
|
||||||
|
|||||||
@@ -93,16 +93,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
void Demolish(Actor self, Actor saboteur, int delay, BitSet<DamageType> damageTypes);
|
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]
|
[RequireExplicitImplementation]
|
||||||
public interface INotifyCrushed
|
public interface INotifyCrushed
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user