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:
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user