Add ActorInfo.HasTraitInfo<T>() requiring ITraitInfo types
This commit is contained in:
@@ -183,5 +183,7 @@ namespace OpenRA
|
||||
i => Pair.New(
|
||||
i.Name.Replace("Init", ""), i));
|
||||
}
|
||||
|
||||
public bool HasTraitInfo<T>() where T : ITraitInfo { return Traits.Contains<T>(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace OpenRA.Graphics
|
||||
if (World.Type == WorldType.Regular && Game.Settings.Game.AlwaysShowStatusBars)
|
||||
{
|
||||
foreach (var g in World.Actors.Where(a => !a.Disposed
|
||||
&& a.Info.Traits.Contains<SelectableInfo>()
|
||||
&& a.Info.HasTraitInfo<SelectableInfo>()
|
||||
&& !World.FogObscures(a)
|
||||
&& !World.Selection.Actors.Contains(a)))
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
public void DrawRollover(Actor unit)
|
||||
{
|
||||
if (unit.Info.Traits.Contains<SelectableInfo>())
|
||||
if (unit.Info.HasTraitInfo<SelectableInfo>())
|
||||
new SelectionBarsRenderable(unit).Render(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Orders
|
||||
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
||||
{
|
||||
var underCursor = world.ScreenMap.ActorsAt(mi)
|
||||
.Where(a => !world.FogObscures(a) && a.Info.Traits.Contains<ITargetableInfo>())
|
||||
.Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo<ITargetableInfo>())
|
||||
.WithHighestSelectionPriority();
|
||||
|
||||
Target target;
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Orders
|
||||
else
|
||||
{
|
||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.WithHighestSelectionPriority();
|
||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||
}
|
||||
@@ -58,12 +58,12 @@ namespace OpenRA.Orders
|
||||
{
|
||||
var useSelect = false;
|
||||
var underCursor = world.ScreenMap.ActorsAt(mi)
|
||||
.Where(a => !world.FogObscures(a) && a.Info.Traits.Contains<ITargetableInfo>())
|
||||
.Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo<ITargetableInfo>())
|
||||
.WithHighestSelectionPriority();
|
||||
|
||||
if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()))
|
||||
{
|
||||
if (underCursor.Info.Traits.Contains<SelectableInfo>())
|
||||
if (underCursor.Info.HasTraitInfo<SelectableInfo>())
|
||||
useSelect = true;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenRA.Orders
|
||||
else
|
||||
{
|
||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
||||
.Where(a => a.Info.Traits.Contains<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.Where(a => a.Info.HasTraitInfo<ITargetableInfo>() && !a.Footprint.All(world.ShroudObscures))
|
||||
.WithHighestSelectionPriority();
|
||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
if (!hasBox && World.Selection.Actors.Any() && !multiClick)
|
||||
{
|
||||
if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.Info.Traits.Contains<SelectableInfo>() &&
|
||||
if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.Info.HasTraitInfo<SelectableInfo>() &&
|
||||
(x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) &&
|
||||
!mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
|
||||
{
|
||||
@@ -301,7 +301,7 @@ namespace OpenRA.Widgets
|
||||
a = b;
|
||||
|
||||
return world.ScreenMap.ActorsInBox(a, b)
|
||||
.Where(x => x.Info.Traits.Contains<SelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
||||
.Where(x => x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
||||
.SubsetWithHighestSelectionPriority();
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
var sumOfHp = 0;
|
||||
foreach (var a in actors)
|
||||
{
|
||||
if (a.Info.Traits.Contains<HealthInfo>())
|
||||
if (a.Info.HasTraitInfo<HealthInfo>())
|
||||
{
|
||||
sumOfMaxHp += a.Trait<Health>().MaxHP;
|
||||
sumOfHp += a.Trait<Health>().HP;
|
||||
@@ -228,7 +228,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var sum = 0;
|
||||
foreach (var a in actors)
|
||||
if (a.Info.Traits.Contains<TTraitInfo>())
|
||||
if (a.Info.HasTraitInfo<TTraitInfo>())
|
||||
sum += getValue(a);
|
||||
|
||||
return sum;
|
||||
@@ -240,7 +240,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
var countActors = 0;
|
||||
foreach (var a in actors)
|
||||
{
|
||||
if (a.Info.Traits.Contains<TTraitInfo>())
|
||||
if (a.Info.HasTraitInfo<TTraitInfo>())
|
||||
{
|
||||
sum += getValue(a);
|
||||
countActors++;
|
||||
|
||||
@@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var randomBaseBuilding = World.Actors.Where(
|
||||
a => a.Owner == Player
|
||||
&& a.Info.Traits.Contains<BaseBuildingInfo>()
|
||||
&& !a.Info.Traits.Contains<MobileInfo>())
|
||||
&& a.Info.HasTraitInfo<BaseBuildingInfo>()
|
||||
&& !a.Info.HasTraitInfo<MobileInfo>())
|
||||
.RandomOrDefault(Random);
|
||||
|
||||
return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter;
|
||||
@@ -233,8 +233,8 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
isEnemyUnit = unit =>
|
||||
Player.Stances[unit.Owner] == Stance.Enemy
|
||||
&& !unit.Info.Traits.Contains<HuskInfo>()
|
||||
&& unit.Info.Traits.Contains<ITargetableInfo>();
|
||||
&& !unit.Info.HasTraitInfo<HuskInfo>()
|
||||
&& unit.Info.HasTraitInfo<ITargetableInfo>();
|
||||
|
||||
foreach (var decision in info.PowerDecisions)
|
||||
powerDecisions.Add(decision.OrderName, decision);
|
||||
@@ -281,8 +281,8 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var baseProviders = World.Actors.Where(
|
||||
a => a.Owner == Player
|
||||
&& a.Info.Traits.Contains<BaseProviderInfo>()
|
||||
&& !a.Info.Traits.Contains<MobileInfo>());
|
||||
&& a.Info.HasTraitInfo<BaseProviderInfo>()
|
||||
&& !a.Info.HasTraitInfo<MobileInfo>());
|
||||
|
||||
foreach (var b in baseProviders)
|
||||
{
|
||||
@@ -308,8 +308,8 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var areaProviders = World.Actors.Where(
|
||||
a => a.Owner == Player
|
||||
&& a.Info.Traits.Contains<GivesBuildableAreaInfo>()
|
||||
&& !a.Info.Traits.Contains<MobileInfo>());
|
||||
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>()
|
||||
&& !a.Info.HasTraitInfo<MobileInfo>());
|
||||
|
||||
foreach (var a in areaProviders)
|
||||
{
|
||||
@@ -489,7 +489,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
case BuildingType.Defense:
|
||||
|
||||
// Build near the closest enemy structure
|
||||
var closestEnemy = World.Actors.Where(a => !a.Disposed && a.Info.Traits.Contains<BuildingInfo>() && Player.Stances[a.Owner] == Stance.Enemy)
|
||||
var closestEnemy = World.Actors.Where(a => !a.Disposed && a.Info.HasTraitInfo<BuildingInfo>() && Player.Stances[a.Owner] == Stance.Enemy)
|
||||
.ClosestTo(World.Map.CenterOfCell(defenseCenter));
|
||||
|
||||
var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
|
||||
@@ -565,7 +565,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
// Pick something worth attacking owned by that player
|
||||
var target = World.Actors
|
||||
.Where(a => a.Owner == enemy && a.Info.Traits.Contains<IOccupySpaceInfo>())
|
||||
.Where(a => a.Owner == enemy && a.Info.HasTraitInfo<IOccupySpaceInfo>())
|
||||
.ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter()));
|
||||
|
||||
if (target == null)
|
||||
@@ -597,7 +597,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
List<Actor> FindEnemyConstructionYards()
|
||||
{
|
||||
return World.Actors.Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead
|
||||
&& a.Info.Traits.Contains<BaseBuildingInfo>() && !a.Info.Traits.Contains<MobileInfo>()).ToList();
|
||||
&& a.Info.HasTraitInfo<BaseBuildingInfo>() && !a.Info.HasTraitInfo<MobileInfo>()).ToList();
|
||||
}
|
||||
|
||||
void CleanSquads()
|
||||
@@ -707,18 +707,18 @@ namespace OpenRA.Mods.Common.AI
|
||||
void FindNewUnits(Actor self)
|
||||
{
|
||||
var newUnits = self.World.ActorsWithTrait<IPositionable>()
|
||||
.Where(a => a.Actor.Owner == Player && !a.Actor.Info.Traits.Contains<BaseBuildingInfo>()
|
||||
.Where(a => a.Actor.Owner == Player && !a.Actor.Info.HasTraitInfo<BaseBuildingInfo>()
|
||||
&& !activeUnits.Contains(a.Actor))
|
||||
.Select(a => a.Actor);
|
||||
|
||||
foreach (var a in newUnits)
|
||||
{
|
||||
if (a.Info.Traits.Contains<HarvesterInfo>())
|
||||
if (a.Info.HasTraitInfo<HarvesterInfo>())
|
||||
QueueOrder(new Order("Harvest", a, false));
|
||||
else
|
||||
unitsHangingAroundTheBase.Add(a);
|
||||
|
||||
if (a.Info.Traits.Contains<AircraftInfo>() && a.Info.Traits.Contains<AttackBaseInfo>())
|
||||
if (a.Info.HasTraitInfo<AircraftInfo>() && a.Info.HasTraitInfo<AttackBaseInfo>())
|
||||
{
|
||||
var air = GetSquadOfType(SquadType.Air);
|
||||
if (air == null)
|
||||
@@ -742,7 +742,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
var attackForce = RegisterNewSquad(SquadType.Assault);
|
||||
|
||||
foreach (var a in unitsHangingAroundTheBase)
|
||||
if (!a.Info.Traits.Contains<AircraftInfo>())
|
||||
if (!a.Info.HasTraitInfo<AircraftInfo>())
|
||||
attackForce.Units.Add(a);
|
||||
|
||||
unitsHangingAroundTheBase.Clear();
|
||||
@@ -753,7 +753,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var allEnemyBaseBuilder = FindEnemyConstructionYards();
|
||||
var ownUnits = activeUnits
|
||||
.Where(unit => unit.Info.Traits.Contains<AttackBaseInfo>() && !unit.Info.Traits.Contains<AircraftInfo>() && unit.IsIdle).ToList();
|
||||
.Where(unit => unit.Info.HasTraitInfo<AttackBaseInfo>() && !unit.Info.HasTraitInfo<AircraftInfo>() && unit.IsIdle).ToList();
|
||||
|
||||
if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize))
|
||||
return;
|
||||
@@ -761,7 +761,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
foreach (var b in allEnemyBaseBuilder)
|
||||
{
|
||||
var enemies = World.FindActorsInCircle(b.CenterPosition, WDist.FromCells(Info.RushAttackScanRadius))
|
||||
.Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.Traits.Contains<AttackBaseInfo>()).ToList();
|
||||
.Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo<AttackBaseInfo>()).ToList();
|
||||
|
||||
if (rushFuzzy.CanAttack(ownUnits, enemies))
|
||||
{
|
||||
@@ -790,8 +790,8 @@ namespace OpenRA.Mods.Common.AI
|
||||
if (!protectSq.IsValid)
|
||||
{
|
||||
var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(GetRandomBaseCenter()), WDist.FromCells(Info.ProtectUnitScanRadius))
|
||||
.Where(unit => unit.Owner == Player && !unit.Info.Traits.Contains<BuildingInfo>()
|
||||
&& unit.Info.Traits.Contains<AttackBaseInfo>());
|
||||
.Where(unit => unit.Owner == Player && !unit.Info.HasTraitInfo<BuildingInfo>()
|
||||
&& unit.Info.HasTraitInfo<AttackBaseInfo>());
|
||||
|
||||
foreach (var a in ownUnits)
|
||||
protectSq.Units.Add(a);
|
||||
@@ -832,7 +832,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
// Find and deploy our mcv
|
||||
var mcv = self.World.Actors
|
||||
.FirstOrDefault(a => a.Owner == Player && a.Info.Traits.Contains<BaseBuildingInfo>());
|
||||
.FirstOrDefault(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>());
|
||||
|
||||
if (mcv != null)
|
||||
{
|
||||
@@ -841,7 +841,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
// Don't transform the mcv if it is a fact
|
||||
// HACK: This needs to query against MCVs directly
|
||||
if (mcv.Info.Traits.Contains<MobileInfo>())
|
||||
if (mcv.Info.HasTraitInfo<MobileInfo>())
|
||||
QueueOrder(new Order("DeployTransform", mcv, false));
|
||||
}
|
||||
else
|
||||
@@ -854,7 +854,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
// HACK: This needs to query against MCVs directly
|
||||
var mcvs = self.World.Actors
|
||||
.Where(a => a.Owner == Player && a.Info.Traits.Contains<BaseBuildingInfo>() && a.Info.Traits.Contains<MobileInfo>());
|
||||
.Where(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>());
|
||||
if (!mcvs.Any())
|
||||
return;
|
||||
|
||||
@@ -1014,7 +1014,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
// No construction yards - Build a new MCV
|
||||
if (!HasAdequateFact() && !self.World.Actors.Any(a =>
|
||||
a.Owner == Player && a.Info.Traits.Contains<BaseBuildingInfo>() && a.Info.Traits.Contains<MobileInfo>()))
|
||||
a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>()))
|
||||
BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name);
|
||||
|
||||
foreach (var q in Info.UnitQueues)
|
||||
@@ -1073,14 +1073,14 @@ namespace OpenRA.Mods.Common.AI
|
||||
if (e.Attacker.Disposed)
|
||||
return;
|
||||
|
||||
if (!e.Attacker.Info.Traits.Contains<ITargetableInfo>())
|
||||
if (!e.Attacker.Info.HasTraitInfo<ITargetableInfo>())
|
||||
return;
|
||||
|
||||
if (e.Damage > 0)
|
||||
aggro[e.Attacker.Owner].Aggro += e.Damage;
|
||||
|
||||
// Protected harvesters or building
|
||||
if ((self.Info.Traits.Contains<HarvesterInfo>() || self.Info.Traits.Contains<BuildingInfo>()) &&
|
||||
if ((self.Info.HasTraitInfo<HarvesterInfo>() || self.Info.HasTraitInfo<BuildingInfo>()) &&
|
||||
Player.Stances[e.Attacker.Owner] == Stance.Enemy)
|
||||
{
|
||||
defenseCenter = e.Attacker.Location;
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
public bool IsTargetValid
|
||||
{
|
||||
get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.Traits.Contains<HuskInfo>(); }
|
||||
get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.HasTraitInfo<HuskInfo>(); }
|
||||
}
|
||||
|
||||
public bool IsTargetVisible
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
var missileUnitsCount = 0;
|
||||
foreach (var unit in units)
|
||||
{
|
||||
if (unit != null && unit.Info.Traits.Contains<AttackBaseInfo>() && !unit.Info.Traits.Contains<AircraftInfo>()
|
||||
if (unit != null && unit.Info.HasTraitInfo<AttackBaseInfo>() && !unit.Info.HasTraitInfo<AircraftInfo>()
|
||||
&& !unit.IsDisabled())
|
||||
{
|
||||
var arms = unit.TraitsImplementing<Armament>();
|
||||
@@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
continue;
|
||||
}
|
||||
|
||||
if (owner.TargetActor.Info.Traits.Contains<ITargetableInfo>() && CanAttackTarget(a, owner.TargetActor))
|
||||
if (owner.TargetActor.Info.HasTraitInfo<ITargetableInfo>() && CanAttackTarget(a, owner.TargetActor))
|
||||
owner.Bot.QueueOrder(new Order("Attack", a, false) { TargetActor = owner.TargetActor });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
var enemies = owner.World.FindActorsInCircle(leader.CenterPosition, WDist.FromCells(12))
|
||||
.Where(a1 => !a1.Disposed && !a1.IsDead);
|
||||
var enemynearby = enemies.Where(a1 => a1.Info.Traits.Contains<ITargetableInfo>() && leader.Owner.Stances[a1.Owner] == Stance.Enemy);
|
||||
var enemynearby = enemies.Where(a1 => a1.Info.HasTraitInfo<ITargetableInfo>() && leader.Owner.Stances[a1.Owner] == Stance.Enemy);
|
||||
var target = enemynearby.ClosestTo(leader.CenterPosition);
|
||||
if (target != null)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
protected static bool CanAttackTarget(Actor a, Actor target)
|
||||
{
|
||||
if (!a.Info.Traits.Contains<AttackBaseInfo>())
|
||||
if (!a.Info.HasTraitInfo<AttackBaseInfo>())
|
||||
return false;
|
||||
|
||||
var targetTypes = target.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes);
|
||||
@@ -82,11 +82,11 @@ namespace OpenRA.Mods.Common.AI
|
||||
|
||||
var u = squad.Units.Random(squad.Random);
|
||||
var units = squad.World.FindActorsInCircle(u.CenterPosition, WDist.FromCells(DangerRadius)).ToList();
|
||||
var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.Traits.Contains<BuildingInfo>());
|
||||
var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.HasTraitInfo<BuildingInfo>());
|
||||
if (ownBaseBuildingAround.Any())
|
||||
return false;
|
||||
|
||||
var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.Traits.Contains<AttackBaseInfo>());
|
||||
var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo<AttackBaseInfo>());
|
||||
if (!enemyAroundUnit.Any())
|
||||
return false;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
target = value;
|
||||
if (target.Type == TargetType.Actor)
|
||||
canHideUnderFog = target.Actor.Info.Traits.Contains<HiddenUnderFogInfo>();
|
||||
canHideUnderFog = target.Actor.Info.HasTraitInfo<HiddenUnderFogInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
// HACK: This would otherwise break targeting frozen actors
|
||||
// The problem is that Shroud.IsTargetable returns false (as it should) for
|
||||
// frozen actors, but we do want to explicitly target the underlying actor here.
|
||||
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.Traits.Contains<FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor))
|
||||
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor))
|
||||
return NextActivity;
|
||||
|
||||
// Try to move within range
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
var attack = self.Trait<AttackBase>();
|
||||
targets = self.World.Actors.Where(a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self)
|
||||
&& a.Info.Traits.Contains<HuntableInfo>() && IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
|
||||
&& a.Info.HasTraitInfo<HuntableInfo>() && IsTargetable(a, self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
|
||||
}
|
||||
|
||||
bool IsTargetable(Actor self, Actor viewer)
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
target = value;
|
||||
if (target.Type == TargetType.Actor)
|
||||
canHideUnderFog = target.Actor.Info.Traits.Contains<HiddenUnderFogInfo>();
|
||||
canHideUnderFog = target.Actor.Info.HasTraitInfo<HiddenUnderFogInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
// HACK to check if we are on the helipad/airfield/etc.
|
||||
var hostBuilding = self.World.ActorMap.GetUnitsAt(self.Location)
|
||||
.FirstOrDefault(a => a.Info.Traits.Contains<BuildingInfo>());
|
||||
.FirstOrDefault(a => a.Info.HasTraitInfo<BuildingInfo>());
|
||||
|
||||
if (hostBuilding == null || !hostBuilding.IsInWorld)
|
||||
return NextActivity;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common
|
||||
if (self.IsDead)
|
||||
return false;
|
||||
|
||||
if (!self.Info.Traits.Contains<IOccupySpace>())
|
||||
if (!self.Info.HasTraitInfo<IOccupySpaceInfo>())
|
||||
return false;
|
||||
|
||||
if (!self.IsInWorld)
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common
|
||||
if (stance == Stance.Ally)
|
||||
return true;
|
||||
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.Traits.Contains<IgnoresDisguiseInfo>())
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo<IgnoresDisguiseInfo>())
|
||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Ally;
|
||||
|
||||
return stance == Stance.Ally;
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common
|
||||
if (stance == Stance.Ally)
|
||||
return false; /* otherwise, we'll hate friendly disguised spies */
|
||||
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.Traits.Contains<IgnoresDisguiseInfo>())
|
||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo<IgnoresDisguiseInfo>())
|
||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Enemy;
|
||||
|
||||
return stance == Stance.Enemy;
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
var leveluporder = new Order("DevLevelUp", actor, false);
|
||||
leveluporder.ExtraData = (uint)level;
|
||||
|
||||
if (actor.Info.Traits.Contains<GainsExperienceInfo>())
|
||||
if (actor.Info.HasTraitInfo<GainsExperienceInfo>())
|
||||
world.IssueOrder(leveluporder);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,10 +116,10 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var initDict = newActorReference.InitDict;
|
||||
|
||||
if (Actor.Traits.Contains<IFacingInfo>())
|
||||
if (Actor.HasTraitInfo<IFacingInfo>())
|
||||
initDict.Add(new FacingInit(facing));
|
||||
|
||||
if (Actor.Traits.Contains<TurretedInfo>())
|
||||
if (Actor.HasTraitInfo<TurretedInfo>())
|
||||
initDict.Add(new TurretFacingInit(facing));
|
||||
|
||||
editorLayer.Add(newActorReference);
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Effects
|
||||
contrail.Update(pos);
|
||||
|
||||
if (ticks++ >= length || (info.Blockable && world.ActorMap
|
||||
.GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.Info.Traits.Contains<IBlocksProjectilesInfo>())))
|
||||
.GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.Info.HasTraitInfo<IBlocksProjectilesInfo>())))
|
||||
Explode(world);
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Effects
|
||||
var shouldExplode = (pos.Z < 0) // Hit the ground
|
||||
|| (dist.LengthSquared < info.CloseEnough.LengthSquared) // Within range
|
||||
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
||||
|| (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.Info.Traits.Contains<IBlocksProjectilesInfo>())) // Hit a wall or other blocking obstacle
|
||||
|| (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.Info.HasTraitInfo<IBlocksProjectilesInfo>())) // Hit a wall or other blocking obstacle
|
||||
|| !world.Map.Contains(cell) // This also avoids an IndexOutOfRangeException in GetTerrainInfo below.
|
||||
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction))
|
||||
emitError("Invalid faction {0} chosen for player {1}.".F(player.Faction, player.Name));
|
||||
|
||||
if (worldActor.Traits.Contains<MPStartLocationsInfo>())
|
||||
if (worldActor.HasTraitInfo<MPStartLocationsInfo>())
|
||||
{
|
||||
var multiPlayers = players.Count(p => p.Value.Playable);
|
||||
var spawns = map.ActorDefinitions.Where(a => a.Value.Value == "mpspawn");
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
if (!target.Info.Traits.Contains<T>() || !canTarget(target))
|
||||
if (!target.Info.HasTraitInfo<T>() || !canTarget(target))
|
||||
return false;
|
||||
|
||||
cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (world.Map.Rules.Actors[building].Traits.Contains<LineBuildInfo>())
|
||||
if (world.Map.Rules.Actors[building].HasTraitInfo<LineBuildInfo>())
|
||||
orderType = "LineBuild";
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
|
||||
}
|
||||
else if (rules.Actors[building].Traits.Contains<LineBuildInfo>())
|
||||
else if (rules.Actors[building].HasTraitInfo<LineBuildInfo>())
|
||||
{
|
||||
// Linebuild for walls.
|
||||
if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
yield break;
|
||||
|
||||
// Repair a building.
|
||||
if (underCursor.Info.Traits.Contains<RepairableBuildingInfo>())
|
||||
if (underCursor.Info.HasTraitInfo<RepairableBuildingInfo>())
|
||||
yield return new Order("RepairBuilding", world.LocalPlayer.PlayerActor, false) { TargetActor = underCursor };
|
||||
|
||||
// Test for generic Repairable (used on units).
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
if (!target.IsValidFor(Self) || target.Type == TargetType.FrozenActor)
|
||||
Log.Write("lua", "{1} is an invalid target for {0}!", Self, targetActor);
|
||||
|
||||
if (!targetActor.Info.Traits.Contains<FrozenUnderFogInfo>() && !Self.Owner.CanTargetActor(targetActor))
|
||||
if (!targetActor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !Self.Owner.CanTargetActor(targetActor))
|
||||
Log.Write("lua", "{1} is not revealed for player {0}!", Self.Owner, targetActor);
|
||||
|
||||
attackBase.AttackTarget(target, true, allowMove);
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
[Desc("Guard the target actor.")]
|
||||
public void Guard(Actor targetActor)
|
||||
{
|
||||
if (targetActor.Info.Traits.Contains<GuardableInfo>())
|
||||
if (targetActor.Info.HasTraitInfo<GuardableInfo>())
|
||||
guard.GuardTarget(Self, Target.FromActor(targetActor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
public Actor[] GetGroundAttackers()
|
||||
{
|
||||
return Player.World.ActorsWithTrait<AttackBase>().Select(a => a.Actor)
|
||||
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.Traits.Contains<MobileInfo>())
|
||||
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo<MobileInfo>())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
firstTick = false;
|
||||
|
||||
// TODO: Aircraft husks don't properly unreserve.
|
||||
if (self.Info.Traits.Contains<FallsToEarthInfo>())
|
||||
if (self.Info.HasTraitInfo<FallsToEarthInfo>())
|
||||
return;
|
||||
|
||||
ReserveSpawnBuilding();
|
||||
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return WVec.Zero;
|
||||
|
||||
return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation)
|
||||
.Where(a => !a.IsDead && a.Info.Traits.Contains<AircraftInfo>() && a.Info.Traits.Get<AircraftInfo>().CruiseAltitude == info.CruiseAltitude)
|
||||
.Where(a => !a.IsDead && a.Info.HasTraitInfo<AircraftInfo>() && a.Info.Traits.Get<AircraftInfo>().CruiseAltitude == info.CruiseAltitude)
|
||||
.Select(GetRepulsionForce)
|
||||
.Aggregate(WVec.Zero, (a, b) => a + b);
|
||||
}
|
||||
@@ -191,7 +191,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return null; // not on the ground.
|
||||
|
||||
return self.World.ActorMap.GetUnitsAt(self.Location)
|
||||
.FirstOrDefault(a => a.Info.Traits.Contains<ReservableInfo>());
|
||||
.FirstOrDefault(a => a.Info.HasTraitInfo<ReservableInfo>());
|
||||
}
|
||||
|
||||
protected void ReserveSpawnBuilding()
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public bool IsReachableTarget(Target target, bool allowMove)
|
||||
{
|
||||
return HasAnyValidWeapons(target)
|
||||
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.Traits.Contains<IMoveInfo>()));
|
||||
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.HasTraitInfo<IMoveInfo>()));
|
||||
}
|
||||
|
||||
class AttackOrderTargeter : IOrderTargeter
|
||||
|
||||
@@ -81,8 +81,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var weapon = attack.ChooseArmamentForTarget(target);
|
||||
if (weapon != null)
|
||||
{
|
||||
var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.Info.Traits.Contains<IMoveInfo>())
|
||||
|| (target.Type == TargetType.FrozenActor && target.FrozenActor.Info.Traits.Contains<IMoveInfo>());
|
||||
var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<IMoveInfo>())
|
||||
|| (target.Type == TargetType.FrozenActor && target.FrozenActor.Info.HasTraitInfo<IMoveInfo>());
|
||||
|
||||
// Try and sit at least one cell closer than the max range to give some leeway if the target starts moving.
|
||||
var maxRange = targetIsMobile ? new WDist(Math.Max(weapon.Weapon.MinRange.Length, weapon.Weapon.Range.Length - 1024))
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return inRange
|
||||
.Where(a =>
|
||||
a.AppearsHostileTo(self) &&
|
||||
!a.Info.Traits.Contains<AutoTargetIgnoreInfo>() &&
|
||||
!a.Info.HasTraitInfo<AutoTargetIgnoreInfo>() &&
|
||||
attack.HasAnyValidWeapons(Target.FromActor(a)) &&
|
||||
self.Owner.CanTargetActor(a))
|
||||
.ClosestTo(self);
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// If a sprite actor has neither custom QuantizedFacings nor a trait implementing IQuantizeBodyOrientationInfo, throw
|
||||
if (qboi == null)
|
||||
{
|
||||
if (self.Info.Traits.Contains<ISpriteBodyInfo>())
|
||||
if (self.Info.HasTraitInfo<ISpriteBodyInfo>())
|
||||
throw new InvalidOperationException("Actor '" + self.Info.Name + "' has a sprite body but no facing quantization."
|
||||
+ " Either add the QuantizeFacingsFromSequence trait or set custom QuantizedFacings on BodyOrientation.");
|
||||
else
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
foreach (var c in footprint.Keys)
|
||||
foreach (var a in self.World.ActorMap.GetUnitsAt(c))
|
||||
if (a.Info.Traits.Contains<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c))
|
||||
if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c))
|
||||
a.Kill(self);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,12 +87,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
var unitsAtPos = world.ActorMap.GetUnitsAt(pos).Where(a => a.IsInWorld
|
||||
&& (a.Owner == p || (allyBuildRadius && a.Owner.Stances[p] == Stance.Ally))
|
||||
&& a.Info.Traits.Contains<GivesBuildableAreaInfo>());
|
||||
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>());
|
||||
|
||||
if (unitsAtPos.Any())
|
||||
nearnessCandidates.Add(pos);
|
||||
}
|
||||
else if (buildingAtPos.IsInWorld && buildingAtPos.Info.Traits.Contains<GivesBuildableAreaInfo>()
|
||||
else if (buildingAtPos.IsInWorld && buildingAtPos.Info.HasTraitInfo<GivesBuildableAreaInfo>()
|
||||
&& (buildingAtPos.Owner == p || (allyBuildRadius && buildingAtPos.Owner.Stances[p] == Stance.Ally)))
|
||||
nearnessCandidates.Add(pos);
|
||||
}
|
||||
@@ -164,7 +164,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void Created(Actor self)
|
||||
{
|
||||
if (SkipMakeAnimation || !self.Info.Traits.Contains<WithMakeAnimationInfo>())
|
||||
if (SkipMakeAnimation || !self.Info.HasTraitInfo<WithMakeAnimationInfo>())
|
||||
NotifyBuildingComplete(self);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (csv != null)
|
||||
return csv.Value;
|
||||
|
||||
var cost = a.Traits.Contains<ValuedInfo>() ? a.Traits.Get<ValuedInfo>().Cost : 0;
|
||||
var cost = a.HasTraitInfo<ValuedInfo>() ? a.Traits.Get<ValuedInfo>().Cost : 0;
|
||||
var time = cost
|
||||
* (25 * 60) /* frames per min */
|
||||
/ 1000;
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
if (!target.Info.Traits.Contains<EngineerRepairableInfo>())
|
||||
if (!target.Info.HasTraitInfo<EngineerRepairableInfo>())
|
||||
return false;
|
||||
|
||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
if (!target.Info.Traits.Contains<EngineerRepairableInfo>())
|
||||
if (!target.Info.HasTraitInfo<EngineerRepairableInfo>())
|
||||
return false;
|
||||
|
||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void Tick(World world)
|
||||
{
|
||||
if (subjects.All(s => s.IsDead || !s.Info.Traits.Contains<GuardInfo>()))
|
||||
if (subjects.All(s => s.IsDead || !s.Info.HasTraitInfo<GuardInfo>()))
|
||||
world.CancelInputMode();
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return world.ScreenMap.ActorsAt(mi)
|
||||
.Where(a => !world.FogObscures(a) && !a.IsDead &&
|
||||
a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) &&
|
||||
a.Info.Traits.Contains<GuardableInfo>());
|
||||
a.Info.HasTraitInfo<GuardableInfo>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (self.IsDead)
|
||||
return;
|
||||
|
||||
if (Info.RemoveInstead || !self.Info.Traits.Contains<HealthInfo>())
|
||||
if (Info.RemoveInstead || !self.Info.HasTraitInfo<HealthInfo>())
|
||||
self.Dispose();
|
||||
else
|
||||
self.Kill(self);
|
||||
|
||||
@@ -665,7 +665,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
var cellInfo = notStupidCells
|
||||
.SelectMany(c => self.World.ActorMap.GetUnitsAt(c)
|
||||
.Where(a => a.IsIdle && a.Info.Traits.Contains<MobileInfo>()),
|
||||
.Where(a => a.IsIdle && a.Info.HasTraitInfo<MobileInfo>()),
|
||||
(c, a) => new { Cell = c, Actor = a })
|
||||
.RandomOrDefault(self.World.SharedRandom);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
var building = order.TargetActor;
|
||||
|
||||
if (building.Info.Traits.Contains<RepairableBuildingInfo>())
|
||||
if (building.Info.HasTraitInfo<RepairableBuildingInfo>())
|
||||
if (building.AppearsFriendlyTo(self))
|
||||
building.Trait<RepairableBuilding>().RepairBuilding(building, self.Owner);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
// only track last hit against our base
|
||||
if (!self.Info.Traits.Contains<BuildingInfo>())
|
||||
if (!self.Info.HasTraitInfo<BuildingInfo>())
|
||||
return;
|
||||
|
||||
if (e.Attacker == null)
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
// only track last hit against our harvesters
|
||||
if (!self.Info.Traits.Contains<HarvesterInfo>())
|
||||
if (!self.Info.HasTraitInfo<HarvesterInfo>())
|
||||
return;
|
||||
|
||||
// don't track self-damage
|
||||
|
||||
@@ -107,18 +107,18 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
var attackerStats = e.Attacker.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||
var defenderStats = self.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||
if (self.Info.Traits.Contains<BuildingInfo>())
|
||||
if (self.Info.HasTraitInfo<BuildingInfo>())
|
||||
{
|
||||
attackerStats.BuildingsKilled++;
|
||||
defenderStats.BuildingsDead++;
|
||||
}
|
||||
else if (self.Info.Traits.Contains<IPositionableInfo>())
|
||||
else if (self.Info.HasTraitInfo<IPositionableInfo>())
|
||||
{
|
||||
attackerStats.UnitsKilled++;
|
||||
defenderStats.UnitsDead++;
|
||||
}
|
||||
|
||||
if (self.Info.Traits.Contains<ValuedInfo>())
|
||||
if (self.Info.HasTraitInfo<ValuedInfo>())
|
||||
{
|
||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
attackerStats.KillsCost += cost;
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return self.World.Map.Rules.Actors.Values
|
||||
.Where(x =>
|
||||
x.Name[0] != '^' &&
|
||||
x.Traits.Contains<BuildableInfo>() &&
|
||||
x.HasTraitInfo<BuildableInfo>() &&
|
||||
x.Traits.Get<BuildableInfo>().Queue.Contains(category));
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!bi.Queue.Contains(Info.Type))
|
||||
return; /* Not built by this queue */
|
||||
|
||||
var cost = unit.Traits.Contains<ValuedInfo>() ? unit.Traits.Get<ValuedInfo>().Cost : 0;
|
||||
var cost = unit.HasTraitInfo<ValuedInfo>() ? unit.Traits.Get<ValuedInfo>().Cost : 0;
|
||||
var time = GetBuildTime(order.TargetString);
|
||||
|
||||
if (BuildableItems().All(b => b.Name != order.TargetString))
|
||||
@@ -278,7 +278,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var hasPlayedSound = false;
|
||||
BeginProduction(new ProductionItem(this, order.TargetString, cost, playerPower, () => self.World.AddFrameEndTask(_ =>
|
||||
{
|
||||
var isBuilding = unit.Traits.Contains<BuildingInfo>();
|
||||
var isBuilding = unit.HasTraitInfo<BuildingInfo>();
|
||||
|
||||
if (isBuilding && !hasPlayedSound)
|
||||
hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName);
|
||||
@@ -314,7 +314,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public virtual int GetBuildTime(string unitString)
|
||||
{
|
||||
var unit = self.World.Map.Rules.Actors[unitString];
|
||||
if (unit == null || !unit.Traits.Contains<BuildableInfo>())
|
||||
if (unit == null || !unit.HasTraitInfo<BuildableInfo>())
|
||||
return 0;
|
||||
|
||||
if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait<DeveloperMode>().FastBuild)
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public void ActorChanged(Actor a)
|
||||
{
|
||||
var bi = a.Info.Traits.GetOrDefault<BuildableInfo>();
|
||||
if (a.Owner == player && (a.Info.Traits.Contains<ITechTreePrerequisiteInfo>() || (bi != null && bi.BuildLimit > 0)))
|
||||
if (a.Owner == player && (a.Info.HasTraitInfo<ITechTreePrerequisiteInfo>() || (bi != null && bi.BuildLimit > 0)))
|
||||
Update();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public Production(ActorInitializer init, ProductionInfo info)
|
||||
{
|
||||
Info = info;
|
||||
occupiesSpace = init.Self.Info.Traits.Contains<IOccupySpaceInfo>();
|
||||
occupiesSpace = init.Self.Info.HasTraitInfo<IOccupySpaceInfo>();
|
||||
rp = Exts.Lazy(() => init.Self.IsDead ? null : init.Self.TraitOrDefault<RallyPoint>());
|
||||
Faction = init.Contains<FactionInit>() ? init.Get<FactionInit, string>() : init.Self.Owner.Faction.InternalName;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public Hovers(HoversInfo info, Actor self)
|
||||
{
|
||||
this.info = info;
|
||||
aircraft = self.Info.Traits.Contains<AircraftInfo>();
|
||||
aircraft = self.Info.HasTraitInfo<AircraftInfo>();
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
this.info = info;
|
||||
wsb = self.Trait<WithSpriteBody>();
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>();
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>();
|
||||
}
|
||||
|
||||
public void BuildingComplete(Actor self)
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>(); // always render instantly for units
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
|
||||
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>(); // always render instantly for units
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
|
||||
|
||||
var overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.Play(info.Sequence);
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>(); // always render instantly for units
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
if (info.StartSequence != null)
|
||||
overlay.PlayThen(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.StartSequence),
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>(); // always render instantly for units
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
|
||||
production = self.Info.Traits.Get<ProductionInfo>();
|
||||
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>(); // always render instantly for units
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.Play(info.Sequence);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public AmbientSound(Actor self, AmbientSoundInfo info)
|
||||
{
|
||||
if (self.Info.Traits.Contains<IOccupySpaceInfo>())
|
||||
if (self.Info.HasTraitInfo<IOccupySpaceInfo>())
|
||||
Sound.PlayLooped(info.SoundFile, self.CenterPosition);
|
||||
else
|
||||
Sound.PlayLooped(info.SoundFile);
|
||||
|
||||
@@ -82,12 +82,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
return target.Info.Traits.Contains<AcceptsSuppliesInfo>();
|
||||
return target.Info.HasTraitInfo<AcceptsSuppliesInfo>();
|
||||
}
|
||||
|
||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||
{
|
||||
return target.Info.Traits.Contains<AcceptsSuppliesInfo>();
|
||||
return target.Info.HasTraitInfo<AcceptsSuppliesInfo>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
void ActorRemoved(Actor a)
|
||||
{
|
||||
if (a.Owner != Self.Owner || !a.Info.Traits.Contains<SupportPowerInfo>())
|
||||
if (a.Owner != Self.Owner || !a.Info.HasTraitInfo<SupportPowerInfo>())
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public IEnumerable<SupportPowerInstance> GetPowersForActor(Actor a)
|
||||
{
|
||||
if (a.Owner != Self.Owner || !a.Info.Traits.Contains<SupportPowerInfo>())
|
||||
if (a.Owner != Self.Owner || !a.Info.HasTraitInfo<SupportPowerInfo>())
|
||||
return NoInstances;
|
||||
|
||||
return a.TraitsImplementing<SupportPower>()
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
if (IsTraitDisabled)
|
||||
return false;
|
||||
if (cloak == null || (!viewer.IsDead && viewer.Info.Traits.Contains<IgnoresCloakInfo>()))
|
||||
if (cloak == null || (!viewer.IsDead && viewer.Info.HasTraitInfo<IgnoresCloakInfo>()))
|
||||
return true;
|
||||
|
||||
return cloak.IsVisible(self, viewer.Owner);
|
||||
|
||||
@@ -109,10 +109,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!queued)
|
||||
self.CancelActivity();
|
||||
|
||||
if (self.Info.Traits.Contains<IFacingInfo>())
|
||||
if (self.Info.HasTraitInfo<IFacingInfo>())
|
||||
self.QueueActivity(new Turn(self, info.Facing));
|
||||
|
||||
if (self.Info.Traits.Contains<HelicopterInfo>())
|
||||
if (self.Info.HasTraitInfo<HelicopterInfo>())
|
||||
self.QueueActivity(new HeliLand(self, true));
|
||||
|
||||
foreach (var nt in self.TraitsImplementing<INotifyTransform>())
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
domainIndexes = new Dictionary<uint, MovementClassDomainIndex>();
|
||||
var movementClasses =
|
||||
world.Map.Rules.Actors.Where(ai => ai.Value.Traits.Contains<MobileInfo>())
|
||||
world.Map.Rules.Actors.Where(ai => ai.Value.HasTraitInfo<MobileInfo>())
|
||||
.Select(ai => (uint)ai.Value.Traits.Get<MobileInfo>().GetMovementClass(world.TileSet)).Distinct();
|
||||
|
||||
foreach (var mc in movementClasses)
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public interface INotifyCharging { void Charging(Actor self, Target target); }
|
||||
public interface INotifyChat { bool OnChat(string from, string message); }
|
||||
public interface INotifyParachuteLanded { void OnLanded(); }
|
||||
public interface IRenderActorPreviewInfo { IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init); }
|
||||
public interface ICruiseAltitudeInfo { WDist GetCruiseAltitude(); }
|
||||
public interface IRenderActorPreviewInfo : ITraitInfo { IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init); }
|
||||
public interface ICruiseAltitudeInfo : ITraitInfo { WDist GetCruiseAltitude(); }
|
||||
|
||||
public interface IUpgradable
|
||||
{
|
||||
|
||||
@@ -92,10 +92,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
foreach (var a in actors)
|
||||
{
|
||||
var actor = a;
|
||||
if (actor.Traits.Contains<BridgeInfo>()) // bridge layer takes care about that automatically
|
||||
if (actor.HasTraitInfo<BridgeInfo>()) // bridge layer takes care about that automatically
|
||||
continue;
|
||||
|
||||
if (!actor.Traits.Contains<IRenderActorPreviewInfo>())
|
||||
if (!actor.HasTraitInfo<IRenderActorPreviewInfo>())
|
||||
continue;
|
||||
|
||||
var filter = actor.Traits.GetOrDefault<EditorTilesetFilterInfo>();
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
.Sum(a => a.Info.Traits.WithInterface<ValuedInfo>().First().Cost);
|
||||
|
||||
var harvesters = template.Get<LabelWidget>("HARVESTERS");
|
||||
harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.Info.Traits.Contains<HarvesterInfo>()).ToString();
|
||||
harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead && a.Info.HasTraitInfo<HarvesterInfo>()).ToString();
|
||||
|
||||
return template;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
return ScrollItemWidget.Setup(template, () => false, () =>
|
||||
{
|
||||
var playerBase = world.Actors.FirstOrDefault(a => !a.IsDead && a.Info.Traits.Contains<BaseBuildingInfo>() && a.Owner == player);
|
||||
var playerBase = world.Actors.FirstOrDefault(a => !a.IsDead && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Owner == player);
|
||||
if (playerBase != null)
|
||||
worldRenderer.Viewport.Center(playerBase.CenterPosition);
|
||||
});
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
static string ActorName(Ruleset rules, string a)
|
||||
{
|
||||
ActorInfo ai;
|
||||
if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.Traits.Contains<TooltipInfo>())
|
||||
if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.HasTraitInfo<TooltipInfo>())
|
||||
return ai.Traits.Get<TooltipInfo>().Name;
|
||||
|
||||
return a;
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
var actor = World.Map.Rules.Actors[icon.Name];
|
||||
|
||||
if (item != null && item.Done && actor.Traits.Contains<BuildingInfo>())
|
||||
if (item != null && item.Done && actor.HasTraitInfo<BuildingInfo>())
|
||||
{
|
||||
World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name);
|
||||
return true;
|
||||
|
||||
@@ -198,7 +198,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
// Is added to world.ActorAdded by the SidebarLogic handler
|
||||
public void ActorChanged(Actor a)
|
||||
{
|
||||
if (a.Info.Traits.Contains<ProductionQueueInfo>())
|
||||
if (a.Info.HasTraitInfo<ProductionQueueInfo>())
|
||||
{
|
||||
var allQueues = a.World.ActorsWithTrait<ProductionQueue>()
|
||||
.Where(p => p.Actor.Owner == p.Actor.World.LocalPlayer && p.Actor.IsInWorld && p.Trait.Enabled)
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
}
|
||||
|
||||
var underCursor = world.ScreenMap.ActorsAt(worldRenderer.Viewport.ViewToWorldPx(Viewport.LastMousePos))
|
||||
.Where(a => !world.FogObscures(a) && a.Info.Traits.Contains<ITooltipInfo>())
|
||||
.Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo<ITooltipInfo>())
|
||||
.WithHighestSelectionPriority();
|
||||
|
||||
if (underCursor != null)
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
bool PerformGuard()
|
||||
{
|
||||
var actors = world.Selection.Actors
|
||||
.Where(a => !a.Disposed && a.Owner == world.LocalPlayer && a.Info.Traits.Contains<GuardInfo>());
|
||||
.Where(a => !a.Disposed && a.Owner == world.LocalPlayer && a.Info.HasTraitInfo<GuardInfo>());
|
||||
|
||||
if (actors.Any())
|
||||
world.OrderGenerator = new GuardOrderGenerator(actors);
|
||||
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
var building = world.ActorsWithTrait<Building>()
|
||||
.Select(b => b.Actor)
|
||||
.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.Info.Traits.Contains<SelectableInfo>());
|
||||
.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.Info.HasTraitInfo<SelectableInfo>());
|
||||
|
||||
// No buildings left
|
||||
if (building == null)
|
||||
@@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
bool CycleProductionBuildings()
|
||||
{
|
||||
var facilities = world.ActorsWithTrait<Production>()
|
||||
.Where(a => a.Actor.Owner == world.LocalPlayer && !a.Actor.Info.Traits.Contains<BaseBuildingInfo>())
|
||||
.Where(a => a.Actor.Owner == world.LocalPlayer && !a.Actor.Info.HasTraitInfo<BaseBuildingInfo>())
|
||||
.OrderBy(f => f.Actor.Info.Traits.Get<ProductionInfo>().Produces.First())
|
||||
.Select(b => b.Actor)
|
||||
.ToList();
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace OpenRA.Mods.D2k.Activities
|
||||
actor1.Dispose();
|
||||
|
||||
// Harvester insurance
|
||||
if (!actor1.Info.Traits.Contains<HarvesterInfo>())
|
||||
if (!actor1.Info.HasTraitInfo<HarvesterInfo>())
|
||||
return;
|
||||
|
||||
var insurance = actor1.Owner.PlayerActor.TraitOrDefault<HarvesterInsurance>();
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
{
|
||||
// HACK: Harvesters need special treatment to avoid getting stuck on resource fields,
|
||||
// so if a Harvester's afterLandActivity is not DeliverResources, queue a new FindResources activity
|
||||
var findResources = self.Info.Traits.Contains<HarvesterInfo>() && !(afterLandActivity is DeliverResources);
|
||||
var findResources = self.Info.HasTraitInfo<HarvesterInfo>() && !(afterLandActivity is DeliverResources);
|
||||
if (findResources)
|
||||
self.QueueActivity(new FindResources(self));
|
||||
else
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
var body = self.Trait<BodyOrientation>();
|
||||
|
||||
// always render instantly for units
|
||||
buildComplete = !self.Info.Traits.Contains<BuildingInfo>();
|
||||
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>();
|
||||
|
||||
var overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.Play(info.Sequence);
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
targetCountdown = Info.TargetRescanInterval;
|
||||
|
||||
// If close enough, we don't care about other actors.
|
||||
var target = self.World.FindActorsInCircle(self.CenterPosition, Info.IgnoreNoiseAttackRange).FirstOrDefault(x => x.Info.Traits.Contains<AttractsWormsInfo>());
|
||||
var target = self.World.FindActorsInCircle(self.CenterPosition, Info.IgnoreNoiseAttackRange).FirstOrDefault(x => x.Info.HasTraitInfo<AttractsWormsInfo>());
|
||||
if (target != null)
|
||||
{
|
||||
self.CancelActivity();
|
||||
@@ -109,7 +109,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
|
||||
Func<Actor, bool> isValidTarget = a =>
|
||||
{
|
||||
if (!a.Info.Traits.Contains<AttractsWormsInfo>())
|
||||
if (!a.Info.HasTraitInfo<AttractsWormsInfo>())
|
||||
return false;
|
||||
|
||||
return mobile.CanEnterCell(a.Location, null, false);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
self.Dispose();
|
||||
|
||||
if (target.Info.Traits.Contains<BuildingInfo>())
|
||||
if (target.Info.HasTraitInfo<BuildingInfo>())
|
||||
Sound.PlayToPlayer(self.Owner, "bldginf1.aud");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
public void UnitProducedByOther(Actor self, Actor producer, Actor produced)
|
||||
{
|
||||
// No recursive cloning!
|
||||
if (producer.Owner != self.Owner || producer.Info.Traits.Contains<ClonesProducedUnitsInfo>())
|
||||
if (producer.Owner != self.Owner || producer.Info.HasTraitInfo<ClonesProducedUnitsInfo>())
|
||||
return;
|
||||
|
||||
var ci = produced.Info.Traits.GetOrDefault<CloneableInfo>();
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation)
|
||||
{
|
||||
// TODO: Allow enemy units to be chronoshifted into bad terrain to kill them
|
||||
return self.Info.Traits.Contains<IPositionableInfo>() && self.Trait<IPositionable>().CanEnterCell(targetLocation);
|
||||
return self.Info.HasTraitInfo<IPositionableInfo>() && self.Trait<IPositionable>().CanEnterCell(targetLocation);
|
||||
}
|
||||
|
||||
public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere)
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
public void OnCrush(Actor crusher)
|
||||
{
|
||||
if (crusher.Info.Traits.Contains<MineImmuneInfo>() || (self.Owner.Stances[crusher.Owner] == Stance.Ally && info.AvoidFriendly))
|
||||
if (crusher.Info.HasTraitInfo<MineImmuneInfo>() || (self.Owner.Stances[crusher.Owner] == Stance.Ally && info.AvoidFriendly))
|
||||
return;
|
||||
|
||||
var mobile = crusher.TraitOrDefault<Mobile>();
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
|
||||
var underCursor = world.ScreenMap.ActorsAt(mi)
|
||||
.Where(a => !world.FogObscures(a))
|
||||
.MaxByOrDefault(a => a.Info.Traits.Contains<SelectableInfo>()
|
||||
.MaxByOrDefault(a => a.Info.HasTraitInfo<SelectableInfo>()
|
||||
? a.Info.Traits.Get<SelectableInfo>().Priority : int.MinValue);
|
||||
|
||||
if (mi.Button == Game.Settings.Game.MouseButtonPreference.Action && underCursor == null)
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
foreach (var t in tiles)
|
||||
units.UnionWith(Self.World.ActorMap.GetUnitsAt(t));
|
||||
|
||||
return units.Where(a => a.Info.Traits.Contains<ChronoshiftableInfo>() &&
|
||||
return units.Where(a => a.Info.HasTraitInfo<ChronoshiftableInfo>() &&
|
||||
!a.TraitsImplementing<IPreventsTeleport>().Any(condition => condition.PreventsTeleport(a)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user