Skip check for ITemporaryBlocker entirely if rules don't contain any temporary blockers

This benefits all mods without temporary blockers like gates or energy walls.
This commit is contained in:
reaperrr
2018-04-30 09:26:38 +02:00
committed by abcdefg30
parent 2a4299906d
commit 3c34330925
6 changed files with 19 additions and 6 deletions

View File

@@ -299,6 +299,8 @@ namespace OpenRA.Traits
void SetVisualPosition(Actor self, WPos pos); void SetVisualPosition(Actor self, WPos pos);
} }
public interface ITemporaryBlockerInfo : ITraitInfoInterface { }
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface ITemporaryBlocker public interface ITemporaryBlocker
{ {

View File

@@ -149,6 +149,8 @@ namespace OpenRA
} }
} }
public bool RulesContainTemporaryBlocker { get; private set; }
internal World(ModData modData, Map map, OrderManager orderManager, WorldType type) internal World(ModData modData, Map map, OrderManager orderManager, WorldType type)
{ {
Type = type; Type = type;
@@ -185,6 +187,8 @@ namespace OpenRA
MapUid = Map.Uid, MapUid = Map.Uid,
MapTitle = Map.Title MapTitle = Map.Title
}; };
RulesContainTemporaryBlocker = map.Rules.Actors.Any(a => a.Value.HasTraitInfo<ITemporaryBlockerInfo>());
} }
public void AddToMaps(Actor self, IOccupySpace ios) public void AddToMaps(Actor self, IOccupySpace ios)

View File

@@ -45,6 +45,9 @@ namespace OpenRA
public static bool ContainsTemporaryBlocker(this World world, CPos cell, Actor ignoreActor = null) public static bool ContainsTemporaryBlocker(this World world, CPos cell, Actor ignoreActor = null)
{ {
if (!world.RulesContainTemporaryBlocker)
return false;
var temporaryBlockers = world.ActorMap.GetActorsAt(cell); var temporaryBlockers = world.ActorMap.GetActorsAt(cell);
foreach (var temporaryBlocker in temporaryBlockers) foreach (var temporaryBlocker in temporaryBlockers)
{ {

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Cnc.Traits namespace OpenRA.Mods.Cnc.Traits
{ {
[Desc("Will open and be passable for actors that appear friendly when there are no enemies in range.")] [Desc("Will open and be passable for actors that appear friendly when there are no enemies in range.")]
public class EnergyWallInfo : BuildingInfo, IObservesVariablesInfo, IRulesetLoaded public class EnergyWallInfo : BuildingInfo, ITemporaryBlockerInfo, IObservesVariablesInfo, IRulesetLoaded
{ {
[FieldLoader.Require] [FieldLoader.Require]
[WeaponReference] [WeaponReference]

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("Will open and be passable for actors that appear friendly when there are no enemies in range.")] [Desc("Will open and be passable for actors that appear friendly when there are no enemies in range.")]
public class GateInfo : PausableConditionalTraitInfo, IBlocksProjectilesInfo, Requires<BuildingInfo> public class GateInfo : PausableConditionalTraitInfo, ITemporaryBlockerInfo, IBlocksProjectilesInfo, Requires<BuildingInfo>
{ {
public readonly string OpeningSound = null; public readonly string OpeningSound = null;
public readonly string ClosingSound = null; public readonly string ClosingSound = null;

View File

@@ -268,10 +268,14 @@ namespace OpenRA.Mods.Common.Traits
IsMovingInMyDirection(self, otherActor)) IsMovingInMyDirection(self, otherActor))
return false; return false;
// If there is a temporary blocker in our path, but we can remove it, we are not blocked. // PERF: Only perform ITemporaryBlocker trait look-up if mod/map rules contain any actors that are temporary blockers
var temporaryBlocker = otherActor.TraitOrDefault<ITemporaryBlocker>(); if (self.World.RulesContainTemporaryBlocker)
if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, self)) {
return false; // If there is a temporary blocker in our path, but we can remove it, we are not blocked.
var temporaryBlocker = otherActor.TraitOrDefault<ITemporaryBlocker>();
if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, self))
return false;
}
// If we cannot crush the other actor in our way, we are blocked. // If we cannot crush the other actor in our way, we are blocked.
if (Crushes == null || Crushes.Count == 0) if (Crushes == null || Crushes.Count == 0)