Merge pull request #9332 from atlimit8/TraitInfoAccess_1
TraitInfo through ActorInfo and HasTrait Removal
This commit is contained in:
@@ -103,7 +103,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
bounds = Exts.Lazy(() =>
|
bounds = Exts.Lazy(() =>
|
||||||
{
|
{
|
||||||
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
var si = Info.TraitInfoOrDefault<SelectableInfo>();
|
||||||
var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
|
var size = (si != null && si.Bounds != null) ? new int2(si.Bounds[0], si.Bounds[1]) :
|
||||||
TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
|
TraitsImplementing<IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault();
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
visualBounds = Exts.Lazy(() =>
|
visualBounds = Exts.Lazy(() =>
|
||||||
{
|
{
|
||||||
var sd = Info.Traits.GetOrDefault<ISelectionDecorationsInfo>();
|
var sd = Info.TraitInfoOrDefault<ISelectionDecorationsInfo>();
|
||||||
if (sd == null || sd.SelectionBoxBounds == null)
|
if (sd == null || sd.SelectionBoxBounds == null)
|
||||||
return bounds.Value;
|
return bounds.Value;
|
||||||
|
|
||||||
@@ -226,11 +226,6 @@ namespace OpenRA
|
|||||||
return World.TraitDict.WithInterface<T>(this);
|
return World.TraitDict.WithInterface<T>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasTrait<T>()
|
|
||||||
{
|
|
||||||
return World.TraitDict.Contains<T>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddTrait(object trait)
|
public void AddTrait(object trait)
|
||||||
{
|
{
|
||||||
World.TraitDict.AddTrait(this, trait);
|
World.TraitDict.AddTrait(this, trait);
|
||||||
|
|||||||
@@ -183,5 +183,9 @@ namespace OpenRA
|
|||||||
i => Pair.New(
|
i => Pair.New(
|
||||||
i.Name.Replace("Init", ""), i));
|
i.Name.Replace("Init", ""), i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasTraitInfo<T>() where T : ITraitInfo { return Traits.Contains<T>(); }
|
||||||
|
public T TraitInfo<T>() where T : ITraitInfo { return Traits.Get<T>(); }
|
||||||
|
public T TraitInfoOrDefault<T>() where T : ITraitInfo { return Traits.GetOrDefault<T>(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ namespace OpenRA.Graphics
|
|||||||
if (World.Type == WorldType.Regular && Game.Settings.Game.AlwaysShowStatusBars)
|
if (World.Type == WorldType.Regular && Game.Settings.Game.AlwaysShowStatusBars)
|
||||||
{
|
{
|
||||||
foreach (var g in World.Actors.Where(a => !a.Disposed
|
foreach (var g in World.Actors.Where(a => !a.Disposed
|
||||||
&& a.HasTrait<Selectable>()
|
&& a.Info.HasTraitInfo<SelectableInfo>()
|
||||||
&& !World.FogObscures(a)
|
&& !World.FogObscures(a)
|
||||||
&& !World.Selection.Actors.Contains(a)))
|
&& !World.Selection.Actors.Contains(a)))
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public void DrawRollover(Actor unit)
|
public void DrawRollover(Actor unit)
|
||||||
{
|
{
|
||||||
if (unit.HasTrait<Selectable>())
|
if (unit.Info.HasTraitInfo<SelectableInfo>())
|
||||||
new SelectionBarsRenderable(unit).Render(this);
|
new SelectionBarsRenderable(unit).Render(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenRA.Orders
|
|||||||
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
public IEnumerable<Order> Order(World world, CPos xy, MouseInput mi)
|
||||||
{
|
{
|
||||||
var underCursor = world.ScreenMap.ActorsAt(mi)
|
var underCursor = world.ScreenMap.ActorsAt(mi)
|
||||||
.Where(a => !world.FogObscures(a) && a.HasTrait<ITargetable>())
|
.Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo<ITargetableInfo>())
|
||||||
.WithHighestSelectionPriority();
|
.WithHighestSelectionPriority();
|
||||||
|
|
||||||
Target target;
|
Target target;
|
||||||
@@ -29,7 +29,7 @@ namespace OpenRA.Orders
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
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();
|
.WithHighestSelectionPriority();
|
||||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||||
}
|
}
|
||||||
@@ -58,12 +58,12 @@ namespace OpenRA.Orders
|
|||||||
{
|
{
|
||||||
var useSelect = false;
|
var useSelect = false;
|
||||||
var underCursor = world.ScreenMap.ActorsAt(mi)
|
var underCursor = world.ScreenMap.ActorsAt(mi)
|
||||||
.Where(a => !world.FogObscures(a) && a.HasTrait<ITargetable>())
|
.Where(a => !world.FogObscures(a) && a.Info.HasTraitInfo<ITargetableInfo>())
|
||||||
.WithHighestSelectionPriority();
|
.WithHighestSelectionPriority();
|
||||||
|
|
||||||
if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()))
|
if (underCursor != null && (mi.Modifiers.HasModifier(Modifiers.Shift) || !world.Selection.Actors.Any()))
|
||||||
{
|
{
|
||||||
if (underCursor.HasTrait<Selectable>())
|
if (underCursor.Info.HasTraitInfo<SelectableInfo>())
|
||||||
useSelect = true;
|
useSelect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ namespace OpenRA.Orders
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var frozen = world.ScreenMap.FrozenActorsAt(world.RenderPlayer, mi)
|
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();
|
.WithHighestSelectionPriority();
|
||||||
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
target = frozen != null ? Target.FromFrozenActor(frozen) : Target.FromCell(world, xy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
public static int SelectionPriority(this ActorInfo a)
|
public static int SelectionPriority(this ActorInfo a)
|
||||||
{
|
{
|
||||||
var selectableInfo = a.Traits.GetOrDefault<SelectableInfo>();
|
var selectableInfo = a.TraitInfoOrDefault<SelectableInfo>();
|
||||||
return selectableInfo != null ? selectableInfo.Priority : int.MinValue;
|
return selectableInfo != null ? selectableInfo.Priority : int.MinValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public static int SelectionPriority(this Actor a)
|
public static int SelectionPriority(this Actor a)
|
||||||
{
|
{
|
||||||
var basePriority = a.Info.Traits.Get<SelectableInfo>().Priority;
|
var basePriority = a.Info.TraitInfo<SelectableInfo>().Priority;
|
||||||
var lp = a.World.LocalPlayer;
|
var lp = a.World.LocalPlayer;
|
||||||
|
|
||||||
if (a.Owner == lp || lp == null)
|
if (a.Owner == lp || lp == null)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace OpenRA
|
|||||||
if (actor.Owner != world.LocalPlayer || !actor.IsInWorld)
|
if (actor.Owner != world.LocalPlayer || !actor.IsInWorld)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var selectable = actor.Info.Traits.GetOrDefault<SelectableInfo>();
|
var selectable = actor.Info.TraitInfoOrDefault<SelectableInfo>();
|
||||||
if (selectable == null || !actor.HasVoice(selectable.Voice))
|
if (selectable == null || !actor.HasVoice(selectable.Voice))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -84,12 +84,6 @@ namespace OpenRA
|
|||||||
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
|
throw new InvalidOperationException("Attempted to get trait from destroyed object ({0})".F(actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains<T>(Actor actor)
|
|
||||||
{
|
|
||||||
CheckDestroyed(actor);
|
|
||||||
return InnerGet<T>().GetMultiple(actor.ActorID).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Get<T>(Actor actor)
|
public T Get<T>(Actor actor)
|
||||||
{
|
{
|
||||||
CheckDestroyed(actor);
|
CheckDestroyed(actor);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public interface ISeedableResource { void Seed(Actor self); }
|
public interface ISeedableResource { void Seed(Actor self); }
|
||||||
|
|
||||||
public interface ISelectionDecorationsInfo
|
public interface ISelectionDecorationsInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
int[] SelectionBoxBounds { get; }
|
int[] SelectionBoxBounds { get; }
|
||||||
}
|
}
|
||||||
@@ -144,13 +144,13 @@ namespace OpenRA.Traits
|
|||||||
Player Owner { get; }
|
Player Owner { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IToolTip
|
public interface ITooltip
|
||||||
{
|
{
|
||||||
ITooltipInfo TooltipInfo { get; }
|
ITooltipInfo TooltipInfo { get; }
|
||||||
Player Owner { get; }
|
Player Owner { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ITooltipInfo
|
public interface ITooltipInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
string TooltipForPlayerStance(Stance stance);
|
string TooltipForPlayerStance(Stance stance);
|
||||||
bool IsOwnerRowVisible { get; }
|
bool IsOwnerRowVisible { get; }
|
||||||
@@ -226,6 +226,7 @@ namespace OpenRA.Traits
|
|||||||
public interface ITags { IEnumerable<TagType> GetTags(); }
|
public interface ITags { IEnumerable<TagType> GetTags(); }
|
||||||
public interface ISelectionBar { float GetValue(); Color GetColor(); }
|
public interface ISelectionBar { float GetValue(); Color GetColor(); }
|
||||||
|
|
||||||
|
public interface IPositionableInfo : ITraitInfo { }
|
||||||
public interface IPositionable : IOccupySpace
|
public interface IPositionable : IOccupySpace
|
||||||
{
|
{
|
||||||
bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any);
|
bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any);
|
||||||
@@ -296,6 +297,7 @@ namespace OpenRA.Traits
|
|||||||
public interface INotifyBecomingIdle { void OnBecomingIdle(Actor self); }
|
public interface INotifyBecomingIdle { void OnBecomingIdle(Actor self); }
|
||||||
public interface INotifyIdle { void TickIdle(Actor self); }
|
public interface INotifyIdle { void TickIdle(Actor self); }
|
||||||
|
|
||||||
|
public interface IBlocksProjectilesInfo : ITraitInfo { }
|
||||||
public interface IBlocksProjectiles { }
|
public interface IBlocksProjectiles { }
|
||||||
public interface IRenderInfantrySequenceModifier
|
public interface IRenderInfantrySequenceModifier
|
||||||
{
|
{
|
||||||
@@ -309,7 +311,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
public interface IPostRenderSelection { IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr); }
|
public interface IPostRenderSelection { IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr); }
|
||||||
|
|
||||||
public interface ITargetableInfo
|
public interface ITargetableInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
HashSet<string> GetTargetTypes();
|
HashSet<string> GetTargetTypes();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace OpenRA.Widgets
|
|||||||
{
|
{
|
||||||
if (!hasBox && World.Selection.Actors.Any() && !multiClick)
|
if (!hasBox && World.Selection.Actors.Any() && !multiClick)
|
||||||
{
|
{
|
||||||
if (!(World.ScreenMap.ActorsAt(xy).Where(x => x.HasTrait<Selectable>() &&
|
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) &&
|
(x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x))).Any() && !mi.Modifiers.HasModifier(Modifiers.Ctrl) &&
|
||||||
!mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
|
!mi.Modifiers.HasModifier(Modifiers.Alt) && UnitOrderGenerator.InputOverridesSelection(World, xy, mi)))
|
||||||
{
|
{
|
||||||
@@ -301,7 +301,7 @@ namespace OpenRA.Widgets
|
|||||||
a = b;
|
a = b;
|
||||||
|
|
||||||
return world.ScreenMap.ActorsInBox(a, b)
|
return world.ScreenMap.ActorsInBox(a, b)
|
||||||
.Where(x => x.HasTrait<Selectable>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
.Where(x => x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(x)))
|
||||||
.SubsetWithHighestSelectionPriority();
|
.SubsetWithHighestSelectionPriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
if (!self.IsInWorld || self.IsDead)
|
if (!self.IsInWorld || self.IsDead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var altitude = self.World.Map.Rules.Actors[actorType].Traits.Get<PlaneInfo>().CruiseAltitude;
|
var altitude = self.World.Map.Rules.Actors[actorType].TraitInfo<PlaneInfo>().CruiseAltitude;
|
||||||
var actor = w.CreateActor(actorType, new TypeDictionary
|
var actor = w.CreateActor(actorType, new TypeDictionary
|
||||||
{
|
{
|
||||||
new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)),
|
new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WDist.Zero, WDist.Zero, altitude)),
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var sumOfHp = 0;
|
var sumOfHp = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
{
|
{
|
||||||
if (a.HasTrait<Health>())
|
if (a.Info.HasTraitInfo<HealthInfo>())
|
||||||
{
|
{
|
||||||
sumOfMaxHp += a.Trait<Health>().MaxHP;
|
sumOfMaxHp += a.Trait<Health>().MaxHP;
|
||||||
sumOfHp += a.Trait<Health>().HP;
|
sumOfHp += a.Trait<Health>().HP;
|
||||||
@@ -191,7 +191,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
protected float RelativePower(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
protected float RelativePower(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
||||||
{
|
{
|
||||||
return RelativeValue(own, enemy, 100, SumOfValues<AttackBase>, a =>
|
return RelativeValue(own, enemy, 100, SumOfValues<AttackBaseInfo>, a =>
|
||||||
{
|
{
|
||||||
var sumOfDamage = 0;
|
var sumOfDamage = 0;
|
||||||
var arms = a.TraitsImplementing<Armament>();
|
var arms = a.TraitsImplementing<Armament>();
|
||||||
@@ -208,7 +208,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
protected float RelativeSpeed(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
protected float RelativeSpeed(IEnumerable<Actor> own, IEnumerable<Actor> enemy)
|
||||||
{
|
{
|
||||||
return RelativeValue(own, enemy, 100, Average<Mobile>, (Actor a) => a.Trait<Mobile>().Info.Speed);
|
return RelativeValue(own, enemy, 100, Average<MobileInfo>, (Actor a) => a.Info.TraitInfo<MobileInfo>().Speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static float RelativeValue(IEnumerable<Actor> own, IEnumerable<Actor> enemy, float normalizeByValue,
|
protected static float RelativeValue(IEnumerable<Actor> own, IEnumerable<Actor> enemy, float normalizeByValue,
|
||||||
@@ -224,23 +224,23 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
return relative.Clamp(0.0f, 999.0f);
|
return relative.Clamp(0.0f, 999.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float SumOfValues<Trait>(IEnumerable<Actor> actors, Func<Actor, int> getValue)
|
protected float SumOfValues<TTraitInfo>(IEnumerable<Actor> actors, Func<Actor, int> getValue) where TTraitInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
if (a.HasTrait<Trait>())
|
if (a.Info.HasTraitInfo<TTraitInfo>())
|
||||||
sum += getValue(a);
|
sum += getValue(a);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float Average<Trait>(IEnumerable<Actor> actors, Func<Actor, int> getValue)
|
protected float Average<TTraitInfo>(IEnumerable<Actor> actors, Func<Actor, int> getValue) where TTraitInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
var countActors = 0;
|
var countActors = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
{
|
{
|
||||||
if (a.HasTrait<Trait>())
|
if (a.Info.HasTraitInfo<TTraitInfo>())
|
||||||
{
|
{
|
||||||
sum += getValue(a);
|
sum += getValue(a);
|
||||||
countActors++;
|
countActors++;
|
||||||
|
|||||||
@@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
var randomBaseBuilding = World.Actors.Where(
|
var randomBaseBuilding = World.Actors.Where(
|
||||||
a => a.Owner == Player
|
a => a.Owner == Player
|
||||||
&& a.HasTrait<BaseBuilding>()
|
&& a.Info.HasTraitInfo<BaseBuildingInfo>()
|
||||||
&& !a.HasTrait<Mobile>())
|
&& !a.Info.HasTraitInfo<MobileInfo>())
|
||||||
.RandomOrDefault(Random);
|
.RandomOrDefault(Random);
|
||||||
|
|
||||||
return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter;
|
return randomBaseBuilding != null ? randomBaseBuilding.Location : initialBaseCenter;
|
||||||
@@ -232,7 +232,9 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
pathfinder = World.WorldActor.Trait<IPathFinder>();
|
pathfinder = World.WorldActor.Trait<IPathFinder>();
|
||||||
|
|
||||||
isEnemyUnit = unit =>
|
isEnemyUnit = unit =>
|
||||||
Player.Stances[unit.Owner] == Stance.Enemy && !unit.HasTrait<Husk>() && unit.HasTrait<ITargetable>();
|
Player.Stances[unit.Owner] == Stance.Enemy
|
||||||
|
&& !unit.Info.HasTraitInfo<HuskInfo>()
|
||||||
|
&& unit.Info.HasTraitInfo<ITargetableInfo>();
|
||||||
|
|
||||||
foreach (var decision in info.PowerDecisions)
|
foreach (var decision in info.PowerDecisions)
|
||||||
powerDecisions.Add(decision.OrderName, decision);
|
powerDecisions.Add(decision.OrderName, decision);
|
||||||
@@ -279,8 +281,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
var baseProviders = World.Actors.Where(
|
var baseProviders = World.Actors.Where(
|
||||||
a => a.Owner == Player
|
a => a.Owner == Player
|
||||||
&& a.HasTrait<BaseProvider>()
|
&& a.Info.HasTraitInfo<BaseProviderInfo>()
|
||||||
&& !a.HasTrait<Mobile>());
|
&& !a.Info.HasTraitInfo<MobileInfo>());
|
||||||
|
|
||||||
foreach (var b in baseProviders)
|
foreach (var b in baseProviders)
|
||||||
{
|
{
|
||||||
@@ -306,8 +308,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
var areaProviders = World.Actors.Where(
|
var areaProviders = World.Actors.Where(
|
||||||
a => a.Owner == Player
|
a => a.Owner == Player
|
||||||
&& a.HasTrait<GivesBuildableArea>()
|
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>()
|
||||||
&& !a.HasTrait<Mobile>());
|
&& !a.Info.HasTraitInfo<MobileInfo>());
|
||||||
|
|
||||||
foreach (var a in areaProviders)
|
foreach (var a in areaProviders)
|
||||||
{
|
{
|
||||||
@@ -431,7 +433,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
// For mods like RA (number of building must match the number of aircraft)
|
// For mods like RA (number of building must match the number of aircraft)
|
||||||
bool HasAdequateAirUnitReloadBuildings(ActorInfo actorInfo)
|
bool HasAdequateAirUnitReloadBuildings(ActorInfo actorInfo)
|
||||||
{
|
{
|
||||||
var aircraftInfo = actorInfo.Traits.GetOrDefault<AircraftInfo>();
|
var aircraftInfo = actorInfo.TraitInfoOrDefault<AircraftInfo>();
|
||||||
if (aircraftInfo == null)
|
if (aircraftInfo == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -451,7 +453,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
CPos defenseCenter;
|
CPos defenseCenter;
|
||||||
public CPos? ChooseBuildLocation(string actorType, bool distanceToBaseIsImportant, BuildingType type)
|
public CPos? ChooseBuildLocation(string actorType, bool distanceToBaseIsImportant, BuildingType type)
|
||||||
{
|
{
|
||||||
var bi = Map.Rules.Actors[actorType].Traits.GetOrDefault<BuildingInfo>();
|
var bi = Map.Rules.Actors[actorType].TraitInfoOrDefault<BuildingInfo>();
|
||||||
if (bi == null)
|
if (bi == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -487,7 +489,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
case BuildingType.Defense:
|
case BuildingType.Defense:
|
||||||
|
|
||||||
// Build near the closest enemy structure
|
// Build near the closest enemy structure
|
||||||
var closestEnemy = World.Actors.Where(a => !a.Disposed && a.HasTrait<Building>() && 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));
|
.ClosestTo(World.Map.CenterOfCell(defenseCenter));
|
||||||
|
|
||||||
var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
|
var targetCell = closestEnemy != null ? closestEnemy.Location : baseCenter;
|
||||||
@@ -563,7 +565,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
// Pick something worth attacking owned by that player
|
// Pick something worth attacking owned by that player
|
||||||
var target = World.Actors
|
var target = World.Actors
|
||||||
.Where(a => a.Owner == enemy && a.HasTrait<IOccupySpace>())
|
.Where(a => a.Owner == enemy && a.Info.HasTraitInfo<IOccupySpaceInfo>())
|
||||||
.ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter()));
|
.ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter()));
|
||||||
|
|
||||||
if (target == null)
|
if (target == null)
|
||||||
@@ -595,7 +597,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
List<Actor> FindEnemyConstructionYards()
|
List<Actor> FindEnemyConstructionYards()
|
||||||
{
|
{
|
||||||
return World.Actors.Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead
|
return World.Actors.Where(a => Player.Stances[a.Owner] == Stance.Enemy && !a.IsDead
|
||||||
&& a.HasTrait<BaseBuilding>() && !a.HasTrait<Mobile>()).ToList();
|
&& a.Info.HasTraitInfo<BaseBuildingInfo>() && !a.Info.HasTraitInfo<MobileInfo>()).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanSquads()
|
void CleanSquads()
|
||||||
@@ -655,8 +657,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
CPos FindNextResource(Actor self)
|
CPos FindNextResource(Actor self)
|
||||||
{
|
{
|
||||||
var harvInfo = self.Info.Traits.Get<HarvesterInfo>();
|
var harvInfo = self.Info.TraitInfo<HarvesterInfo>();
|
||||||
var mobileInfo = self.Info.Traits.Get<MobileInfo>();
|
var mobileInfo = self.Info.TraitInfo<MobileInfo>();
|
||||||
var passable = (uint)mobileInfo.GetMovementClass(World.TileSet);
|
var passable = (uint)mobileInfo.GetMovementClass(World.TileSet);
|
||||||
|
|
||||||
var path = pathfinder.FindPath(
|
var path = pathfinder.FindPath(
|
||||||
@@ -705,18 +707,18 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
void FindNewUnits(Actor self)
|
void FindNewUnits(Actor self)
|
||||||
{
|
{
|
||||||
var newUnits = self.World.ActorsWithTrait<IPositionable>()
|
var newUnits = self.World.ActorsWithTrait<IPositionable>()
|
||||||
.Where(a => a.Actor.Owner == Player && !a.Actor.HasTrait<BaseBuilding>()
|
.Where(a => a.Actor.Owner == Player && !a.Actor.Info.HasTraitInfo<BaseBuildingInfo>()
|
||||||
&& !activeUnits.Contains(a.Actor))
|
&& !activeUnits.Contains(a.Actor))
|
||||||
.Select(a => a.Actor);
|
.Select(a => a.Actor);
|
||||||
|
|
||||||
foreach (var a in newUnits)
|
foreach (var a in newUnits)
|
||||||
{
|
{
|
||||||
if (a.HasTrait<Harvester>())
|
if (a.Info.HasTraitInfo<HarvesterInfo>())
|
||||||
QueueOrder(new Order("Harvest", a, false));
|
QueueOrder(new Order("Harvest", a, false));
|
||||||
else
|
else
|
||||||
unitsHangingAroundTheBase.Add(a);
|
unitsHangingAroundTheBase.Add(a);
|
||||||
|
|
||||||
if (a.HasTrait<Aircraft>() && a.HasTrait<AttackBase>())
|
if (a.Info.HasTraitInfo<AircraftInfo>() && a.Info.HasTraitInfo<AttackBaseInfo>())
|
||||||
{
|
{
|
||||||
var air = GetSquadOfType(SquadType.Air);
|
var air = GetSquadOfType(SquadType.Air);
|
||||||
if (air == null)
|
if (air == null)
|
||||||
@@ -740,7 +742,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var attackForce = RegisterNewSquad(SquadType.Assault);
|
var attackForce = RegisterNewSquad(SquadType.Assault);
|
||||||
|
|
||||||
foreach (var a in unitsHangingAroundTheBase)
|
foreach (var a in unitsHangingAroundTheBase)
|
||||||
if (!a.HasTrait<Aircraft>())
|
if (!a.Info.HasTraitInfo<AircraftInfo>())
|
||||||
attackForce.Units.Add(a);
|
attackForce.Units.Add(a);
|
||||||
|
|
||||||
unitsHangingAroundTheBase.Clear();
|
unitsHangingAroundTheBase.Clear();
|
||||||
@@ -751,7 +753,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
var allEnemyBaseBuilder = FindEnemyConstructionYards();
|
var allEnemyBaseBuilder = FindEnemyConstructionYards();
|
||||||
var ownUnits = activeUnits
|
var ownUnits = activeUnits
|
||||||
.Where(unit => unit.HasTrait<AttackBase>() && !unit.HasTrait<Aircraft>() && unit.IsIdle).ToList();
|
.Where(unit => unit.Info.HasTraitInfo<AttackBaseInfo>() && !unit.Info.HasTraitInfo<AircraftInfo>() && unit.IsIdle).ToList();
|
||||||
|
|
||||||
if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize))
|
if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize))
|
||||||
return;
|
return;
|
||||||
@@ -759,7 +761,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
foreach (var b in allEnemyBaseBuilder)
|
foreach (var b in allEnemyBaseBuilder)
|
||||||
{
|
{
|
||||||
var enemies = World.FindActorsInCircle(b.CenterPosition, WDist.FromCells(Info.RushAttackScanRadius))
|
var enemies = World.FindActorsInCircle(b.CenterPosition, WDist.FromCells(Info.RushAttackScanRadius))
|
||||||
.Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait<AttackBase>()).ToList();
|
.Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo<AttackBaseInfo>()).ToList();
|
||||||
|
|
||||||
if (rushFuzzy.CanAttack(ownUnits, enemies))
|
if (rushFuzzy.CanAttack(ownUnits, enemies))
|
||||||
{
|
{
|
||||||
@@ -788,8 +790,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
if (!protectSq.IsValid)
|
if (!protectSq.IsValid)
|
||||||
{
|
{
|
||||||
var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(GetRandomBaseCenter()), WDist.FromCells(Info.ProtectUnitScanRadius))
|
var ownUnits = World.FindActorsInCircle(World.Map.CenterOfCell(GetRandomBaseCenter()), WDist.FromCells(Info.ProtectUnitScanRadius))
|
||||||
.Where(unit => unit.Owner == Player && !unit.HasTrait<Building>()
|
.Where(unit => unit.Owner == Player && !unit.Info.HasTraitInfo<BuildingInfo>()
|
||||||
&& unit.HasTrait<AttackBase>());
|
&& unit.Info.HasTraitInfo<AttackBaseInfo>());
|
||||||
|
|
||||||
foreach (var a in ownUnits)
|
foreach (var a in ownUnits)
|
||||||
protectSq.Units.Add(a);
|
protectSq.Units.Add(a);
|
||||||
@@ -805,7 +807,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
var buildings = self.World.ActorsWithTrait<RallyPoint>()
|
var buildings = self.World.ActorsWithTrait<RallyPoint>()
|
||||||
.Where(rp => rp.Actor.Owner == Player &&
|
.Where(rp => rp.Actor.Owner == Player &&
|
||||||
!IsRallyPointValid(rp.Trait.Location, rp.Actor.Info.Traits.GetOrDefault<BuildingInfo>())).ToArray();
|
!IsRallyPointValid(rp.Trait.Location, rp.Actor.Info.TraitInfoOrDefault<BuildingInfo>())).ToArray();
|
||||||
|
|
||||||
foreach (var a in buildings)
|
foreach (var a in buildings)
|
||||||
QueueOrder(new Order("SetRallyPoint", a.Actor, false) { TargetLocation = ChooseRallyLocationNear(a.Actor), SuppressVisualFeedback = true });
|
QueueOrder(new Order("SetRallyPoint", a.Actor, false) { TargetLocation = ChooseRallyLocationNear(a.Actor), SuppressVisualFeedback = true });
|
||||||
@@ -815,7 +817,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
CPos ChooseRallyLocationNear(Actor producer)
|
CPos ChooseRallyLocationNear(Actor producer)
|
||||||
{
|
{
|
||||||
var possibleRallyPoints = Map.FindTilesInCircle(producer.Location, Info.RallyPointScanRadius)
|
var possibleRallyPoints = Map.FindTilesInCircle(producer.Location, Info.RallyPointScanRadius)
|
||||||
.Where(c => IsRallyPointValid(c, producer.Info.Traits.GetOrDefault<BuildingInfo>()));
|
.Where(c => IsRallyPointValid(c, producer.Info.TraitInfoOrDefault<BuildingInfo>()));
|
||||||
|
|
||||||
if (!possibleRallyPoints.Any())
|
if (!possibleRallyPoints.Any())
|
||||||
{
|
{
|
||||||
@@ -830,7 +832,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
{
|
{
|
||||||
// Find and deploy our mcv
|
// Find and deploy our mcv
|
||||||
var mcv = self.World.Actors
|
var mcv = self.World.Actors
|
||||||
.FirstOrDefault(a => a.Owner == Player && a.HasTrait<BaseBuilding>());
|
.FirstOrDefault(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>());
|
||||||
|
|
||||||
if (mcv != null)
|
if (mcv != null)
|
||||||
{
|
{
|
||||||
@@ -839,7 +841,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
// Don't transform the mcv if it is a fact
|
// Don't transform the mcv if it is a fact
|
||||||
// HACK: This needs to query against MCVs directly
|
// HACK: This needs to query against MCVs directly
|
||||||
if (mcv.HasTrait<Mobile>())
|
if (mcv.Info.HasTraitInfo<MobileInfo>())
|
||||||
QueueOrder(new Order("DeployTransform", mcv, false));
|
QueueOrder(new Order("DeployTransform", mcv, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -851,7 +853,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
void FindAndDeployBackupMcv(Actor self)
|
void FindAndDeployBackupMcv(Actor self)
|
||||||
{
|
{
|
||||||
// HACK: This needs to query against MCVs directly
|
// HACK: This needs to query against MCVs directly
|
||||||
var mcvs = self.World.Actors.Where(a => a.Owner == Player && a.HasTrait<BaseBuilding>() && a.HasTrait<Mobile>());
|
var mcvs = self.World.Actors
|
||||||
|
.Where(a => a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>());
|
||||||
if (!mcvs.Any())
|
if (!mcvs.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -860,7 +863,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
if (mcv.IsMoving())
|
if (mcv.IsMoving())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var factType = mcv.Info.Traits.Get<TransformsInfo>().IntoActor;
|
var factType = mcv.Info.TraitInfo<TransformsInfo>().IntoActor;
|
||||||
var desiredLocation = ChooseBuildLocation(factType, false, BuildingType.Building);
|
var desiredLocation = ChooseBuildLocation(factType, false, BuildingType.Building);
|
||||||
if (desiredLocation == null)
|
if (desiredLocation == null)
|
||||||
continue;
|
continue;
|
||||||
@@ -1010,7 +1013,8 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// No construction yards - Build a new MCV
|
// No construction yards - Build a new MCV
|
||||||
if (!HasAdequateFact() && !self.World.Actors.Any(a => a.Owner == Player && a.HasTrait<BaseBuilding>() && a.HasTrait<Mobile>()))
|
if (!HasAdequateFact() && !self.World.Actors.Any(a =>
|
||||||
|
a.Owner == Player && a.Info.HasTraitInfo<BaseBuildingInfo>() && a.Info.HasTraitInfo<MobileInfo>()))
|
||||||
BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name);
|
BuildUnit("Vehicle", GetUnitInfoByCommonName("Mcv", Player).Name);
|
||||||
|
|
||||||
foreach (var q in Info.UnitQueues)
|
foreach (var q in Info.UnitQueues)
|
||||||
@@ -1069,14 +1073,14 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
if (e.Attacker.Disposed)
|
if (e.Attacker.Disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!e.Attacker.HasTrait<ITargetable>())
|
if (!e.Attacker.Info.HasTraitInfo<ITargetableInfo>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.Damage > 0)
|
if (e.Damage > 0)
|
||||||
aggro[e.Attacker.Owner].Aggro += e.Damage;
|
aggro[e.Attacker.Owner].Aggro += e.Damage;
|
||||||
|
|
||||||
// Protected harvesters or building
|
// Protected harvesters or building
|
||||||
if ((self.HasTrait<Harvester>() || self.HasTrait<Building>()) &&
|
if ((self.Info.HasTraitInfo<HarvesterInfo>() || self.Info.HasTraitInfo<BuildingInfo>()) &&
|
||||||
Player.Stances[e.Attacker.Owner] == Stance.Enemy)
|
Player.Stances[e.Attacker.Owner] == Stance.Enemy)
|
||||||
{
|
{
|
||||||
defenseCenter = e.Attacker.Location;
|
defenseCenter = e.Attacker.Location;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
public bool IsTargetValid
|
public bool IsTargetValid
|
||||||
{
|
{
|
||||||
get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.HasTrait<Husk>(); }
|
get { return Target.IsValidFor(Units.FirstOrDefault()) && !Target.Actor.Info.HasTraitInfo<HuskInfo>(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsTargetVisible
|
public bool IsTargetVisible
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
var missileUnitsCount = 0;
|
var missileUnitsCount = 0;
|
||||||
foreach (var unit in units)
|
foreach (var unit in units)
|
||||||
{
|
{
|
||||||
if (unit != null && unit.HasTrait<AttackBase>() && !unit.HasTrait<Aircraft>()
|
if (unit != null && unit.Info.HasTraitInfo<AttackBaseInfo>() && !unit.Info.HasTraitInfo<AircraftInfo>()
|
||||||
&& !unit.IsDisabled())
|
&& !unit.IsDisabled())
|
||||||
{
|
{
|
||||||
var arms = unit.TraitsImplementing<Armament>();
|
var arms = unit.TraitsImplementing<Armament>();
|
||||||
@@ -223,7 +223,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner.TargetActor.HasTrait<ITargetable>() && 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 });
|
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))
|
var enemies = owner.World.FindActorsInCircle(leader.CenterPosition, WDist.FromCells(12))
|
||||||
.Where(a1 => !a1.Disposed && !a1.IsDead);
|
.Where(a1 => !a1.Disposed && !a1.IsDead);
|
||||||
var enemynearby = enemies.Where(a1 => a1.HasTrait<ITargetable>() && 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);
|
var target = enemynearby.ClosestTo(leader.CenterPosition);
|
||||||
if (target != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
protected static bool CanAttackTarget(Actor a, Actor target)
|
protected static bool CanAttackTarget(Actor a, Actor target)
|
||||||
{
|
{
|
||||||
if (!a.HasTrait<AttackBase>())
|
if (!a.Info.HasTraitInfo<AttackBaseInfo>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var targetTypes = target.TraitsImplementing<ITargetable>().Where(Exts.IsTraitEnabled).SelectMany(t => t.TargetTypes);
|
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 u = squad.Units.Random(squad.Random);
|
||||||
var units = squad.World.FindActorsInCircle(u.CenterPosition, WDist.FromCells(DangerRadius)).ToList();
|
var units = squad.World.FindActorsInCircle(u.CenterPosition, WDist.FromCells(DangerRadius)).ToList();
|
||||||
var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.HasTrait<Building>());
|
var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.HasTraitInfo<BuildingInfo>());
|
||||||
if (ownBaseBuildingAround.Any())
|
if (ownBaseBuildingAround.Any())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait<AttackBase>());
|
var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo<AttackBaseInfo>());
|
||||||
if (!enemyAroundUnit.Any())
|
if (!enemyAroundUnit.Any())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
switch (TargetMetric)
|
switch (TargetMetric)
|
||||||
{
|
{
|
||||||
case DecisionMetric.Value:
|
case DecisionMetric.Value:
|
||||||
var valueInfo = a.Info.Traits.GetOrDefault<ValuedInfo>();
|
var valueInfo = a.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
return (valueInfo != null) ? valueInfo.Cost * Attractiveness : 0;
|
return (valueInfo != null) ? valueInfo.Cost * Attractiveness : 0;
|
||||||
|
|
||||||
case DecisionMetric.Health:
|
case DecisionMetric.Health:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
target = value;
|
target = value;
|
||||||
if (target.Type == TargetType.Actor)
|
if (target.Type == TargetType.Actor)
|
||||||
canHideUnderFog = target.Actor.HasTrait<HiddenUnderFog>();
|
canHideUnderFog = target.Actor.Info.HasTraitInfo<HiddenUnderFogInfo>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,20 +17,16 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
public class HeliReturn : Activity
|
public class HeliReturn : Activity
|
||||||
{
|
{
|
||||||
readonly AircraftInfo aircraftInfo;
|
|
||||||
readonly Helicopter heli;
|
readonly Helicopter heli;
|
||||||
readonly HelicopterInfo heliInfo;
|
|
||||||
|
|
||||||
public HeliReturn(Actor self)
|
public HeliReturn(Actor self)
|
||||||
{
|
{
|
||||||
aircraftInfo = self.Info.Traits.Get<AircraftInfo>();
|
|
||||||
heli = self.Trait<Helicopter>();
|
heli = self.Trait<Helicopter>();
|
||||||
heliInfo = self.Info.Traits.Get<HelicopterInfo>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Actor ChooseHelipad(Actor self)
|
public Actor ChooseHelipad(Actor self)
|
||||||
{
|
{
|
||||||
var rearmBuildings = self.Info.Traits.Get<HelicopterInfo>().RearmBuildings;
|
var rearmBuildings = heli.Info.RearmBuildings;
|
||||||
return self.World.Actors.Where(a => a.Owner == self.Owner).FirstOrDefault(
|
return self.World.Actors.Where(a => a.Owner == self.Owner).FirstOrDefault(
|
||||||
a => rearmBuildings.Contains(a.Info.Name) && !Reservable.IsReserved(a));
|
a => rearmBuildings.Contains(a.Info.Name) && !Reservable.IsReserved(a));
|
||||||
}
|
}
|
||||||
@@ -41,11 +37,11 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
var dest = ChooseHelipad(self);
|
var dest = ChooseHelipad(self);
|
||||||
var initialFacing = aircraftInfo.InitialFacing;
|
var initialFacing = heli.Info.InitialFacing;
|
||||||
|
|
||||||
if (dest == null)
|
if (dest == null)
|
||||||
{
|
{
|
||||||
var rearmBuildings = heliInfo.RearmBuildings;
|
var rearmBuildings = heli.Info.RearmBuildings;
|
||||||
var nearestHpad = self.World.ActorsWithTrait<Reservable>()
|
var nearestHpad = self.World.ActorsWithTrait<Reservable>()
|
||||||
.Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name))
|
.Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name))
|
||||||
.Select(a => a.Actor)
|
.Select(a => a.Actor)
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
plane = self.Trait<Plane>();
|
plane = self.Trait<Plane>();
|
||||||
planeInfo = self.Info.Traits.Get<PlaneInfo>();
|
planeInfo = self.Info.TraitInfo<PlaneInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
|
public static Actor ChooseAirfield(Actor self, bool unreservedOnly)
|
||||||
{
|
{
|
||||||
var rearmBuildings = self.Info.Traits.Get<PlaneInfo>().RearmBuildings;
|
var rearmBuildings = self.Info.TraitInfo<PlaneInfo>().RearmBuildings;
|
||||||
return self.World.ActorsWithTrait<Reservable>()
|
return self.World.ActorsWithTrait<Reservable>()
|
||||||
.Where(a => a.Actor.Owner == self.Owner)
|
.Where(a => a.Actor.Owner == self.Owner)
|
||||||
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name)
|
.Where(a => rearmBuildings.Contains(a.Actor.Info.Name)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
// HACK: This would otherwise break targeting frozen actors
|
// HACK: This would otherwise break targeting frozen actors
|
||||||
// The problem is that Shroud.IsTargetable returns false (as it should) for
|
// 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.
|
// frozen actors, but we do want to explicitly target the underlying actor here.
|
||||||
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.CanTargetActor(Target.Actor))
|
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor))
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|
||||||
// Try to move within range
|
// Try to move within range
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
actor = target;
|
actor = target;
|
||||||
building = actor.TraitOrDefault<Building>();
|
building = actor.TraitOrDefault<Building>();
|
||||||
capturesInfo = self.Info.Traits.Get<CapturesInfo>();
|
capturesInfo = self.Info.TraitInfo<CapturesInfo>();
|
||||||
capturable = target.Trait<Capturable>();
|
capturable = target.Trait<Capturable>();
|
||||||
health = actor.Trait<Health>();
|
health = actor.Trait<Health>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
readonly IMove movement;
|
readonly IMove movement;
|
||||||
readonly Harvester harv;
|
readonly Harvester harv;
|
||||||
readonly HarvesterInfo harvInfo;
|
|
||||||
|
|
||||||
bool isDocking;
|
bool isDocking;
|
||||||
int chosenTicks;
|
int chosenTicks;
|
||||||
@@ -30,7 +29,6 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
movement = self.Trait<IMove>();
|
movement = self.Trait<IMove>();
|
||||||
harv = self.Trait<Harvester>();
|
harv = self.Trait<Harvester>();
|
||||||
harvInfo = self.Info.Traits.Get<HarvesterInfo>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
@@ -57,7 +55,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
// No refineries exist; check again after delay defined in Harvester.
|
// No refineries exist; check again after delay defined in Harvester.
|
||||||
if (harv.LinkedProc == null)
|
if (harv.LinkedProc == null)
|
||||||
return Util.SequenceActivities(new Wait(harvInfo.SearchForDeliveryBuildingDelay), this);
|
return Util.SequenceActivities(new Wait(harv.Info.SearchForDeliveryBuildingDelay), this);
|
||||||
|
|
||||||
var proc = harv.LinkedProc;
|
var proc = harv.LinkedProc;
|
||||||
var iao = proc.Trait<IAcceptResources>();
|
var iao = proc.Trait<IAcceptResources>();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
this.target = target;
|
this.target = target;
|
||||||
capturable = target.Actor.Trait<ExternalCapturable>();
|
capturable = target.Actor.Trait<ExternalCapturable>();
|
||||||
capturesInfo = self.Info.Traits.Get<ExternalCapturesInfo>();
|
capturesInfo = self.Info.TraitInfo<ExternalCapturesInfo>();
|
||||||
mobile = self.Trait<Mobile>();
|
mobile = self.Trait<Mobile>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public FindResources(Actor self)
|
public FindResources(Actor self)
|
||||||
{
|
{
|
||||||
harv = self.Trait<Harvester>();
|
harv = self.Trait<Harvester>();
|
||||||
harvInfo = self.Info.Traits.Get<HarvesterInfo>();
|
harvInfo = self.Info.TraitInfo<HarvesterInfo>();
|
||||||
mobile = self.Trait<Mobile>();
|
mobile = self.Trait<Mobile>();
|
||||||
mobileInfo = self.Info.Traits.Get<MobileInfo>();
|
mobileInfo = self.Info.TraitInfo<MobileInfo>();
|
||||||
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
||||||
territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
|
territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
|
||||||
pathFinder = self.World.WorldActor.Trait<IPathFinder>();
|
pathFinder = self.World.WorldActor.Trait<IPathFinder>();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public HarvestResource(Actor self)
|
public HarvestResource(Actor self)
|
||||||
{
|
{
|
||||||
harv = self.Trait<Harvester>();
|
harv = self.Trait<Harvester>();
|
||||||
harvInfo = self.Info.Traits.Get<HarvesterInfo>();
|
harvInfo = self.Info.TraitInfo<HarvesterInfo>();
|
||||||
facing = self.Trait<IFacing>();
|
facing = self.Trait<IFacing>();
|
||||||
territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
|
territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
|
||||||
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
var attack = self.Trait<AttackBase>();
|
var attack = self.Trait<AttackBase>();
|
||||||
targets = self.World.Actors.Where(a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self)
|
targets = self.World.Actors.Where(a => self != a && !a.IsDead && a.IsInWorld && a.AppearsHostileTo(self)
|
||||||
&& a.HasTrait<Huntable>() && 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)
|
bool IsTargetable(Actor self, Actor viewer)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
{
|
{
|
||||||
target = value;
|
target = value;
|
||||||
if (target.Type == TargetType.Actor)
|
if (target.Type == TargetType.Actor)
|
||||||
canHideUnderFog = target.Actor.HasTrait<HiddenUnderFog>();
|
canHideUnderFog = target.Actor.Info.HasTraitInfo<HiddenUnderFogInfo>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
pos = self.TraitOrDefault<IPositionable>();
|
pos = self.TraitOrDefault<IPositionable>();
|
||||||
|
|
||||||
// Parachutable trait is a prerequisite for running this activity
|
// Parachutable trait is a prerequisite for running this activity
|
||||||
para = self.Info.Traits.Get<ParachutableInfo>();
|
para = self.Info.TraitInfo<ParachutableInfo>();
|
||||||
fallVector = new WVec(0, 0, para.FallRate);
|
fallVector = new WVec(0, 0, para.FallRate);
|
||||||
this.dropPosition = dropPosition;
|
this.dropPosition = dropPosition;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// HACK to check if we are on the helipad/airfield/etc.
|
// HACK to check if we are on the helipad/airfield/etc.
|
||||||
var hostBuilding = self.World.ActorMap.GetUnitsAt(self.Location).FirstOrDefault(a => a.HasTrait<Building>());
|
var hostBuilding = self.World.ActorMap.GetUnitsAt(self.Location)
|
||||||
|
.FirstOrDefault(a => a.Info.HasTraitInfo<BuildingInfo>());
|
||||||
|
|
||||||
if (hostBuilding == null || !hostBuilding.IsInWorld)
|
if (hostBuilding == null || !hostBuilding.IsInWorld)
|
||||||
return NextActivity;
|
return NextActivity;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public Repair(Actor host)
|
public Repair(Actor host)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
repairsUnits = host.Info.Traits.Get<RepairsUnitsInfo>();
|
repairsUnits = host.Info.TraitInfo<RepairsUnitsInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity Tick(Actor self)
|
public override Activity Tick(Actor self)
|
||||||
@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
|
|
||||||
if (remainingTicks == 0)
|
if (remainingTicks == 0)
|
||||||
{
|
{
|
||||||
var unitCost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
var unitCost = self.Info.TraitInfo<ValuedInfo>().Cost;
|
||||||
var hpToRepair = repairsUnits.HpPerStep;
|
var hpToRepair = repairsUnits.HpPerStep;
|
||||||
var cost = Math.Max(1, (hpToRepair * unitCost * repairsUnits.ValuePercentage) / (health.MaxHP * 100));
|
var cost = Math.Max(1, (hpToRepair * unitCost * repairsUnits.ValuePercentage) / (health.MaxHP * 100));
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public Sell(Actor self)
|
public Sell(Actor self)
|
||||||
{
|
{
|
||||||
health = self.TraitOrDefault<Health>();
|
health = self.TraitOrDefault<Health>();
|
||||||
sellableInfo = self.Info.Traits.Get<SellableInfo>();
|
sellableInfo = self.Info.TraitInfo<SellableInfo>();
|
||||||
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
|
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
public class SpriteHarvesterDockSequence : HarvesterDockSequence
|
public class SpriteHarvesterDockSequence : HarvesterDockSequence
|
||||||
{
|
{
|
||||||
readonly WithSpriteBody wsb;
|
readonly WithSpriteBody wsb;
|
||||||
readonly WithDockingAnimation wda;
|
readonly WithDockingAnimationInfo wda;
|
||||||
|
|
||||||
public SpriteHarvesterDockSequence(Actor self, Actor refinery, int dockAngle, bool isDragRequired, WVec dragOffset, int dragLength)
|
public SpriteHarvesterDockSequence(Actor self, Actor refinery, int dockAngle, bool isDragRequired, WVec dragOffset, int dragLength)
|
||||||
: base(self, refinery, dockAngle, isDragRequired, dragOffset, dragLength)
|
: base(self, refinery, dockAngle, isDragRequired, dragOffset, dragLength)
|
||||||
{
|
{
|
||||||
wsb = self.Trait<WithSpriteBody>();
|
wsb = self.Trait<WithSpriteBody>();
|
||||||
wda = self.Trait<WithDockingAnimation>();
|
wda = self.Info.TraitInfo<WithDockingAnimationInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity OnStateDock(Actor self)
|
public override Activity OnStateDock(Actor self)
|
||||||
@@ -30,14 +30,14 @@ namespace OpenRA.Mods.Common.Activities
|
|||||||
foreach (var trait in self.TraitsImplementing<INotifyHarvesterAction>())
|
foreach (var trait in self.TraitsImplementing<INotifyHarvesterAction>())
|
||||||
trait.Docked();
|
trait.Docked();
|
||||||
|
|
||||||
wsb.PlayCustomAnimation(self, wda.Info.DockSequence, () => wsb.PlayCustomAnimationRepeating(self, wda.Info.DockLoopSequence));
|
wsb.PlayCustomAnimation(self, wda.DockSequence, () => wsb.PlayCustomAnimationRepeating(self, wda.DockLoopSequence));
|
||||||
dockingState = State.Loop;
|
dockingState = State.Loop;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Activity OnStateUndock(Actor self)
|
public override Activity OnStateUndock(Actor self)
|
||||||
{
|
{
|
||||||
wsb.PlayCustomAnimationBackwards(self, wda.Info.DockSequence,
|
wsb.PlayCustomAnimationBackwards(self, wda.DockSequence,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
dockingState = State.Complete;
|
dockingState = State.Complete;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common
|
|||||||
if (self.IsDead)
|
if (self.IsDead)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!self.HasTrait<IOccupySpace>())
|
if (!self.Info.HasTraitInfo<IOccupySpaceInfo>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!self.IsInWorld)
|
if (!self.IsInWorld)
|
||||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common
|
|||||||
if (stance == Stance.Ally)
|
if (stance == Stance.Ally)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.HasTrait<IgnoresDisguise>())
|
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo<IgnoresDisguiseInfo>())
|
||||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Ally;
|
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Ally;
|
||||||
|
|
||||||
return stance == Stance.Ally;
|
return stance == Stance.Ally;
|
||||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common
|
|||||||
if (stance == Stance.Ally)
|
if (stance == Stance.Ally)
|
||||||
return false; /* otherwise, we'll hate friendly disguised spies */
|
return false; /* otherwise, we'll hate friendly disguised spies */
|
||||||
|
|
||||||
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.HasTrait<IgnoresDisguise>())
|
if (self.EffectiveOwner != null && self.EffectiveOwner.Disguised && !toActor.Info.HasTraitInfo<IgnoresDisguiseInfo>())
|
||||||
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Enemy;
|
return toActor.Owner.Stances[self.EffectiveOwner.Owner] == Stance.Enemy;
|
||||||
|
|
||||||
return stance == Stance.Enemy;
|
return stance == Stance.Enemy;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Commands
|
|||||||
var leveluporder = new Order("DevLevelUp", actor, false);
|
var leveluporder = new Order("DevLevelUp", actor, false);
|
||||||
leveluporder.ExtraData = (uint)level;
|
leveluporder.ExtraData = (uint)level;
|
||||||
|
|
||||||
if (actor.HasTrait<GainsExperience>())
|
if (actor.Info.HasTraitInfo<GainsExperienceInfo>())
|
||||||
world.IssueOrder(leveluporder);
|
world.IssueOrder(leveluporder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
preview.GetScale = () => worldRenderer.Viewport.Zoom;
|
preview.GetScale = () => worldRenderer.Viewport.Zoom;
|
||||||
preview.IsVisible = () => editorWidget.CurrentBrush == this;
|
preview.IsVisible = () => editorWidget.CurrentBrush == this;
|
||||||
|
|
||||||
var buildingInfo = actor.Traits.GetOrDefault<BuildingInfo>();
|
var buildingInfo = actor.TraitInfoOrDefault<BuildingInfo>();
|
||||||
if (buildingInfo != null)
|
if (buildingInfo != null)
|
||||||
{
|
{
|
||||||
locationOffset = -FootprintUtils.AdjustForBuildingSize(buildingInfo);
|
locationOffset = -FootprintUtils.AdjustForBuildingSize(buildingInfo);
|
||||||
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
td.Add(new FactionInit(owner.Faction));
|
td.Add(new FactionInit(owner.Faction));
|
||||||
preview.SetPreview(actor, td);
|
preview.SetPreview(actor, td);
|
||||||
|
|
||||||
var ios = actor.Traits.GetOrDefault<IOccupySpaceInfo>();
|
var ios = actor.TraitInfoOrDefault<IOccupySpaceInfo>();
|
||||||
if (ios != null)
|
if (ios != null)
|
||||||
footprint = ios.OccupiedCells(actor, CPos.Zero)
|
footprint = ios.OccupiedCells(actor, CPos.Zero)
|
||||||
.Select(c => c.Key - CPos.Zero)
|
.Select(c => c.Key - CPos.Zero)
|
||||||
@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
cell += locationOffset;
|
cell += locationOffset;
|
||||||
newActorReference.Add(new LocationInit(cell));
|
newActorReference.Add(new LocationInit(cell));
|
||||||
|
|
||||||
var ios = Actor.Traits.GetOrDefault<IOccupySpaceInfo>();
|
var ios = Actor.TraitInfoOrDefault<IOccupySpaceInfo>();
|
||||||
if (ios != null && ios.SharesCell)
|
if (ios != null && ios.SharesCell)
|
||||||
{
|
{
|
||||||
var subcell = editorLayer.FreeSubCellAt(cell);
|
var subcell = editorLayer.FreeSubCellAt(cell);
|
||||||
@@ -116,10 +116,10 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
var initDict = newActorReference.InitDict;
|
var initDict = newActorReference.InitDict;
|
||||||
|
|
||||||
if (Actor.Traits.Contains<IFacingInfo>())
|
if (Actor.HasTraitInfo<IFacingInfo>())
|
||||||
initDict.Add(new FacingInit(facing));
|
initDict.Add(new FacingInit(facing));
|
||||||
|
|
||||||
if (Actor.Traits.Contains<TurretedInfo>())
|
if (Actor.HasTraitInfo<TurretedInfo>())
|
||||||
initDict.Add(new TurretFacingInit(facing));
|
initDict.Add(new TurretFacingInit(facing));
|
||||||
|
|
||||||
editorLayer.Add(newActorReference);
|
editorLayer.Add(newActorReference);
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
contrail.Update(pos);
|
contrail.Update(pos);
|
||||||
|
|
||||||
if (ticks++ >= length || (info.Blockable && world.ActorMap
|
if (ticks++ >= length || (info.Blockable && world.ActorMap
|
||||||
.GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.HasTrait<IBlocksProjectiles>())))
|
.GetUnitsAt(world.Map.CellContaining(pos)).Any(a => a.Info.HasTraitInfo<IBlocksProjectilesInfo>())))
|
||||||
Explode(world);
|
Explode(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Effects
|
|||||||
var shouldExplode = (pos.Z < 0) // Hit the ground
|
var shouldExplode = (pos.Z < 0) // Hit the ground
|
||||||
|| (dist.LengthSquared < info.CloseEnough.LengthSquared) // Within range
|
|| (dist.LengthSquared < info.CloseEnough.LengthSquared) // Within range
|
||||||
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
|| (info.RangeLimit != 0 && ticks > info.RangeLimit) // Ran out of fuel
|
||||||
|| (info.Blockable && world.ActorMap.GetUnitsAt(cell).Any(a => a.HasTrait<IBlocksProjectiles>())) // 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.
|
|| !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
|
|| (!string.IsNullOrEmpty(info.BoundToTerrainType) && world.Map.GetTerrainInfo(cell).Type != info.BoundToTerrainType); // Hit incompatible terrain
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
emitError("Actor type `{0}` defines multiple default visibility types!".F(actorInfo.Key));
|
emitError("Actor type `{0}` defines multiple default visibility types!".F(actorInfo.Key));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var vis = actorInfo.Value.Traits.GetOrDefault<HiddenUnderShroudInfo>();
|
var vis = actorInfo.Value.TraitInfoOrDefault<HiddenUnderShroudInfo>();
|
||||||
if (vis != null && vis.Type == VisibilityType.Footprint)
|
if (vis != null && vis.Type == VisibilityType.Footprint)
|
||||||
{
|
{
|
||||||
var ios = actorInfo.Value.Traits.GetOrDefault<IOccupySpaceInfo>();
|
var ios = actorInfo.Value.TraitInfoOrDefault<IOccupySpaceInfo>();
|
||||||
if (ios == null)
|
if (ios == null)
|
||||||
emitError("Actor type `{0}` defines VisibilityType.Footprint in `{1}` but has no IOccupySpace traits!".F(actorInfo.Key, vis.GetType()));
|
emitError("Actor type `{0}` defines VisibilityType.Footprint in `{1}` but has no IOccupySpace traits!".F(actorInfo.Key, vis.GetType()));
|
||||||
else if (!ios.OccupiedCells(actorInfo.Value, CPos.Zero).Any())
|
else if (!ios.OccupiedCells(actorInfo.Value, CPos.Zero).Any())
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction))
|
if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction))
|
||||||
emitError("Invalid faction {0} chosen for player {1}.".F(player.Faction, player.Name));
|
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 multiPlayers = players.Count(p => p.Value.Playable);
|
||||||
var spawns = map.ActorDefinitions.Where(a => a.Value.Value == "mpspawn");
|
var spawns = map.ActorDefinitions.Where(a => a.Value.Value == "mpspawn");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
if (actorInfo.Key.StartsWith("^"))
|
if (actorInfo.Key.StartsWith("^"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ios = actorInfo.Value.Traits.GetOrDefault<IOccupySpaceInfo>();
|
var ios = actorInfo.Value.TraitInfoOrDefault<IOccupySpaceInfo>();
|
||||||
foreach (var rsi in actorInfo.Value.Traits.WithInterface<RevealsShroudInfo>())
|
foreach (var rsi in actorInfo.Value.Traits.WithInterface<RevealsShroudInfo>())
|
||||||
{
|
{
|
||||||
if (rsi.Type == VisibilityType.CenterPosition)
|
if (rsi.Type == VisibilityType.CenterPosition)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
// TODO: this check is case insensitive while the real check in-game is not
|
// TODO: this check is case insensitive while the real check in-game is not
|
||||||
foreach (var i in rules.Actors)
|
foreach (var i in rules.Actors)
|
||||||
{
|
{
|
||||||
var bi = i.Value.Traits.GetOrDefault<BuildableInfo>();
|
var bi = i.Value.TraitInfoOrDefault<BuildableInfo>();
|
||||||
if (bi != null)
|
if (bi != null)
|
||||||
foreach (var prereq in bi.Prerequisites)
|
foreach (var prereq in bi.Prerequisites)
|
||||||
if (!prereq.StartsWith("~disabled"))
|
if (!prereq.StartsWith("~disabled"))
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Orders
|
namespace OpenRA.Mods.Common.Orders
|
||||||
{
|
{
|
||||||
public class EnterAlliedActorTargeter<T> : UnitOrderTargeter
|
public class EnterAlliedActorTargeter<T> : UnitOrderTargeter where T : ITraitInfo
|
||||||
{
|
{
|
||||||
readonly Func<Actor, bool> canTarget;
|
readonly Func<Actor, bool> canTarget;
|
||||||
readonly Func<Actor, bool> useEnterCursor;
|
readonly Func<Actor, bool> useEnterCursor;
|
||||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
|
|
||||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
if (!target.HasTrait<T>() || !canTarget(target))
|
if (!target.Info.HasTraitInfo<T>() || !canTarget(target))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
|
cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name)
|
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name)
|
||||||
{
|
{
|
||||||
producer = queue.Actor;
|
producer = queue.Actor;
|
||||||
placeBuildingInfo = producer.Owner.PlayerActor.Info.Traits.Get<PlaceBuildingInfo>();
|
placeBuildingInfo = producer.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>();
|
||||||
building = name;
|
building = name;
|
||||||
|
|
||||||
// Clear selection if using Left-Click Orders
|
// Clear selection if using Left-Click Orders
|
||||||
@@ -46,9 +46,9 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
var tileset = producer.World.TileSet.Id.ToLowerInvariant();
|
var tileset = producer.World.TileSet.Id.ToLowerInvariant();
|
||||||
|
|
||||||
var info = map.Rules.Actors[building];
|
var info = map.Rules.Actors[building];
|
||||||
buildingInfo = info.Traits.Get<BuildingInfo>();
|
buildingInfo = info.TraitInfo<BuildingInfo>();
|
||||||
|
|
||||||
var buildableInfo = info.Traits.Get<BuildableInfo>();
|
var buildableInfo = info.TraitInfo<BuildableInfo>();
|
||||||
var mostLikelyProducer = queue.MostLikelyProducer();
|
var mostLikelyProducer = queue.MostLikelyProducer();
|
||||||
faction = buildableInfo.ForceFaction
|
faction = buildableInfo.ForceFaction
|
||||||
?? (mostLikelyProducer.Trait != null ? mostLikelyProducer.Trait.Faction : producer.Owner.Faction.InternalName);
|
?? (mostLikelyProducer.Trait != null ? mostLikelyProducer.Trait.Faction : producer.Owner.Faction.InternalName);
|
||||||
@@ -81,7 +81,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
var orderType = "PlaceBuilding";
|
var orderType = "PlaceBuilding";
|
||||||
var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
|
var topLeft = xy - FootprintUtils.AdjustForBuildingSize(buildingInfo);
|
||||||
|
|
||||||
var plugInfo = world.Map.Rules.Actors[building].Traits.GetOrDefault<PlugInfo>();
|
var plugInfo = world.Map.Rules.Actors[building].TraitInfoOrDefault<PlugInfo>();
|
||||||
if (plugInfo != null)
|
if (plugInfo != null)
|
||||||
{
|
{
|
||||||
orderType = "PlacePlug";
|
orderType = "PlacePlug";
|
||||||
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world.Map.Rules.Actors[building].Traits.Contains<LineBuildInfo>())
|
if (world.Map.Rules.Actors[building].HasTraitInfo<LineBuildInfo>())
|
||||||
orderType = "LineBuild";
|
orderType = "LineBuild";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
|
|
||||||
var cells = new Dictionary<CPos, bool>();
|
var cells = new Dictionary<CPos, bool>();
|
||||||
|
|
||||||
var plugInfo = rules.Actors[building].Traits.GetOrDefault<PlugInfo>();
|
var plugInfo = rules.Actors[building].TraitInfoOrDefault<PlugInfo>();
|
||||||
if (plugInfo != null)
|
if (plugInfo != null)
|
||||||
{
|
{
|
||||||
if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
|
if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
|
||||||
@@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
|
|
||||||
cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
|
cells.Add(topLeft, AcceptsPlug(topLeft, plugInfo));
|
||||||
}
|
}
|
||||||
else if (rules.Actors[building].Traits.Contains<LineBuildInfo>())
|
else if (rules.Actors[building].HasTraitInfo<LineBuildInfo>())
|
||||||
{
|
{
|
||||||
// Linebuild for walls.
|
// Linebuild for walls.
|
||||||
if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
|
if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
// Repair a building.
|
// 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 };
|
yield return new Order("RepairBuilding", world.LocalPlayer.PlayerActor, false) { TargetActor = underCursor };
|
||||||
|
|
||||||
// Test for generic Repairable (used on units).
|
// Test for generic Repairable (used on units).
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
if (!Context.World.Map.Rules.Actors.TryGetValue(type, out ai))
|
if (!Context.World.Map.Rules.Actors.TryGetValue(type, out ai))
|
||||||
throw new LuaException("Unknown actor type '{0}'".F(type));
|
throw new LuaException("Unknown actor type '{0}'".F(type));
|
||||||
|
|
||||||
var pi = ai.Traits.GetOrDefault<ICruiseAltitudeInfo>();
|
var pi = ai.TraitInfoOrDefault<ICruiseAltitudeInfo>();
|
||||||
return pi != null ? pi.GetCruiseAltitude().Length : 0;
|
return pi != null ? pi.GetCruiseAltitude().Length : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
|
|
||||||
if (entryLocation.HasValue)
|
if (entryLocation.HasValue)
|
||||||
{
|
{
|
||||||
var pi = ai.Traits.GetOrDefault<AircraftInfo>();
|
var pi = ai.TraitInfoOrDefault<AircraftInfo>();
|
||||||
initDict.Add(new CenterPositionInit(owner.World.Map.CenterOfCell(entryLocation.Value) + new WVec(0, 0, pi != null ? pi.CruiseAltitude.Length : 0)));
|
initDict.Add(new CenterPositionInit(owner.World.Map.CenterOfCell(entryLocation.Value) + new WVec(0, 0, pi != null ? pi.CruiseAltitude.Length : 0)));
|
||||||
initDict.Add(new LocationInit(entryLocation.Value));
|
initDict.Add(new LocationInit(entryLocation.Value));
|
||||||
}
|
}
|
||||||
@@ -137,10 +137,10 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var heli = transport.TraitOrDefault<Helicopter>();
|
var heli = transport.Info.TraitInfoOrDefault<HelicopterInfo>();
|
||||||
if (heli != null)
|
if (heli != null)
|
||||||
{
|
{
|
||||||
transport.QueueActivity(new Turn(transport, heli.Info.InitialFacing));
|
transport.QueueActivity(new Turn(transport, heli.InitialFacing));
|
||||||
transport.QueueActivity(new HeliLand(transport, true));
|
transport.QueueActivity(new HeliLand(transport, true));
|
||||||
transport.QueueActivity(new Wait(15));
|
transport.QueueActivity(new Wait(15));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
public CaptureProperties(ScriptContext context, Actor self)
|
public CaptureProperties(ScriptContext context, Actor self)
|
||||||
: base(context, self)
|
: base(context, self)
|
||||||
{
|
{
|
||||||
normalInfo = Self.Info.Traits.GetOrDefault<CapturesInfo>();
|
normalInfo = Self.Info.TraitInfoOrDefault<CapturesInfo>();
|
||||||
externalInfo = Self.Info.Traits.GetOrDefault<ExternalCapturesInfo>();
|
externalInfo = Self.Info.TraitInfoOrDefault<ExternalCapturesInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Desc("Captures the target actor.")]
|
[Desc("Captures the target actor.")]
|
||||||
public void Capture(Actor target)
|
public void Capture(Actor target)
|
||||||
{
|
{
|
||||||
var normalCapturable = target.Info.Traits.GetOrDefault<CapturableInfo>();
|
var normalCapturable = target.Info.TraitInfoOrDefault<CapturableInfo>();
|
||||||
var externalCapturable = target.Info.Traits.GetOrDefault<ExternalCapturableInfo>();
|
var externalCapturable = target.Info.TraitInfoOrDefault<ExternalCapturableInfo>();
|
||||||
|
|
||||||
if (normalInfo != null && normalCapturable != null && normalInfo.CaptureTypes.Contains(normalCapturable.Type))
|
if (normalInfo != null && normalCapturable != null && normalInfo.CaptureTypes.Contains(normalCapturable.Type))
|
||||||
Self.QueueActivity(new CaptureActor(Self, target));
|
Self.QueueActivity(new CaptureActor(Self, target));
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
if (!target.IsValidFor(Self) || target.Type == TargetType.FrozenActor)
|
if (!target.IsValidFor(Self) || target.Type == TargetType.FrozenActor)
|
||||||
Log.Write("lua", "{1} is an invalid target for {0}!", Self, targetActor);
|
Log.Write("lua", "{1} is an invalid target for {0}!", Self, targetActor);
|
||||||
|
|
||||||
if (!targetActor.HasTrait<FrozenUnderFog>() && !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);
|
Log.Write("lua", "{1} is not revealed for player {0}!", Self.Owner, targetActor);
|
||||||
|
|
||||||
attackBase.AttackTarget(target, true, allowMove);
|
attackBase.AttackTarget(target, true, allowMove);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
public DemolitionProperties(ScriptContext context, Actor self)
|
public DemolitionProperties(ScriptContext context, Actor self)
|
||||||
: base(context, self)
|
: base(context, self)
|
||||||
{
|
{
|
||||||
info = Self.Info.Traits.Get<C4DemolitionInfo>();
|
info = Self.Info.TraitInfo<C4DemolitionInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ScriptActorPropertyActivity]
|
[ScriptActorPropertyActivity]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
[Desc("Guard the target actor.")]
|
[Desc("Guard the target actor.")]
|
||||||
public void Guard(Actor targetActor)
|
public void Guard(Actor targetActor)
|
||||||
{
|
{
|
||||||
if (targetActor.HasTrait<Guardable>())
|
if (targetActor.Info.HasTraitInfo<GuardableInfo>())
|
||||||
guard.GuardTarget(Self, Target.FromActor(targetActor));
|
guard.GuardTarget(Self, Target.FromActor(targetActor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
public Actor[] GetGroundAttackers()
|
public Actor[] GetGroundAttackers()
|
||||||
{
|
{
|
||||||
return Player.World.ActorsWithTrait<AttackBase>().Select(a => a.Actor)
|
return Player.World.ActorsWithTrait<AttackBase>().Select(a => a.Actor)
|
||||||
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.HasTrait<Mobile>())
|
.Where(a => a.Owner == Player && !a.IsDead && a.IsInWorld && a.Info.HasTraitInfo<MobileInfo>())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
BuildableInfo GetBuildableInfo(string actorType)
|
BuildableInfo GetBuildableInfo(string actorType)
|
||||||
{
|
{
|
||||||
var ri = Self.World.Map.Rules.Actors[actorType];
|
var ri = Self.World.Map.Rules.Actors[actorType];
|
||||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
var bi = ri.TraitInfoOrDefault<BuildableInfo>();
|
||||||
|
|
||||||
if (bi == null)
|
if (bi == null)
|
||||||
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
||||||
@@ -267,7 +267,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
BuildableInfo GetBuildableInfo(string actorType)
|
BuildableInfo GetBuildableInfo(string actorType)
|
||||||
{
|
{
|
||||||
var ri = Player.World.Map.Rules.Actors[actorType];
|
var ri = Player.World.Map.Rules.Actors[actorType];
|
||||||
var bi = ri.Traits.GetOrDefault<BuildableInfo>();
|
var bi = ri.TraitInfoOrDefault<BuildableInfo>();
|
||||||
|
|
||||||
if (bi == null)
|
if (bi == null)
|
||||||
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
throw new LuaException("Actor of type {0} cannot be produced".F(actorType));
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public class AircraftInfo : ITraitInfo, IFacingInfo, IOccupySpaceInfo, ICruiseAltitudeInfo, UsesInit<LocationInit>, UsesInit<FacingInit>
|
public class AircraftInfo : IPositionableInfo, IFacingInfo, IOccupySpaceInfo, ICruiseAltitudeInfo, UsesInit<LocationInit>, UsesInit<FacingInit>
|
||||||
{
|
{
|
||||||
public readonly WDist CruiseAltitude = new WDist(1280);
|
public readonly WDist CruiseAltitude = new WDist(1280);
|
||||||
public readonly WDist IdealSeparation = new WDist(1706);
|
public readonly WDist IdealSeparation = new WDist(1706);
|
||||||
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
firstTick = false;
|
firstTick = false;
|
||||||
|
|
||||||
// TODO: Aircraft husks don't properly unreserve.
|
// TODO: Aircraft husks don't properly unreserve.
|
||||||
if (self.HasTrait<FallsToEarth>())
|
if (self.Info.HasTraitInfo<FallsToEarthInfo>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ReserveSpawnBuilding();
|
ReserveSpawnBuilding();
|
||||||
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return WVec.Zero;
|
return WVec.Zero;
|
||||||
|
|
||||||
return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation)
|
return self.World.FindActorsInCircle(self.CenterPosition, info.IdealSeparation)
|
||||||
.Where(a => !a.IsDead && a.HasTrait<Aircraft>() && a.Info.Traits.Get<AircraftInfo>().CruiseAltitude == info.CruiseAltitude)
|
.Where(a => !a.IsDead && a.Info.HasTraitInfo<AircraftInfo>() && a.Info.TraitInfo<AircraftInfo>().CruiseAltitude == info.CruiseAltitude)
|
||||||
.Select(GetRepulsionForce)
|
.Select(GetRepulsionForce)
|
||||||
.Aggregate(WVec.Zero, (a, b) => a + b);
|
.Aggregate(WVec.Zero, (a, b) => a + b);
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return null; // not on the ground.
|
return null; // not on the ground.
|
||||||
|
|
||||||
return self.World.ActorMap.GetUnitsAt(self.Location)
|
return self.World.ActorMap.GetUnitsAt(self.Location)
|
||||||
.FirstOrDefault(a => a.HasTrait<Reservable>());
|
.FirstOrDefault(a => a.Info.HasTraitInfo<ReservableInfo>());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ReserveSpawnBuilding()
|
protected void ReserveSpawnBuilding()
|
||||||
@@ -341,7 +341,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new EnterAlliedActorTargeter<Building>("Enter", 5,
|
yield return new EnterAlliedActorTargeter<BuildingInfo>("Enter", 5,
|
||||||
target => AircraftCanEnter(target), target => !Reservable.IsReserved(target));
|
target => AircraftCanEnter(target), target => !Reservable.IsReserved(target));
|
||||||
|
|
||||||
yield return new AircraftMoveOrderTargeter(info);
|
yield return new AircraftMoveOrderTargeter(info);
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public bool IsReachableTarget(Target target, bool allowMove)
|
public bool IsReachableTarget(Target target, bool allowMove)
|
||||||
{
|
{
|
||||||
return HasAnyValidWeapons(target)
|
return HasAnyValidWeapons(target)
|
||||||
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.HasTrait<IMove>()));
|
&& (target.IsInRange(self.CenterPosition, GetMaximumRange()) || (allowMove && self.Info.HasTraitInfo<IMoveInfo>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttackOrderTargeter : IOrderTargeter
|
class AttackOrderTargeter : IOrderTargeter
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var weapon = attack.ChooseArmamentForTarget(target);
|
var weapon = attack.ChooseArmamentForTarget(target);
|
||||||
if (weapon != null)
|
if (weapon != null)
|
||||||
{
|
{
|
||||||
var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.HasTrait<IMove>())
|
var targetIsMobile = (target.Type == TargetType.Actor && target.Actor.Info.HasTraitInfo<IMoveInfo>())
|
||||||
|| (target.Type == TargetType.FrozenActor && target.FrozenActor.Info.Traits.Contains<IMove>());
|
|| (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.
|
// 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))
|
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
|
return inRange
|
||||||
.Where(a =>
|
.Where(a =>
|
||||||
a.AppearsHostileTo(self) &&
|
a.AppearsHostileTo(self) &&
|
||||||
!a.HasTrait<AutoTargetIgnore>() &&
|
!a.Info.HasTraitInfo<AutoTargetIgnoreInfo>() &&
|
||||||
attack.HasAnyValidWeapons(Target.FromActor(a)) &&
|
attack.HasAnyValidWeapons(Target.FromActor(a)) &&
|
||||||
self.Owner.CanTargetActor(a))
|
self.Owner.CanTargetActor(a))
|
||||||
.ClosestTo(self);
|
.ClosestTo(self);
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
// TODO: Add functionality like a customizable Height that is compared to projectile altitude
|
// TODO: Add functionality like a customizable Height that is compared to projectile altitude
|
||||||
[Desc("This actor blocks bullets and missiles with 'Blockable' property.")]
|
[Desc("This actor blocks bullets and missiles with 'Blockable' property.")]
|
||||||
public class BlocksProjectilesInfo : TraitInfo<BlocksProjectiles> { }
|
public class BlocksProjectilesInfo : TraitInfo<BlocksProjectiles>, IBlocksProjectilesInfo { }
|
||||||
public class BlocksProjectiles : IBlocksProjectiles { }
|
public class BlocksProjectiles : IBlocksProjectiles { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,12 +72,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (info.QuantizedFacings >= 0)
|
if (info.QuantizedFacings >= 0)
|
||||||
return info.QuantizedFacings;
|
return info.QuantizedFacings;
|
||||||
|
|
||||||
var qboi = self.Info.Traits.GetOrDefault<IQuantizeBodyOrientationInfo>();
|
var qboi = self.Info.TraitInfoOrDefault<IQuantizeBodyOrientationInfo>();
|
||||||
|
|
||||||
// If a sprite actor has neither custom QuantizedFacings nor a trait implementing IQuantizeBodyOrientationInfo, throw
|
// If a sprite actor has neither custom QuantizedFacings nor a trait implementing IQuantizeBodyOrientationInfo, throw
|
||||||
if (qboi == null)
|
if (qboi == null)
|
||||||
{
|
{
|
||||||
if (self.HasTrait<ISpriteBody>())
|
if (self.Info.HasTraitInfo<ISpriteBodyInfo>())
|
||||||
throw new InvalidOperationException("Actor '" + self.Info.Name + "' has a sprite body but no facing quantization."
|
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.");
|
+ " Either add the QuantizeFacingsFromSequence trait or set custom QuantizedFacings on BodyOrientation.");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (Palette != null)
|
if (Palette != null)
|
||||||
p = init.WorldRenderer.Palette(Palette);
|
p = init.WorldRenderer.Palette(Palette);
|
||||||
|
|
||||||
var bi = init.Actor.Traits.Get<BuildingInfo>();
|
var bi = init.Actor.TraitInfo<BuildingInfo>();
|
||||||
|
|
||||||
var width = bi.Dimensions.X;
|
var width = bi.Dimensions.X;
|
||||||
var bibOffset = bi.Dimensions.Y - 1;
|
var bibOffset = bi.Dimensions.Y - 1;
|
||||||
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
this.info = info;
|
this.info = info;
|
||||||
rs = self.Trait<RenderSprites>();
|
rs = self.Trait<RenderSprites>();
|
||||||
bi = self.Info.Traits.Get<BuildingInfo>();
|
bi = self.Info.TraitInfo<BuildingInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddedToWorld(Actor self)
|
public void AddedToWorld(Actor self)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
class Bridge : IRender, INotifyDamageStateChanged
|
class Bridge : IRender, INotifyDamageStateChanged
|
||||||
{
|
{
|
||||||
readonly Building building;
|
readonly BuildingInfo building;
|
||||||
readonly Bridge[] neighbours = new Bridge[2];
|
readonly Bridge[] neighbours = new Bridge[2];
|
||||||
readonly BridgeHut[] huts = new BridgeHut[2]; // Huts before this / first & after this / last
|
readonly BridgeHut[] huts = new BridgeHut[2]; // Huts before this / first & after this / last
|
||||||
readonly Health health;
|
readonly Health health;
|
||||||
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
this.info = info;
|
this.info = info;
|
||||||
type = self.Info.Name;
|
type = self.Info.Name;
|
||||||
isDangling = new Lazy<bool>(() => huts[0] == huts[1] && (neighbours[0] == null || neighbours[1] == null));
|
isDangling = new Lazy<bool>(() => huts[0] == huts[1] && (neighbours[0] == null || neighbours[1] == null));
|
||||||
building = self.Trait<Building>();
|
building = self.Info.TraitInfo<BuildingInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bridge Neighbour(int direction) { return neighbours[direction]; }
|
public Bridge Neighbour(int direction) { return neighbours[direction]; }
|
||||||
@@ -173,7 +173,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
IRenderable[] TemplateRenderables(WorldRenderer wr, PaletteReference palette, ushort template)
|
IRenderable[] TemplateRenderables(WorldRenderer wr, PaletteReference palette, ushort template)
|
||||||
{
|
{
|
||||||
var offset = FootprintUtils.CenterOffset(self.World, building.Info).Y + 1024;
|
var offset = FootprintUtils.CenterOffset(self.World, building).Y + 1024;
|
||||||
|
|
||||||
return footprint.Select(c => (IRenderable)(new SpriteRenderable(
|
return footprint.Select(c => (IRenderable)(new SpriteRenderable(
|
||||||
wr.Theater.TileSprite(new TerrainTile(template, c.Value)),
|
wr.Theater.TileSprite(new TerrainTile(template, c.Value)),
|
||||||
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
foreach (var c in footprint.Keys)
|
foreach (var c in footprint.Keys)
|
||||||
foreach (var a in self.World.ActorMap.GetUnitsAt(c))
|
foreach (var a in self.World.ActorMap.GetUnitsAt(c))
|
||||||
if (a.HasTrait<IPositionable>() && !a.Trait<IPositionable>().CanEnterCell(c))
|
if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c))
|
||||||
a.Kill(self);
|
a.Kill(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var buildingMaxBounds = Dimensions;
|
var buildingMaxBounds = Dimensions;
|
||||||
var buildingTraits = world.Map.Rules.Actors[buildingName].Traits;
|
var bibInfo = world.Map.Rules.Actors[buildingName].TraitInfoOrDefault<BibInfo>();
|
||||||
if (buildingTraits.Contains<BibInfo>() && !buildingTraits.Get<BibInfo>().HasMinibib)
|
if (bibInfo != null && !bibInfo.HasMinibib)
|
||||||
buildingMaxBounds += new CVec(0, 1);
|
buildingMaxBounds += new CVec(0, 1);
|
||||||
|
|
||||||
var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent));
|
var scanStart = world.Map.Clamp(topLeft - new CVec(Adjacent, Adjacent));
|
||||||
@@ -87,12 +87,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var unitsAtPos = world.ActorMap.GetUnitsAt(pos).Where(a => a.IsInWorld
|
var unitsAtPos = world.ActorMap.GetUnitsAt(pos).Where(a => a.IsInWorld
|
||||||
&& (a.Owner == p || (allyBuildRadius && a.Owner.Stances[p] == Stance.Ally))
|
&& (a.Owner == p || (allyBuildRadius && a.Owner.Stances[p] == Stance.Ally))
|
||||||
&& a.HasTrait<GivesBuildableArea>());
|
&& a.Info.HasTraitInfo<GivesBuildableAreaInfo>());
|
||||||
|
|
||||||
if (unitsAtPos.Any())
|
if (unitsAtPos.Any())
|
||||||
nearnessCandidates.Add(pos);
|
nearnessCandidates.Add(pos);
|
||||||
}
|
}
|
||||||
else if (buildingAtPos.IsInWorld && buildingAtPos.HasTrait<GivesBuildableArea>()
|
else if (buildingAtPos.IsInWorld && buildingAtPos.Info.HasTraitInfo<GivesBuildableAreaInfo>()
|
||||||
&& (buildingAtPos.Owner == p || (allyBuildRadius && buildingAtPos.Owner.Stances[p] == Stance.Ally)))
|
&& (buildingAtPos.Owner == p || (allyBuildRadius && buildingAtPos.Owner.Stances[p] == Stance.Ally)))
|
||||||
nearnessCandidates.Add(pos);
|
nearnessCandidates.Add(pos);
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void Created(Actor self)
|
public void Created(Actor self)
|
||||||
{
|
{
|
||||||
if (SkipMakeAnimation || !self.HasTrait<WithMakeAnimation>())
|
if (SkipMakeAnimation || !self.Info.HasTraitInfo<WithMakeAnimationInfo>())
|
||||||
NotifyBuildingComplete(self);
|
NotifyBuildingComplete(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,22 +31,22 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
world.ActorAdded += a =>
|
world.ActorAdded += a =>
|
||||||
{
|
{
|
||||||
var b = a.TraitOrDefault<Building>();
|
var b = a.Info.TraitInfoOrDefault<BuildingInfo>();
|
||||||
if (b == null)
|
if (b == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b.Info, a.Location))
|
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location))
|
||||||
if (influence.Contains(u) && influence[u] == null)
|
if (influence.Contains(u) && influence[u] == null)
|
||||||
influence[u] = a;
|
influence[u] = a;
|
||||||
};
|
};
|
||||||
|
|
||||||
world.ActorRemoved += a =>
|
world.ActorRemoved += a =>
|
||||||
{
|
{
|
||||||
var b = a.TraitOrDefault<Building>();
|
var b = a.Info.TraitInfoOrDefault<BuildingInfo>();
|
||||||
if (b == null)
|
if (b == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b.Info, a.Location))
|
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b, a.Location))
|
||||||
if (influence.Contains(u) && influence[u] == a)
|
if (influence.Contains(u) && influence[u] == a)
|
||||||
influence[u] = null;
|
influence[u] = null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public static IEnumerable<CPos> GetLineBuildCells(World world, CPos location, string name, BuildingInfo bi)
|
public static IEnumerable<CPos> GetLineBuildCells(World world, CPos location, string name, BuildingInfo bi)
|
||||||
{
|
{
|
||||||
var lbi = world.Map.Rules.Actors[name].Traits.Get<LineBuildInfo>();
|
var lbi = world.Map.Rules.Actors[name].TraitInfo<LineBuildInfo>();
|
||||||
var topLeft = location; // 1x1 assumption!
|
var topLeft = location; // 1x1 assumption!
|
||||||
|
|
||||||
if (world.IsCellBuildable(topLeft, bi))
|
if (world.IsCellBuildable(topLeft, bi))
|
||||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// Cell contains an actor. Is it the type we want?
|
// Cell contains an actor. Is it the type we want?
|
||||||
if (world.ActorsWithTrait<LineBuildNode>().Any(a =>
|
if (world.ActorsWithTrait<LineBuildNode>().Any(a =>
|
||||||
(a.Actor.Location == cell &&
|
(a.Actor.Location == cell &&
|
||||||
a.Actor.Info.Traits.Get<LineBuildNodeInfo>()
|
a.Actor.Info.TraitInfo<LineBuildNodeInfo>()
|
||||||
.Types.Overlaps(lbi.NodeTypes))))
|
.Types.Overlaps(lbi.NodeTypes))))
|
||||||
dirs[d] = i; // Cell contains actor of correct type
|
dirs[d] = i; // Cell contains actor of correct type
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
||||||
|
|
||||||
var buildingTraits = rules.Actors[name].Traits;
|
var bibInfo = rules.Actors[name].TraitInfoOrDefault<BibInfo>();
|
||||||
if (buildingTraits.Contains<BibInfo>() && !buildingTraits.Get<BibInfo>().HasMinibib)
|
if (bibInfo != null && !bibInfo.HasMinibib)
|
||||||
{
|
{
|
||||||
dim += new CVec(0, 1);
|
dim += new CVec(0, 1);
|
||||||
footprint = footprint.Concat(new char[dim.X]);
|
footprint = footprint.Concat(new char[dim.X]);
|
||||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public static IEnumerable<CPos> Tiles(Actor a)
|
public static IEnumerable<CPos> Tiles(Actor a)
|
||||||
{
|
{
|
||||||
return Tiles(a.World.Map.Rules, a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), a.Location);
|
return Tiles(a.World.Map.Rules, a.Info.Name, a.Info.TraitInfo<BuildingInfo>(), a.Location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<CPos> UnpathableTiles(string name, BuildingInfo buildingInfo, CPos position)
|
public static IEnumerable<CPos> UnpathableTiles(string name, BuildingInfo buildingInfo, CPos position)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
// TODO: THIS IS SHIT
|
// TODO: THIS IS SHIT
|
||||||
// Cancel existing primaries
|
// Cancel existing primaries
|
||||||
foreach (var p in self.Info.Traits.Get<ProductionInfo>().Produces)
|
foreach (var p in self.Info.TraitInfo<ProductionInfo>().Produces)
|
||||||
{
|
{
|
||||||
var productionType = p; // benign closure hazard
|
var productionType = p; // benign closure hazard
|
||||||
foreach (var b in self.World
|
foreach (var b in self.World
|
||||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
.Where(a =>
|
.Where(a =>
|
||||||
a.Actor.Owner == self.Owner &&
|
a.Actor.Owner == self.Owner &&
|
||||||
a.Trait.IsPrimary &&
|
a.Trait.IsPrimary &&
|
||||||
a.Actor.Info.Traits.Get<ProductionInfo>().Produces.Contains(productionType)))
|
a.Actor.Info.TraitInfo<ProductionInfo>().Produces.Contains(productionType)))
|
||||||
b.Trait.SetPrimaryProducer(b.Actor, false);
|
b.Trait.SetPrimaryProducer(b.Actor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public class RefineryInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
|
public class RefineryInfo : IAcceptResourcesInfo, Requires<WithSpriteBodyInfo>
|
||||||
{
|
{
|
||||||
[Desc("Actual harvester facing when docking, 0-255 counter-clock-wise.")]
|
[Desc("Actual harvester facing when docking, 0-255 counter-clock-wise.")]
|
||||||
public readonly int DockAngle = 0;
|
public readonly int DockAngle = 0;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public bool CanBeTargetedBy(Actor captor, Player owner)
|
public bool CanBeTargetedBy(Actor captor, Player owner)
|
||||||
{
|
{
|
||||||
var c = captor.TraitOrDefault<Captures>();
|
var c = captor.Info.TraitInfoOrDefault<CapturesInfo>();
|
||||||
if (c == null)
|
if (c == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (playerRelationship == Stance.Neutral && !AllowNeutral)
|
if (playerRelationship == Stance.Neutral && !AllowNeutral)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!c.Info.CaptureTypes.Contains(Type))
|
if (!c.CaptureTypes.Contains(Type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
var c = target.Info.Traits.GetOrDefault<CapturableInfo>();
|
var c = target.Info.TraitInfoOrDefault<CapturableInfo>();
|
||||||
if (c == null || !c.CanBeTargetedBy(self, target.Owner))
|
if (c == null || !c.CanBeTargetedBy(self, target.Owner))
|
||||||
{
|
{
|
||||||
cursor = "enter-blocked";
|
cursor = "enter-blocked";
|
||||||
@@ -109,14 +109,14 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
var c = target.Info.Traits.GetOrDefault<CapturableInfo>();
|
var c = target.Info.TraitInfoOrDefault<CapturableInfo>();
|
||||||
if (c == null || !c.CanBeTargetedBy(self, target.Owner))
|
if (c == null || !c.CanBeTargetedBy(self, target.Owner))
|
||||||
{
|
{
|
||||||
cursor = "enter-blocked";
|
cursor = "enter-blocked";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var health = target.Info.Traits.GetOrDefault<HealthInfo>();
|
var health = target.Info.TraitInfoOrDefault<HealthInfo>();
|
||||||
var lowEnoughHealth = target.HP <= c.CaptureThreshold * health.HP;
|
var lowEnoughHealth = target.HP <= c.CaptureThreshold * health.HP;
|
||||||
|
|
||||||
cursor = !sabotage || lowEnoughHealth || target.Owner.NonCombatant
|
cursor = !sabotage || lowEnoughHealth || target.Owner.NonCombatant
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
helicopter = self.TraitOrDefault<Helicopter>();
|
helicopter = self.TraitOrDefault<Helicopter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetWeight(Actor a) { return a.Info.Traits.Get<PassengerInfo>().Weight; }
|
static int GetWeight(Actor a) { return a.Info.TraitInfo<PassengerInfo>().Weight; }
|
||||||
|
|
||||||
public IEnumerable<IOrderTargeter> Orders
|
public IEnumerable<IOrderTargeter> Orders
|
||||||
{
|
{
|
||||||
@@ -268,7 +268,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
foreach (var c in cargo)
|
foreach (var c in cargo)
|
||||||
{
|
{
|
||||||
var pi = c.Info.Traits.Get<PassengerInfo>();
|
var pi = c.Info.TraitInfo<PassengerInfo>();
|
||||||
if (n < pi.Weight)
|
if (n < pi.Weight)
|
||||||
return pi.PipType;
|
return pi.PipType;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
readonly DeveloperMode devMode;
|
readonly DeveloperMode devMode;
|
||||||
|
|
||||||
|
readonly HealthInfo healthInfo;
|
||||||
Lazy<AttackBase> attack;
|
Lazy<AttackBase> attack;
|
||||||
Lazy<BodyOrientation> coords;
|
Lazy<BodyOrientation> coords;
|
||||||
Lazy<Health> health;
|
|
||||||
|
|
||||||
public CombatDebugOverlay(Actor self)
|
public CombatDebugOverlay(Actor self)
|
||||||
{
|
{
|
||||||
|
healthInfo = self.Info.TraitInfoOrDefault<HealthInfo>();
|
||||||
attack = Exts.Lazy(() => self.TraitOrDefault<AttackBase>());
|
attack = Exts.Lazy(() => self.TraitOrDefault<AttackBase>());
|
||||||
coords = Exts.Lazy(() => self.Trait<BodyOrientation>());
|
coords = Exts.Lazy(() => self.Trait<BodyOrientation>());
|
||||||
health = Exts.Lazy(() => self.TraitOrDefault<Health>());
|
|
||||||
|
|
||||||
var localPlayer = self.World.LocalPlayer;
|
var localPlayer = self.World.LocalPlayer;
|
||||||
devMode = localPlayer != null ? localPlayer.PlayerActor.Trait<DeveloperMode>() : null;
|
devMode = localPlayer != null ? localPlayer.PlayerActor.Trait<DeveloperMode>() : null;
|
||||||
@@ -45,8 +45,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (devMode == null || !devMode.ShowCombatGeometry)
|
if (devMode == null || !devMode.ShowCombatGeometry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (health.Value != null)
|
if (healthInfo != null)
|
||||||
wr.DrawRangeCircle(self.CenterPosition, health.Value.Info.Radius, Color.Red);
|
wr.DrawRangeCircle(self.CenterPosition, healthInfo.Radius, Color.Red);
|
||||||
|
|
||||||
// No armaments to draw
|
// No armaments to draw
|
||||||
if (attack.Value == null)
|
if (attack.Value == null)
|
||||||
@@ -96,11 +96,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (devMode == null || !devMode.ShowCombatGeometry || e.Damage == 0)
|
if (devMode == null || !devMode.ShowCombatGeometry || e.Damage == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var health = self.TraitOrDefault<Health>();
|
if (healthInfo == null)
|
||||||
if (health == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var damageText = "{0} ({1}%)".F(-e.Damage, e.Damage * 100 / health.MaxHP);
|
var maxHP = healthInfo.HP > 0 ? healthInfo.HP : 1;
|
||||||
|
var damageText = "{0} ({1}%)".F(-e.Damage, e.Damage * 100 / maxHP);
|
||||||
|
|
||||||
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, e.Attacker.Owner.Color.RGB, damageText, 30)));
|
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, e.Attacker.Owner.Color.RGB, damageText, 30)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
class CrateInfo : ITraitInfo, IOccupySpaceInfo, Requires<RenderSpritesInfo>
|
class CrateInfo : IPositionableInfo, IOccupySpaceInfo, Requires<RenderSpritesInfo>
|
||||||
{
|
{
|
||||||
[Desc("Length of time (in seconds) until the crate gets removed automatically. " +
|
[Desc("Length of time (in seconds) until the crate gets removed automatically. " +
|
||||||
"A value of zero disables auto-removal.")]
|
"A value of zero disables auto-removal.")]
|
||||||
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var collector = landedOn.FirstOrDefault(a =>
|
var collector = landedOn.FirstOrDefault(a =>
|
||||||
{
|
{
|
||||||
// Mobile is (currently) the only trait that supports crushing
|
// Mobile is (currently) the only trait that supports crushing
|
||||||
var mi = a.Info.Traits.GetOrDefault<MobileInfo>();
|
var mi = a.Info.TraitInfoOrDefault<MobileInfo>();
|
||||||
if (mi == null)
|
if (mi == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// Restrict duplicate count to a maximum value
|
// Restrict duplicate count to a maximum value
|
||||||
if (info.MaxDuplicateValue > 0)
|
if (info.MaxDuplicateValue > 0)
|
||||||
{
|
{
|
||||||
var vi = collector.Info.Traits.GetOrDefault<ValuedInfo>();
|
var vi = collector.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
if (vi != null && vi.Cost > 0)
|
if (vi != null && vi.Cost > 0)
|
||||||
duplicates = Math.Min(duplicates, info.MaxDuplicateValue / vi.Cost);
|
duplicates = Math.Min(duplicates, info.MaxDuplicateValue / vi.Cost);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
IEnumerable<CPos> GetSuitableCells(CPos near, string unitName)
|
IEnumerable<CPos> GetSuitableCells(CPos near, string unitName)
|
||||||
{
|
{
|
||||||
var mi = self.World.Map.Rules.Actors[unitName].Traits.Get<MobileInfo>();
|
var mi = self.World.Map.Rules.Actors[unitName].TraitInfo<MobileInfo>();
|
||||||
|
|
||||||
for (var i = -1; i < 2; i++)
|
for (var i = -1; i < 2; i++)
|
||||||
for (var j = -1; j < 2; j++)
|
for (var j = -1; j < 2; j++)
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
public static int GetBuildTime(this ActorInfo a)
|
public static int GetBuildTime(this ActorInfo a)
|
||||||
{
|
{
|
||||||
var csv = a.Traits.GetOrDefault<CustomBuildTimeValueInfo>();
|
var csv = a.TraitInfoOrDefault<CustomBuildTimeValueInfo>();
|
||||||
if (csv != null)
|
if (csv != null)
|
||||||
return csv.Value;
|
return csv.Value;
|
||||||
|
|
||||||
var cost = a.Traits.Contains<ValuedInfo>() ? a.Traits.Get<ValuedInfo>().Cost : 0;
|
var cost = a.HasTraitInfo<ValuedInfo>() ? a.TraitInfo<ValuedInfo>().Cost : 0;
|
||||||
var time = cost
|
var time = cost
|
||||||
* (25 * 60) /* frames per min */
|
* (25 * 60) /* frames per min */
|
||||||
/ 1000;
|
/ 1000;
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
public static int GetSellValue(this Actor a)
|
public static int GetSellValue(this Actor a)
|
||||||
{
|
{
|
||||||
var csv = a.Info.Traits.GetOrDefault<CustomSellValueInfo>();
|
var csv = a.Info.TraitInfoOrDefault<CustomSellValueInfo>();
|
||||||
if (csv != null) return csv.Value;
|
if (csv != null) return csv.Value;
|
||||||
|
|
||||||
var valued = a.Info.Traits.GetOrDefault<ValuedInfo>();
|
var valued = a.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
if (valued != null) return valued.Cost;
|
if (valued != null) return valued.Cost;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (!correctFaction)
|
if (!correctFaction)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var csv = self.Info.Traits.GetOrDefault<CustomSellValueInfo>();
|
var csv = self.Info.TraitInfoOrDefault<CustomSellValueInfo>();
|
||||||
var valued = self.Info.Traits.GetOrDefault<ValuedInfo>();
|
var valued = self.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
var cost = csv != null ? csv.Value : (valued != null ? valued.Cost : 0);
|
var cost = csv != null ? csv.Value : (valued != null ? valued.Cost : 0);
|
||||||
|
|
||||||
var health = self.TraitOrDefault<Health>();
|
var health = self.TraitOrDefault<Health>();
|
||||||
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
dudesValue /= 100;
|
dudesValue /= 100;
|
||||||
|
|
||||||
var eligibleLocations = FootprintUtils.Tiles(self).ToList();
|
var eligibleLocations = FootprintUtils.Tiles(self).ToList();
|
||||||
var actorTypes = info.ActorTypes.Select(a => new { Name = a, Cost = self.World.Map.Rules.Actors[a].Traits.Get<ValuedInfo>().Cost }).ToList();
|
var actorTypes = info.ActorTypes.Select(a => new { Name = a, Cost = self.World.Map.Rules.Actors[a].TraitInfo<ValuedInfo>().Cost }).ToList();
|
||||||
|
|
||||||
while (eligibleLocations.Count > 0 && actorTypes.Any(a => a.Cost <= dudesValue))
|
while (eligibleLocations.Count > 0 && actorTypes.Any(a => a.Cost <= dudesValue))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
if (!target.HasTrait<EngineerRepairable>())
|
if (!target.Info.HasTraitInfo<EngineerRepairableInfo>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
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)
|
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
if (!target.Info.Traits.Contains<EngineerRepairable>())
|
if (!target.Info.HasTraitInfo<EngineerRepairableInfo>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
if (self.Owner.Stances[target.Owner] != Stance.Ally)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public bool CanBeTargetedBy(Actor captor, Player owner)
|
public bool CanBeTargetedBy(Actor captor, Player owner)
|
||||||
{
|
{
|
||||||
var c = captor.TraitOrDefault<ExternalCaptures>();
|
var c = captor.Info.TraitInfoOrDefault<ExternalCapturesInfo>();
|
||||||
if (c == null)
|
if (c == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (playerRelationship == Stance.Neutral && !AllowNeutral)
|
if (playerRelationship == Stance.Neutral && !AllowNeutral)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!c.Info.CaptureTypes.Contains(Type))
|
if (!c.CaptureTypes.Contains(Type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (frozen == null)
|
if (frozen == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var ci = frozen.Info.Traits.GetOrDefault<ExternalCapturableInfo>();
|
var ci = frozen.Info.TraitInfoOrDefault<ExternalCapturableInfo>();
|
||||||
return ci != null && ci.CanBeTargetedBy(self, frozen.Owner);
|
return ci != null && ci.CanBeTargetedBy(self, frozen.Owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
var c = target.Info.Traits.GetOrDefault<ExternalCapturableInfo>();
|
var c = target.Info.TraitInfoOrDefault<ExternalCapturableInfo>();
|
||||||
|
|
||||||
var canTargetActor = c != null && c.CanBeTargetedBy(self, target.Owner);
|
var canTargetActor = c != null && c.CanBeTargetedBy(self, target.Owner);
|
||||||
cursor = canTargetActor ? "ability" : "move-blocked";
|
cursor = canTargetActor ? "ability" : "move-blocked";
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
MaxLevel = info.Upgrades.Count;
|
MaxLevel = info.Upgrades.Count;
|
||||||
|
|
||||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
var cost = self.Info.TraitInfo<ValuedInfo>().Cost;
|
||||||
foreach (var kv in info.Upgrades)
|
foreach (var kv in info.Upgrades)
|
||||||
nextLevel.Add(Pair.New(kv.Key * cost, kv.Value));
|
nextLevel.Add(Pair.New(kv.Key * cost, kv.Value));
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
static int GetMultiplier(Actor self)
|
static int GetMultiplier(Actor self)
|
||||||
{
|
{
|
||||||
// returns 100's as 1, so as to keep accuracy for longer.
|
// returns 100's as 1, so as to keep accuracy for longer.
|
||||||
var info = self.Info.Traits.Get<GivesBountyInfo>();
|
var info = self.Info.TraitInfo<GivesBountyInfo>();
|
||||||
var gainsExp = self.TraitOrDefault<GainsExperience>();
|
var gainsExp = self.TraitOrDefault<GainsExperience>();
|
||||||
if (gainsExp == null)
|
if (gainsExp == null)
|
||||||
return 100;
|
return 100;
|
||||||
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void Killed(Actor self, AttackInfo e)
|
public void Killed(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
var info = self.Info.Traits.Get<GivesBountyInfo>();
|
var info = self.Info.TraitInfo<GivesBountyInfo>();
|
||||||
|
|
||||||
if (e.Attacker == null || e.Attacker.Disposed) return;
|
if (e.Attacker == null || e.Attacker.Disposed) return;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (e.Attacker == null || e.Attacker.Disposed || (!info.FriendlyFire && e.Attacker.Owner.Stances[self.Owner] == Stance.Ally))
|
if (e.Attacker == null || e.Attacker.Disposed || (!info.FriendlyFire && e.Attacker.Owner.Stances[self.Owner] == Stance.Ally))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var valued = self.Info.Traits.GetOrDefault<ValuedInfo>();
|
var valued = self.Info.TraitInfoOrDefault<ValuedInfo>();
|
||||||
|
|
||||||
// Default experience is 100 times our value
|
// Default experience is 100 times our value
|
||||||
var exp = info.Experience >= 0
|
var exp = info.Experience >= 0
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
self.SetTargetLine(target, Color.Yellow);
|
self.SetTargetLine(target, Color.Yellow);
|
||||||
|
|
||||||
var range = WDist.FromCells(target.Actor.Info.Traits.Get<GuardableInfo>().Range);
|
var range = WDist.FromCells(target.Actor.Info.TraitInfo<GuardableInfo>().Range);
|
||||||
self.QueueActivity(false, new AttackMoveActivity(self, self.Trait<IMove>().MoveFollow(self, target, WDist.Zero, range)));
|
self.QueueActivity(false, new AttackMoveActivity(self, self.Trait<IMove>().MoveFollow(self, target, WDist.Zero, range)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
{
|
{
|
||||||
if (subjects.All(s => s.IsDead || !s.HasTrait<Guard>()))
|
if (subjects.All(s => s.IsDead || !s.Info.HasTraitInfo<GuardInfo>()))
|
||||||
world.CancelInputMode();
|
world.CancelInputMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return world.ScreenMap.ActorsAt(mi)
|
return world.ScreenMap.ActorsAt(mi)
|
||||||
.Where(a => !world.FogObscures(a) && !a.IsDead &&
|
.Where(a => !world.FogObscures(a) && !a.IsDead &&
|
||||||
a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) &&
|
a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) &&
|
||||||
a.HasTrait<Guardable>());
|
a.Info.HasTraitInfo<GuardableInfo>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
IExplodeModifier, IOrderVoice, ISpeedModifier, ISync, INotifyCreated,
|
IExplodeModifier, IOrderVoice, ISpeedModifier, ISync, INotifyCreated,
|
||||||
INotifyResourceClaimLost, INotifyIdle, INotifyBlockingMove, INotifyBuildComplete
|
INotifyResourceClaimLost, INotifyIdle, INotifyBlockingMove, INotifyBuildComplete
|
||||||
{
|
{
|
||||||
readonly HarvesterInfo info;
|
public readonly HarvesterInfo Info;
|
||||||
readonly Mobile mobile;
|
readonly Mobile mobile;
|
||||||
Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
|
Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
|
||||||
bool idleSmart = true;
|
bool idleSmart = true;
|
||||||
@@ -92,20 +92,20 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public Harvester(Actor self, HarvesterInfo info)
|
public Harvester(Actor self, HarvesterInfo info)
|
||||||
{
|
{
|
||||||
this.info = info;
|
Info = info;
|
||||||
mobile = self.Trait<Mobile>();
|
mobile = self.Trait<Mobile>();
|
||||||
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
|
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Created(Actor self)
|
public void Created(Actor self)
|
||||||
{
|
{
|
||||||
if (info.SearchOnCreation)
|
if (Info.SearchOnCreation)
|
||||||
self.QueueActivity(new FindResources(self));
|
self.QueueActivity(new FindResources(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BuildingComplete(Actor self)
|
public void BuildingComplete(Actor self)
|
||||||
{
|
{
|
||||||
if (info.SearchOnCreation)
|
if (Info.SearchOnCreation)
|
||||||
self.QueueActivity(new FindResources(self));
|
self.QueueActivity(new FindResources(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +151,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
bool IsAcceptableProcType(Actor proc)
|
bool IsAcceptableProcType(Actor proc)
|
||||||
{
|
{
|
||||||
return info.DeliveryBuildings.Count == 0 ||
|
return Info.DeliveryBuildings.Count == 0 ||
|
||||||
info.DeliveryBuildings.Contains(proc.Info.Name);
|
Info.DeliveryBuildings.Contains(proc.Info.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actor ClosestProc(Actor self, Actor ignore)
|
public Actor ClosestProc(Actor self, Actor ignore)
|
||||||
@@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
// Start a search from each refinery's delivery location:
|
// Start a search from each refinery's delivery location:
|
||||||
List<CPos> path;
|
List<CPos> path;
|
||||||
var mi = self.Info.Traits.Get<MobileInfo>();
|
var mi = self.Info.TraitInfo<MobileInfo>();
|
||||||
using (var search = PathSearch.FromPoints(self.World, mi, self, refs.Values.Select(r => r.Location), self.Location, false)
|
using (var search = PathSearch.FromPoints(self.World, mi, self, refs.Values.Select(r => r.Location), self.Location, false)
|
||||||
.WithCustomCost(loc =>
|
.WithCustomCost(loc =>
|
||||||
{
|
{
|
||||||
@@ -192,9 +192,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsFull { get { return contents.Values.Sum() == info.Capacity; } }
|
public bool IsFull { get { return contents.Values.Sum() == Info.Capacity; } }
|
||||||
public bool IsEmpty { get { return contents.Values.Sum() == 0; } }
|
public bool IsEmpty { get { return contents.Values.Sum() == 0; } }
|
||||||
public int Fullness { get { return contents.Values.Sum() * 100 / info.Capacity; } }
|
public int Fullness { get { return contents.Values.Sum() * 100 / Info.Capacity; } }
|
||||||
|
|
||||||
public void AcceptResource(ResourceType type)
|
public void AcceptResource(ResourceType type)
|
||||||
{
|
{
|
||||||
@@ -212,7 +212,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (self.Location == deliveryLoc)
|
if (self.Location == deliveryLoc)
|
||||||
{
|
{
|
||||||
// Get out of the way:
|
// Get out of the way:
|
||||||
var unblockCell = LastHarvestedCell ?? (deliveryLoc + info.UnblockCell);
|
var unblockCell = LastHarvestedCell ?? (deliveryLoc + Info.UnblockCell);
|
||||||
var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5);
|
var moveTo = mobile.NearestMoveableCell(unblockCell, 1, 5);
|
||||||
self.QueueActivity(mobile.MoveTo(moveTo, 1));
|
self.QueueActivity(mobile.MoveTo(moveTo, 1));
|
||||||
self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false);
|
self.SetTargetLine(Target.FromCell(self.World, moveTo), Color.Gray, false);
|
||||||
@@ -287,7 +287,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (--contents[type] == 0)
|
if (--contents[type] == 0)
|
||||||
contents.Remove(type);
|
contents.Remove(type);
|
||||||
|
|
||||||
currentUnloadTicks = info.UnloadTicksPerBale;
|
currentUnloadTicks = Info.UnloadTicksPerBale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return contents.Count == 0;
|
return contents.Count == 0;
|
||||||
@@ -297,7 +297,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new EnterAlliedActorTargeter<IAcceptResources>("Deliver", 5,
|
yield return new EnterAlliedActorTargeter<IAcceptResourcesInfo>("Deliver", 5,
|
||||||
proc => IsAcceptableProcType(proc),
|
proc => IsAcceptableProcType(proc),
|
||||||
proc => !IsEmpty && proc.Trait<IAcceptResources>().AllowDocking);
|
proc => !IsEmpty && proc.Trait<IAcceptResources>().AllowDocking);
|
||||||
yield return new HarvestOrderTargeter();
|
yield return new HarvestOrderTargeter();
|
||||||
@@ -318,10 +318,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public string VoicePhraseForOrder(Actor self, Order order)
|
public string VoicePhraseForOrder(Actor self, Order order)
|
||||||
{
|
{
|
||||||
if (order.OrderString == "Harvest")
|
if (order.OrderString == "Harvest")
|
||||||
return info.HarvestVoice;
|
return Info.HarvestVoice;
|
||||||
|
|
||||||
if (order.OrderString == "Deliver" && !IsEmpty)
|
if (order.OrderString == "Deliver" && !IsEmpty)
|
||||||
return info.DeliverVoice;
|
return Info.DeliverVoice;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -421,7 +421,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
PipType GetPipAt(int i)
|
PipType GetPipAt(int i)
|
||||||
{
|
{
|
||||||
var n = i * info.Capacity / info.PipCount;
|
var n = i * Info.Capacity / Info.PipCount;
|
||||||
|
|
||||||
foreach (var rt in contents)
|
foreach (var rt in contents)
|
||||||
if (n < rt.Value)
|
if (n < rt.Value)
|
||||||
@@ -434,7 +434,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public IEnumerable<PipType> GetPips(Actor self)
|
public IEnumerable<PipType> GetPips(Actor self)
|
||||||
{
|
{
|
||||||
var numPips = info.PipCount;
|
var numPips = Info.PipCount;
|
||||||
|
|
||||||
for (var i = 0; i < numPips; i++)
|
for (var i = 0; i < numPips; i++)
|
||||||
yield return GetPipAt(i);
|
yield return GetPipAt(i);
|
||||||
@@ -444,7 +444,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public int GetSpeedModifier()
|
public int GetSpeedModifier()
|
||||||
{
|
{
|
||||||
return 100 - (100 - info.FullyLoadedSpeed) * contents.Values.Sum() / info.Capacity;
|
return 100 - (100 - Info.FullyLoadedSpeed) * contents.Values.Sum() / Info.Capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HarvestOrderTargeter : IOrderTargeter
|
class HarvestOrderTargeter : IOrderTargeter
|
||||||
@@ -469,7 +469,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var res = self.World.WorldActor.Trait<ResourceLayer>().GetRenderedResource(location);
|
var res = self.World.WorldActor.Trait<ResourceLayer>().GetRenderedResource(location);
|
||||||
var info = self.Info.Traits.Get<HarvesterInfo>();
|
var info = self.Info.TraitInfo<HarvesterInfo>();
|
||||||
|
|
||||||
if (res == null || !info.Resources.Contains(res.Info.Name))
|
if (res == null || !info.Resources.Contains(res.Info.Name))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (self.IsDead)
|
if (self.IsDead)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Info.RemoveInstead || !self.HasTrait<Health>())
|
if (Info.RemoveInstead || !self.Info.HasTraitInfo<HealthInfo>())
|
||||||
self.Dispose();
|
self.Dispose();
|
||||||
else
|
else
|
||||||
self.Kill(self);
|
self.Kill(self);
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Desc("Unit is able to move.")]
|
[Desc("Unit is able to move.")]
|
||||||
public class MobileInfo : IMoveInfo, IOccupySpaceInfo, IFacingInfo, UsesInit<FacingInit>, UsesInit<LocationInit>, UsesInit<SubCellInit>
|
public class MobileInfo : IMoveInfo, IPositionableInfo, IOccupySpaceInfo, IFacingInfo,
|
||||||
|
UsesInit<FacingInit>, UsesInit<LocationInit>, UsesInit<SubCellInit>
|
||||||
{
|
{
|
||||||
[FieldLoader.LoadUsing("LoadSpeeds", true)]
|
[FieldLoader.LoadUsing("LoadSpeeds", true)]
|
||||||
[Desc("Set Water: 0 for ground units and lower the value on rough terrain.")]
|
[Desc("Set Water: 0 for ground units and lower the value on rough terrain.")]
|
||||||
@@ -664,7 +665,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var cellInfo = notStupidCells
|
var cellInfo = notStupidCells
|
||||||
.SelectMany(c => self.World.ActorMap.GetUnitsAt(c)
|
.SelectMany(c => self.World.ActorMap.GetUnitsAt(c)
|
||||||
.Where(a => a.IsIdle && a.HasTrait<Mobile>()),
|
.Where(a => a.IsIdle && a.Info.HasTraitInfo<MobileInfo>()),
|
||||||
(c, a) => new { Cell = c, Actor = a })
|
(c, a) => new { Cell = c, Actor = a })
|
||||||
.RandomOrDefault(self.World.SharedRandom);
|
.RandomOrDefault(self.World.SharedRandom);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly bool startsRevealed;
|
readonly bool startsRevealed;
|
||||||
readonly PPos[] footprint;
|
readonly PPos[] footprint;
|
||||||
|
|
||||||
readonly Lazy<IToolTip> tooltip;
|
readonly Lazy<ITooltip> tooltip;
|
||||||
readonly Lazy<Health> health;
|
readonly Lazy<Health> health;
|
||||||
|
|
||||||
readonly Dictionary<Player, bool> visible;
|
readonly Dictionary<Player, bool> visible;
|
||||||
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
|
||||||
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
|
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
|
||||||
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();
|
footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray();
|
||||||
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<IToolTip>().FirstOrDefault());
|
tooltip = Exts.Lazy(() => init.Self.TraitsImplementing<ITooltip>().FirstOrDefault());
|
||||||
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
health = Exts.Lazy(() => init.Self.TraitOrDefault<Health>());
|
||||||
|
|
||||||
frozen = new Dictionary<Player, FrozenActor>();
|
frozen = new Dictionary<Player, FrozenActor>();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
public enum AlternateTransportsMode { None, Force, Default, Always }
|
public enum AlternateTransportsMode { None, Force, Default, Always }
|
||||||
|
|
||||||
public class EnterTransportTargeter : EnterAlliedActorTargeter<Cargo>
|
public class EnterTransportTargeter : EnterAlliedActorTargeter<CargoInfo>
|
||||||
{
|
{
|
||||||
readonly AlternateTransportsMode mode;
|
readonly AlternateTransportsMode mode;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EnterTransportsTargeter : EnterAlliedActorTargeter<Cargo>
|
public class EnterTransportsTargeter : EnterAlliedActorTargeter<CargoInfo>
|
||||||
{
|
{
|
||||||
readonly AlternateTransportsMode mode;
|
readonly AlternateTransportsMode mode;
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
Info = info;
|
Info = info;
|
||||||
Func<Actor, bool> canTarget = IsCorrectCargoType;
|
Func<Actor, bool> canTarget = IsCorrectCargoType;
|
||||||
Func<Actor, bool> useEnterCursor = CanEnter;
|
Func<Actor, bool> useEnterCursor = CanEnter;
|
||||||
Orders = new EnterAlliedActorTargeter<Cargo>[]
|
Orders = new EnterAlliedActorTargeter<CargoInfo>[]
|
||||||
{
|
{
|
||||||
new EnterTransportTargeter("EnterTransport", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode),
|
new EnterTransportTargeter("EnterTransport", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode),
|
||||||
new EnterTransportsTargeter("EnterTransports", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode)
|
new EnterTransportsTargeter("EnterTransports", 5, canTarget, useEnterCursor, Info.AlternateTransportsMode)
|
||||||
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
bool IsCorrectCargoType(Actor target)
|
bool IsCorrectCargoType(Actor target)
|
||||||
{
|
{
|
||||||
var ci = target.Info.Traits.Get<CargoInfo>();
|
var ci = target.Info.TraitInfo<CargoInfo>();
|
||||||
return ci.Types.Contains(Info.CargoType);
|
return ci.Types.Contains(Info.CargoType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var building = order.TargetActor;
|
var building = order.TargetActor;
|
||||||
|
|
||||||
if (building.HasTrait<RepairableBuilding>())
|
if (building.Info.HasTraitInfo<RepairableBuildingInfo>())
|
||||||
if (building.AppearsFriendlyTo(self))
|
if (building.AppearsFriendlyTo(self))
|
||||||
building.Trait<RepairableBuilding>().RepairBuilding(building, self.Owner);
|
building.Trait<RepairableBuilding>().RepairBuilding(building, self.Owner);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public void Damaged(Actor self, AttackInfo e)
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
// only track last hit against our base
|
// only track last hit against our base
|
||||||
if (!self.HasTrait<Building>())
|
if (!self.Info.HasTraitInfo<BuildingInfo>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.Attacker == null)
|
if (e.Attacker == null)
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
// Find a production structure to build this actor
|
// Find a production structure to build this actor
|
||||||
var ai = self.World.Map.Rules.Actors[name];
|
var ai = self.World.Map.Rules.Actors[name];
|
||||||
var bi = ai.Traits.GetOrDefault<BuildableInfo>();
|
var bi = ai.TraitInfoOrDefault<BuildableInfo>();
|
||||||
|
|
||||||
// Some units may request a specific production type, which is ignored if the AllTech cheat is enabled
|
// Some units may request a specific production type, which is ignored if the AllTech cheat is enabled
|
||||||
var type = bi == null || developerMode.AllTech ? Info.Type : bi.BuildAtProductionType ?? Info.Type;
|
var type = bi == null || developerMode.AllTech ? Info.Type : bi.BuildAtProductionType ?? Info.Type;
|
||||||
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public override int GetBuildTime(string unitString)
|
public override int GetBuildTime(string unitString)
|
||||||
{
|
{
|
||||||
var ai = self.World.Map.Rules.Actors[unitString];
|
var ai = self.World.Map.Rules.Actors[unitString];
|
||||||
var bi = ai.Traits.GetOrDefault<BuildableInfo>();
|
var bi = ai.TraitInfoOrDefault<BuildableInfo>();
|
||||||
if (bi == null)
|
if (bi == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void Damaged(Actor self, AttackInfo e)
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
// only track last hit against our base
|
// only track last hit against our harvesters
|
||||||
if (!self.HasTrait<Harvester>())
|
if (!self.Info.HasTraitInfo<HarvesterInfo>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// don't track self-damage
|
// don't track self-damage
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
|
public IEnumerable<IRenderable> Render(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition)
|
||||||
{
|
{
|
||||||
if (!ai.Traits.Get<BuildingInfo>().RequiresBaseProvider)
|
if (!ai.TraitInfo<BuildingInfo>().RequiresBaseProvider)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
foreach (var a in w.ActorsWithTrait<BaseProvider>())
|
foreach (var a in w.ActorsWithTrait<BaseProvider>())
|
||||||
@@ -75,9 +75,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
var producer = queue.MostLikelyProducer();
|
var producer = queue.MostLikelyProducer();
|
||||||
var faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
|
var faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
|
||||||
var buildingInfo = unit.Traits.Get<BuildingInfo>();
|
var buildingInfo = unit.TraitInfo<BuildingInfo>();
|
||||||
|
|
||||||
var buildableInfo = unit.Traits.GetOrDefault<BuildableInfo>();
|
var buildableInfo = unit.TraitInfoOrDefault<BuildableInfo>();
|
||||||
if (buildableInfo != null && buildableInfo.ForceFaction != null)
|
if (buildableInfo != null && buildableInfo.ForceFaction != null)
|
||||||
faction = buildableInfo.ForceFaction;
|
faction = buildableInfo.ForceFaction;
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (host == null)
|
if (host == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var plugInfo = unit.Traits.GetOrDefault<PlugInfo>();
|
var plugInfo = unit.TraitInfoOrDefault<PlugInfo>();
|
||||||
if (plugInfo == null)
|
if (plugInfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -107,20 +107,20 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
var attackerStats = e.Attacker.Owner.PlayerActor.Trait<PlayerStatistics>();
|
var attackerStats = e.Attacker.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||||
var defenderStats = self.Owner.PlayerActor.Trait<PlayerStatistics>();
|
var defenderStats = self.Owner.PlayerActor.Trait<PlayerStatistics>();
|
||||||
if (self.HasTrait<Building>())
|
if (self.Info.HasTraitInfo<BuildingInfo>())
|
||||||
{
|
{
|
||||||
attackerStats.BuildingsKilled++;
|
attackerStats.BuildingsKilled++;
|
||||||
defenderStats.BuildingsDead++;
|
defenderStats.BuildingsDead++;
|
||||||
}
|
}
|
||||||
else if (self.HasTrait<IPositionable>())
|
else if (self.Info.HasTraitInfo<IPositionableInfo>())
|
||||||
{
|
{
|
||||||
attackerStats.UnitsKilled++;
|
attackerStats.UnitsKilled++;
|
||||||
defenderStats.UnitsDead++;
|
defenderStats.UnitsDead++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.HasTrait<Valued>())
|
if (self.Info.HasTraitInfo<ValuedInfo>())
|
||||||
{
|
{
|
||||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
var cost = self.Info.TraitInfo<ValuedInfo>().Cost;
|
||||||
attackerStats.KillsCost += cost;
|
attackerStats.KillsCost += cost;
|
||||||
defenderStats.DeathsCost += cost;
|
defenderStats.DeathsCost += cost;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
foreach (var a in AllBuildables(Info.Type))
|
foreach (var a in AllBuildables(Info.Type))
|
||||||
{
|
{
|
||||||
var bi = a.Traits.Get<BuildableInfo>();
|
var bi = a.TraitInfo<BuildableInfo>();
|
||||||
|
|
||||||
produceable.Add(a, new ProductionState());
|
produceable.Add(a, new ProductionState());
|
||||||
ttc.Add(a.Name, bi.Prerequisites, bi.BuildLimit, this);
|
ttc.Add(a.Name, bi.Prerequisites, bi.BuildLimit, this);
|
||||||
@@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return self.World.Map.Rules.Actors.Values
|
return self.World.Map.Rules.Actors.Values
|
||||||
.Where(x =>
|
.Where(x =>
|
||||||
x.Name[0] != '^' &&
|
x.Name[0] != '^' &&
|
||||||
x.Traits.Contains<BuildableInfo>() &&
|
x.HasTraitInfo<BuildableInfo>() &&
|
||||||
x.Traits.Get<BuildableInfo>().Queue.Contains(category));
|
x.TraitInfo<BuildableInfo>().Queue.Contains(category));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrerequisitesAvailable(string key)
|
public void PrerequisitesAvailable(string key)
|
||||||
@@ -250,11 +250,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
case "StartProduction":
|
case "StartProduction":
|
||||||
{
|
{
|
||||||
var unit = self.World.Map.Rules.Actors[order.TargetString];
|
var unit = self.World.Map.Rules.Actors[order.TargetString];
|
||||||
var bi = unit.Traits.Get<BuildableInfo>();
|
var bi = unit.TraitInfo<BuildableInfo>();
|
||||||
if (!bi.Queue.Contains(Info.Type))
|
if (!bi.Queue.Contains(Info.Type))
|
||||||
return; /* Not built by this queue */
|
return; /* Not built by this queue */
|
||||||
|
|
||||||
var cost = unit.Traits.Contains<ValuedInfo>() ? unit.Traits.Get<ValuedInfo>().Cost : 0;
|
var cost = unit.HasTraitInfo<ValuedInfo>() ? unit.TraitInfo<ValuedInfo>().Cost : 0;
|
||||||
var time = GetBuildTime(order.TargetString);
|
var time = GetBuildTime(order.TargetString);
|
||||||
|
|
||||||
if (BuildableItems().All(b => b.Name != order.TargetString))
|
if (BuildableItems().All(b => b.Name != order.TargetString))
|
||||||
@@ -278,7 +278,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var hasPlayedSound = false;
|
var hasPlayedSound = false;
|
||||||
BeginProduction(new ProductionItem(this, order.TargetString, cost, playerPower, () => self.World.AddFrameEndTask(_ =>
|
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)
|
if (isBuilding && !hasPlayedSound)
|
||||||
hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName);
|
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)
|
public virtual int GetBuildTime(string unitString)
|
||||||
{
|
{
|
||||||
var unit = self.World.Map.Rules.Actors[unitString];
|
var unit = self.World.Map.Rules.Actors[unitString];
|
||||||
if (unit == null || !unit.Traits.Contains<BuildableInfo>())
|
if (unit == null || !unit.HasTraitInfo<BuildableInfo>())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait<DeveloperMode>().FastBuild)
|
if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait<DeveloperMode>().FastBuild)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public class ProvidesPrerequisiteInfo : ITraitInfo
|
public class ProvidesPrerequisiteInfo : ITechTreePrerequisiteInfo
|
||||||
{
|
{
|
||||||
[Desc("The prerequisite type that this provides. If left empty it defaults to the actor's name.")]
|
[Desc("The prerequisite type that this provides. If left empty it defaults to the actor's name.")]
|
||||||
public readonly string Prerequisite = null;
|
public readonly string Prerequisite = null;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using OpenRA.Traits;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public class ProvidesTechPrerequisiteInfo : ITraitInfo
|
public class ProvidesTechPrerequisiteInfo : ITechTreePrerequisiteInfo
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
public readonly string[] Prerequisites = { };
|
public readonly string[] Prerequisites = { };
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void ActorChanged(Actor a)
|
public void ActorChanged(Actor a)
|
||||||
{
|
{
|
||||||
var bi = a.Info.Traits.GetOrDefault<BuildableInfo>();
|
var bi = a.Info.TraitInfoOrDefault<BuildableInfo>();
|
||||||
if (a.Owner == player && (a.HasTrait<ITechTreePrerequisite>() || (bi != null && bi.BuildLimit > 0)))
|
if (a.Owner == player && (a.Info.HasTraitInfo<ITechTreePrerequisiteInfo>() || (bi != null && bi.BuildLimit > 0)))
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
a.Actor.IsInWorld &&
|
a.Actor.IsInWorld &&
|
||||||
!a.Actor.IsDead &&
|
!a.Actor.IsDead &&
|
||||||
!ret.ContainsKey(a.Actor.Info.Name) &&
|
!ret.ContainsKey(a.Actor.Info.Name) &&
|
||||||
a.Actor.Info.Traits.Get<BuildableInfo>().BuildLimit > 0)
|
a.Actor.Info.TraitInfo<BuildableInfo>().BuildLimit > 0)
|
||||||
.Do(b => ret[b.Actor.Info.Name].Add(b.Actor));
|
.Do(b => ret[b.Actor.Info.Name].Add(b.Actor));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public Production(ActorInitializer init, ProductionInfo info)
|
public Production(ActorInitializer init, ProductionInfo info)
|
||||||
{
|
{
|
||||||
Info = 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>());
|
rp = Exts.Lazy(() => init.Self.IsDead ? null : init.Self.TraitOrDefault<RallyPoint>());
|
||||||
Faction = init.Contains<FactionInit>() ? init.Get<FactionInit, string>() : init.Self.Owner.Faction.InternalName;
|
Faction = init.Contains<FactionInit>() ? init.Get<FactionInit, string>() : init.Self.Owner.Faction.InternalName;
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var exitLocation = CPos.Zero;
|
var exitLocation = CPos.Zero;
|
||||||
var target = Target.Invalid;
|
var target = Target.Invalid;
|
||||||
|
|
||||||
var bi = producee.Traits.GetOrDefault<BuildableInfo>();
|
var bi = producee.TraitInfoOrDefault<BuildableInfo>();
|
||||||
if (bi != null && bi.ForceFaction != null)
|
if (bi != null && bi.ForceFaction != null)
|
||||||
factionVariant = bi.ForceFaction;
|
factionVariant = bi.ForceFaction;
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var spawn = self.CenterPosition + exitinfo.SpawnOffset;
|
var spawn = self.CenterPosition + exitinfo.SpawnOffset;
|
||||||
var to = self.World.Map.CenterOfCell(exit);
|
var to = self.World.Map.CenterOfCell(exit);
|
||||||
|
|
||||||
var fi = producee.Traits.GetOrDefault<IFacingInfo>();
|
var fi = producee.TraitInfoOrDefault<IFacingInfo>();
|
||||||
var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi == null ? 0 : fi.GetInitialFacing()) : exitinfo.Facing;
|
var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi == null ? 0 : fi.GetInitialFacing()) : exitinfo.Facing;
|
||||||
|
|
||||||
exitLocation = rp.Value != null ? rp.Value.Location : exit;
|
exitLocation = rp.Value != null ? rp.Value.Location : exit;
|
||||||
@@ -133,7 +133,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
static bool CanUseExit(Actor self, ActorInfo producee, ExitInfo s)
|
static bool CanUseExit(Actor self, ActorInfo producee, ExitInfo s)
|
||||||
{
|
{
|
||||||
var mobileInfo = producee.Traits.GetOrDefault<MobileInfo>();
|
var mobileInfo = producee.TraitInfoOrDefault<MobileInfo>();
|
||||||
|
|
||||||
self.NotifyBlocker(self.Location + s.ExitCell);
|
self.NotifyBlocker(self.Location + s.ExitCell);
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user