diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index d0741bf33c..17a1781a97 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -122,8 +122,9 @@ namespace OpenRA World = world; ActorID = world.NextAID(); - if (initDict.Contains()) - Owner = init.Get(); + var ownerInit = init.GetOrDefault(null); + if (ownerInit != null) + Owner = ownerInit.Value(world); if (name != null) { diff --git a/OpenRA.Game/Map/ActorInitializer.cs b/OpenRA.Game/Map/ActorInitializer.cs index 271a5ac509..06267b385f 100644 --- a/OpenRA.Game/Map/ActorInitializer.cs +++ b/OpenRA.Game/Map/ActorInitializer.cs @@ -9,17 +9,21 @@ */ #endregion +using System; using System.Linq; using OpenRA.Primitives; +using OpenRA.Traits; namespace OpenRA { public interface IActorInitializer { World World { get; } - T Get() where T : IActorInit; - U Get() where T : IActorInit; - bool Contains() where T : IActorInit; + T GetOrDefault(TraitInfo info) where T : IActorInit; + T Get(TraitInfo info) where T : IActorInit; + U GetValue(TraitInfo info) where T : IActorInit; + U GetValue(TraitInfo info, U fallback) where T : IActorInit; + bool Contains(TraitInfo info) where T : IActorInit; } public class ActorInitializer : IActorInitializer @@ -35,16 +39,39 @@ namespace OpenRA Dict = dict; } - public T Get() where T : IActorInit { return Dict.Get(); } - public U Get() where T : IActorInit { return Dict.Get().Value(World); } - public bool Contains() where T : IActorInit { return Dict.Contains(); } + public T GetOrDefault(TraitInfo info) where T : IActorInit + { + return Dict.GetOrDefault(); + } + + public T Get(TraitInfo info) where T : IActorInit + { + var init = GetOrDefault(info); + if (init == null) + throw new InvalidOperationException("TypeDictionary does not contain instance of type `{0}`".F(typeof(T))); + + return init; + } + + public U GetValue(TraitInfo info) where T : IActorInit + { + return Get(info).Value; + } + + public U GetValue(TraitInfo info, U fallback) where T : IActorInit + { + var init = GetOrDefault(info); + return init != null ? init.Value : fallback; + } + + public bool Contains(TraitInfo info) where T : IActorInit { return GetOrDefault(info) != null; } } public interface IActorInit { } public interface IActorInit : IActorInit { - T Value(World world); + T Value { get; } } public class LocationInit : IActorInit @@ -54,23 +81,23 @@ namespace OpenRA public LocationInit() { } public LocationInit(CPos init) { value = init; } - public CPos Value(World world) { return value; } + public CPos Value { get { return value; } } } - public class OwnerInit : IActorInit + public class OwnerInit : IActorInit { [FieldFromYamlKey] - public readonly string PlayerName = "Neutral"; + public readonly string InternalName = "Neutral"; Player player; public OwnerInit() { } - public OwnerInit(string playerName) { PlayerName = playerName; } + public OwnerInit(string playerName) { InternalName = playerName; } public OwnerInit(Player player) { this.player = player; - PlayerName = player.InternalName; + InternalName = player.InternalName; } public Player Value(World world) @@ -78,7 +105,7 @@ namespace OpenRA if (player != null) return player; - return world.Players.First(x => x.InternalName == PlayerName); + return world.Players.First(x => x.InternalName == InternalName); } } } diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 55f2928d17..1d6217dc68 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -276,7 +276,7 @@ namespace OpenRA foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); - spawns.Add(s.InitDict.Get().Value(null)); + spawns.Add(s.InitDict.Get().Value); } newData.SpawnPoints = spawns.ToArray(); diff --git a/OpenRA.Mods.Cnc/Traits/Attack/AttackPopupTurreted.cs b/OpenRA.Mods.Cnc/Traits/Attack/AttackPopupTurreted.cs index 340c3d5556..5ada871d8f 100644 --- a/OpenRA.Mods.Cnc/Traits/Attack/AttackPopupTurreted.cs +++ b/OpenRA.Mods.Cnc/Traits/Attack/AttackPopupTurreted.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Cnc.Traits this.info = info; turret = turrets.FirstOrDefault(); wsb = init.Self.TraitsImplementing().Single(w => w.Info.Name == info.Body); - skippedMakeAnimation = init.Contains(); + skippedMakeAnimation = init.Contains(info); } protected override void Created(Actor self) diff --git a/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs b/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs index bc84e7ef24..668151b39f 100644 --- a/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs +++ b/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using OpenRA.Mods.Cnc.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; @@ -58,18 +59,14 @@ namespace OpenRA.Mods.Cnc.Traits : base(info) { self = init.Self; + ReturnTicks = init.GetValue(info, 0); + duration = init.GetValue(info, 0); + Origin = init.GetValue(info, CPos.Zero); - if (init.Contains()) - ReturnTicks = init.Get(); - - if (init.Contains()) - duration = init.Get(); - - if (init.Contains()) - Origin = init.Get(); - - if (init.Contains()) - chronosphere = init.Get(); + // Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet + var chronosphereInit = init.GetOrDefault(info); + if (chronosphereInit != null) + init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value(init.World).Value); } void ITick.Tick(Actor self) @@ -186,7 +183,7 @@ namespace OpenRA.Mods.Cnc.Traits public ChronoshiftReturnInit() { } public ChronoshiftReturnInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } public class ChronoshiftDurationInit : IActorInit @@ -196,7 +193,7 @@ namespace OpenRA.Mods.Cnc.Traits public ChronoshiftDurationInit() { } public ChronoshiftDurationInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } public class ChronoshiftOriginInit : IActorInit @@ -205,13 +202,14 @@ namespace OpenRA.Mods.Cnc.Traits readonly CPos value; public ChronoshiftOriginInit(CPos init) { value = init; } - public CPos Value(World world) { return value; } + public CPos Value { get { return value; } } } - public class ChronoshiftChronosphereInit : IActorInit + public class ChronoshiftChronosphereInit : IActorInit { readonly Actor value; public ChronoshiftChronosphereInit(Actor init) { value = init; } - public Actor Value(World world) { return value; } + + public Lazy Value(World world) { return new Lazy(() => value); } } } diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index 305497525b..d5636fc525 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common; @@ -94,19 +95,15 @@ namespace OpenRA.Mods.Cnc.Traits health = self.Trait(); wsb = self.TraitsImplementing().Single(w => w.Info.Name == info.Body); - faction = init.Contains() ? init.Get() : self.Owner.Faction.InternalName; + faction = init.GetValue(info, self.Owner.Faction.InternalName); + returnTicks = init.GetValue(info, 0); + duration = init.GetValue(info, 0); + origin = init.GetValue(info, CPos.Zero); - if (init.Contains()) - returnTicks = init.Get(); - - if (init.Contains()) - duration = init.Get(); - - if (init.Contains()) - origin = init.Get(); - - if (init.Contains()) - chronosphere = init.Get(); + // Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet + var chronosphereInit = init.GetOrDefault(info); + if (chronosphereInit != null) + init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value(init.World).Value); } IEnumerable IObservesVariables.GetVariableObservers() diff --git a/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs b/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs index 63a09572b3..708ecd4c68 100644 --- a/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs +++ b/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Cnc.Traits public InfiltrateForTransform(ActorInitializer init, InfiltrateForTransformInfo info) { this.info = info; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } void INotifyInfiltrated.Infiltrated(Actor self, Actor infiltrator, BitSet types) diff --git a/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs b/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs index 5de172d9fd..c0ad19a56f 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs @@ -32,7 +32,7 @@ namespace OpenRA.Mods.Cnc.Traits public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (init.Contains() && init.Get()) + if (init.Contains(this)) yield break; if (Palette != null) @@ -45,10 +45,7 @@ namespace OpenRA.Mods.Cnc.Traits var bibOffset = bi.Dimensions.Y - rows; var centerOffset = bi.CenterOffset(init.World); var map = init.World.Map; - var location = CPos.Zero; - - if (init.Contains()) - location = init.Get(); + var location = init.GetValue(this, CPos.Zero); for (var i = 0; i < rows * width; i++) { @@ -136,13 +133,8 @@ namespace OpenRA.Mods.Cnc.Traits } } - class HideBibPreviewInit : IActorInit, ISuppressInitExport + class HideBibPreviewInit : IActorInit, ISuppressInitExport { - [FieldFromYamlKey] - readonly bool value = true; - public HideBibPreviewInit() { } - public HideBibPreviewInit(bool init) { value = init; } - public bool Value(World world) { return value; } } } diff --git a/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs b/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs index 07ea910bf6..d9a494dea9 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithEmbeddedTurretSpriteBody.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render var wsb = init.Actor.TraitInfos().FirstOrDefault(); // Show the correct turret facing - var facing = WAngle.FromFacing(init.Contains() ? init.Get().Value(init.World) : t.InitialFacing); + var facing = WAngle.FromFacing(init.GetValue(this, t.InitialFacing)); var anim = new Animation(init.World, image, () => facing); anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), wsb.Sequence)); diff --git a/OpenRA.Mods.Cnc/Traits/Render/WithVoxelWalkerBody.cs b/OpenRA.Mods.Cnc/Traits/Render/WithVoxelWalkerBody.cs index 0643c7a652..b11da36525 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithVoxelWalkerBody.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithVoxelWalkerBody.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Cnc.Traits.Render { var model = init.World.ModelCache.GetModelSequence(image, Sequence); var body = init.Actor.TraitInfo(); - var frame = init.Contains() ? init.Get() : 0; + var frame = init.GetValue(this, 0); yield return new ModelAnimation(model, () => WVec.Zero, () => new[] { body.QuantizeOrientation(orientation(), facings) }, @@ -102,6 +102,6 @@ namespace OpenRA.Mods.Cnc.Traits.Render public BodyAnimationFrameInit() { } public BodyAnimationFrameInit(uint init) { value = init; } - public uint Value(World world) { return value; } + public uint Value { get { return value; } } } } diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index aab4e66c46..d315d1b5c5 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -80,13 +80,15 @@ namespace OpenRA.Mods.Cnc.Traits Info = info; self = init.Self; - if (init.Contains()) - SetPosition(self, init.Get()); + var locationInit = init.GetOrDefault(info); + if (locationInit != null) + SetPosition(self, locationInit.Value); - if (init.Contains()) - SetPosition(self, init.Get()); + var centerPositionInit = init.GetOrDefault(info); + if (centerPositionInit != null) + SetPosition(self, centerPositionInit.Value); - Facing = init.Contains() ? init.Get() : Info.GetInitialFacing(); + Facing = init.GetValue(info, Info.GetInitialFacing()); // Prevent mappers from setting bogus facings if (Facing != 64 && Facing != 192) diff --git a/OpenRA.Mods.Common/ActorInitializer.cs b/OpenRA.Mods.Common/ActorInitializer.cs index 7708b4d830..724bed4f0d 100644 --- a/OpenRA.Mods.Common/ActorInitializer.cs +++ b/OpenRA.Mods.Common/ActorInitializer.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common public FacingInit() { } public FacingInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } public class CreationActivityDelayInit : IActorInit @@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common public CreationActivityDelayInit() { } public CreationActivityDelayInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } public class DynamicFacingInit : IActorInit> @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common readonly Func func; public DynamicFacingInit(Func func) { this.func = func; } - public Func Value(World world) { return func; } + public Func Value { get { return func; } } } public class SubCellInit : IActorInit @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common public SubCellInit() { } public SubCellInit(byte init) { value = init; } public SubCellInit(SubCell init) { value = (byte)init; } - public SubCell Value(World world) { return (SubCell)value; } + public SubCell Value { get { return (SubCell)value; } } } public class CenterPositionInit : IActorInit @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common public CenterPositionInit() { } public CenterPositionInit(WPos init) { value = init; } - public WPos Value(World world) { return value; } + public WPos Value { get { return value; } } } // Allows maps / transformations to specify the faction variant of an actor. @@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common public FactionInit() { } public FactionInit(string faction) { Faction = faction; } - public string Value(World world) { return Faction; } + public string Value { get { return Faction; } } } public class EffectiveOwnerInit : IActorInit @@ -81,6 +81,6 @@ namespace OpenRA.Mods.Common public EffectiveOwnerInit() { } public EffectiveOwnerInit(Player owner) { value = owner; } - Player IActorInit.Value(World world) { return value; } + public Player Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs index b731a1db1f..5683c57a3a 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs @@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Widgets { var location = copy.InitDict.Get(); copy.InitDict.Remove(location); - copy.InitDict.Add(new LocationInit(location.Value(worldRenderer.World) + offset)); + copy.InitDict.Add(new LocationInit(location.Value + offset)); } previews.Add(preview.ID, copy); diff --git a/OpenRA.Mods.Common/Graphics/ActorPreview.cs b/OpenRA.Mods.Common/Graphics/ActorPreview.cs index 5c18f9b5c5..feab85a55a 100644 --- a/OpenRA.Mods.Common/Graphics/ActorPreview.cs +++ b/OpenRA.Mods.Common/Graphics/ActorPreview.cs @@ -41,9 +41,32 @@ namespace OpenRA.Mods.Common.Graphics this.dict = dict; } - public T Get() where T : IActorInit { return dict.Get(); } - public U Get() where T : IActorInit { return dict.Get().Value(World); } - public bool Contains() where T : IActorInit { return dict.Contains(); } + public T GetOrDefault(TraitInfo info) where T : IActorInit + { + return dict.GetOrDefault(); + } + + public T Get(TraitInfo info) where T : IActorInit + { + var init = GetOrDefault(info); + if (init == null) + throw new InvalidOperationException("TypeDictionary does not contain instance of type `{0}`".F(typeof(T))); + + return init; + } + + public U GetValue(TraitInfo info) where T : IActorInit + { + return Get(info).Value; + } + + public U GetValue(TraitInfo info, U fallback) where T : IActorInit + { + var init = GetOrDefault(info); + return init != null ? init.Value : fallback; + } + + public bool Contains(TraitInfo info) where T : IActorInit { return GetOrDefault(info) != null; } public Func GetOrientation() { @@ -56,13 +79,13 @@ namespace OpenRA.Mods.Common.Graphics if (dynamicInit != null) { // TODO: Account for terrain slope - var getFacing = dynamicInit.Value(null); + var getFacing = dynamicInit.Value; return () => WRot.FromFacing(getFacing()); } // Fall back to initial actor facing if an Init isn't available var facingInit = dict.GetOrDefault(); - var facing = facingInit != null ? facingInit.Value(null) : facingInfo.GetInitialFacing(); + var facing = facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing(); var orientation = WRot.FromFacing(facing); return () => orientation; } @@ -77,13 +100,13 @@ namespace OpenRA.Mods.Common.Graphics var dynamicInit = dict.GetOrDefault(); if (dynamicInit != null) { - var getFacing = dynamicInit.Value(null); + var getFacing = dynamicInit.Value; return () => WAngle.FromFacing(getFacing()); } // Fall back to initial actor facing if an Init isn't available var facingInit = dict.GetOrDefault(); - var facing = WAngle.FromFacing(facingInit != null ? facingInit.Value(null) : facingInfo.GetInitialFacing()); + var facing = WAngle.FromFacing(facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing()); return () => facing; } @@ -94,7 +117,7 @@ namespace OpenRA.Mods.Common.Graphics if (health == null) return DamageState.Undamaged; - var hf = health.Value(null); + var hf = health.Value; if (hf <= 0) return DamageState.Dead; diff --git a/OpenRA.Mods.Common/Lint/CheckPlayers.cs b/OpenRA.Mods.Common/Lint/CheckPlayers.cs index 09011326dd..4b4580c28f 100644 --- a/OpenRA.Mods.Common/Lint/CheckPlayers.cs +++ b/OpenRA.Mods.Common/Lint/CheckPlayers.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var kv in map.ActorDefinitions.Where(d => d.Value.Value == "mpspawn")) { var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); - spawns.Add(s.InitDict.Get().Value(null)); + spawns.Add(s.InitDict.Get().Value); } if (playerCount > spawns.Count) @@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Lint emitError("Actor {0} is not owned by any player.".F(kv.Key)); else { - var ownerName = ownerInit.PlayerName; + var ownerName = ownerInit.InternalName; if (!playerNames.Contains(ownerName)) emitError("Actor {0} is owned by unknown player {1}.".F(kv.Key, ownerName)); diff --git a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs index c68a1e49a1..abb9c19d0b 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ActorGlobal.cs @@ -41,11 +41,18 @@ namespace OpenRA.Mods.Common.Scripting if (initType == null) throw new LuaException("Unknown initializer type '{0}'".F(typeName)); - // Cast it up to an IActorInit - var genericType = initType.GetInterfaces() - .First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IActorInit<>)); - var innerType = genericType.GetGenericArguments().First(); - var valueType = innerType.IsEnum ? Enum.GetUnderlyingType(innerType) : innerType; + // HACK: Handle OwnerInit as a special case until ActorInit creation can be rewritten + Type innerType, valueType; + if (initType != typeof(OwnerInit)) + { + // Cast it up to an IActorInit + var genericType = initType.GetInterfaces() + .First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IActorInit<>)); + innerType = genericType.GetGenericArguments().First(); + valueType = innerType.IsEnum ? Enum.GetUnderlyingType(innerType) : innerType; + } + else + innerType = valueType = typeof(Player); // Try and coerce the table value to the required type object value; diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 2d2ae6847f..c7f8ccbdf6 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits actor => { var init = actor.Init(); - return init != null ? init.Value(world) : InitialFacing; + return init != null ? init.Value : InitialFacing; }, (actor, value) => actor.ReplaceInit(new FacingInit((int)value))); } @@ -241,16 +241,16 @@ namespace OpenRA.Mods.Common.Traits { self = init.Self; - if (init.Contains()) - SetPosition(self, init.Get()); + var locationInit = init.GetOrDefault(info); + if (locationInit != null) + SetPosition(self, locationInit.Value); - if (init.Contains()) - SetPosition(self, init.Get()); + var centerPositionInit = init.GetOrDefault(info); + if (centerPositionInit != null) + SetPosition(self, centerPositionInit.Value); - Facing = init.Contains() ? init.Get() : Info.InitialFacing; - - if (init.Contains()) - creationActivityDelay = init.Get(); + Facing = init.GetValue(info, Info.InitialFacing); + creationActivityDelay = init.GetValue(info, 0); } public WDist LandAltitude diff --git a/OpenRA.Mods.Common/Traits/Air/FallsToEarth.cs b/OpenRA.Mods.Common/Traits/Air/FallsToEarth.cs index 2d719d5edf..02c9a33d1e 100644 --- a/OpenRA.Mods.Common/Traits/Air/FallsToEarth.cs +++ b/OpenRA.Mods.Common/Traits/Air/FallsToEarth.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits public FallsToEarth(ActorInitializer init, FallsToEarthInfo info) { this.info = info; - effectiveOwner = init.Contains() ? init.Get() : init.Self.Owner; + effectiveOwner = init.GetValue(info, init.Self.Owner); } // We return init.Self.Owner if there's no effective owner diff --git a/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs b/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs index 0f6e1715f0..502dad40bd 100644 --- a/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs +++ b/OpenRA.Mods.Common/Traits/AppearsOnMapPreview.cs @@ -42,14 +42,14 @@ namespace OpenRA.Mods.Common.Traits } else { - var owner = map.PlayerDefinitions.Where(p => s.InitDict.Get().PlayerName == p.Value.Nodes.First(k => k.Key == "Name").Value.Value).First(); + var owner = map.PlayerDefinitions.Single(p => s.InitDict.Get().InternalName == p.Value.Nodes.Last(k => k.Key == "Name").Value.Value); var colorValue = owner.Value.Nodes.Where(n => n.Key == "Color"); var ownerColor = colorValue.Any() ? colorValue.First().Value.Value : "FFFFFF"; Color.TryParse(ownerColor, out color); } var ios = ai.TraitInfo(); - var cells = ios.OccupiedCells(ai, s.InitDict.Get().Value(null)); + var cells = ios.OccupiedCells(ai, s.InitDict.Get().Value); foreach (var cell in cells) destinationBuffer.Add(new Pair(cell.Key.ToMPos(map), color)); } diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index 49e84aeaf2..31ffe6a7d4 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits actor => { var init = actor.Init(); - var stance = init != null ? init.Value(world) : InitialStance; + var stance = init != null ? init.Value : InitialStance; return stances[(int)stance]; }, (actor, value) => actor.ReplaceInit(new StanceInit((UnitStance)stances.IndexOf(value)))); @@ -183,10 +183,7 @@ namespace OpenRA.Mods.Common.Traits var self = init.Self; ActiveAttackBases = self.TraitsImplementing().ToArray().Where(Exts.IsTraitEnabled); - if (init.Contains()) - stance = init.Get(); - else - stance = self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance; + stance = init.GetValue(info, self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance); PredictedStance = stance; @@ -455,6 +452,6 @@ namespace OpenRA.Mods.Common.Traits public StanceInit() { } public StanceInit(UnitStance init) { value = init; } - public UnitStance Value(World world) { return value; } + public UnitStance Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/BodyOrientation.cs b/OpenRA.Mods.Common/Traits/BodyOrientation.cs index 6f1abd7831..1bf6275dfd 100644 --- a/OpenRA.Mods.Common/Traits/BodyOrientation.cs +++ b/OpenRA.Mods.Common/Traits/BodyOrientation.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits { this.info = info; var self = init.Self; - var faction = init.Contains() ? init.Get() : self.Owner.Faction.InternalName; + var faction = init.GetValue(info, self.Owner.Faction.InternalName); quantizedFacings = Exts.Lazy(() => { diff --git a/OpenRA.Mods.Common/Traits/Buildings/ActorPreviewPlaceBuildingPreview.cs b/OpenRA.Mods.Common/Traits/Buildings/ActorPreviewPlaceBuildingPreview.cs index 04f79863eb..9a71963ac1 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/ActorPreviewPlaceBuildingPreview.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/ActorPreviewPlaceBuildingPreview.cs @@ -68,8 +68,8 @@ namespace OpenRA.Mods.Common.Traits if (!string.IsNullOrEmpty(info.OverridePalette)) { - var owner = init.Get().Value(wr.World); - palette = wr.Palette(info.OverridePaletteIsPlayerPalette ? info.OverridePalette + owner.InternalName : info.OverridePalette); + var ownerName = init.Get().InternalName; + palette = wr.Palette(info.OverridePaletteIsPlayerPalette ? info.OverridePalette + ownerName : info.OverridePalette); } } diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index 2b6ad1f4ee..44e74b9d41 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Building.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Building.cs @@ -278,7 +278,7 @@ namespace OpenRA.Mods.Common.Traits public Building(ActorInitializer init, BuildingInfo info) { self = init.Self; - topLeft = init.Get(); + topLeft = init.GetValue(info); Info = info; influence = self.World.WorldActor.Trait(); diff --git a/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs b/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs index 56411654dd..dc389bd1fb 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using OpenRA.Primitives; using OpenRA.Traits; @@ -43,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits { var init = actor.Init(); if (init != null) - return init.Value(world); + return init.Value; return true; }, @@ -63,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits public FreeActor(ActorInitializer init, FreeActorInfo info) : base(info) { - allowSpawn = !init.Contains() || init.Get().ActorValue; + allowSpawn = init.GetValue(info, true); } protected override void TraitEnabled(Actor self) @@ -92,13 +93,14 @@ namespace OpenRA.Mods.Common.Traits public readonly bool ActorValue = true; public FreeActorInit() { } public FreeActorInit(bool init) { ActorValue = init; } - public bool Value(World world) { return ActorValue; } + public bool Value { get { return ActorValue; } } } - public class ParentActorInit : IActorInit + public class ParentActorInit : IActorInit { - public readonly Actor ActorValue; - public ParentActorInit(Actor parent) { ActorValue = parent; } - public Actor Value(World world) { return ActorValue; } + readonly Actor value; + public ParentActorInit(Actor init) { value = init; } + + public Lazy Value(World world) { return new Lazy(() => value); } } } diff --git a/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs b/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs index 9ad052113d..fea345fd69 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs @@ -20,22 +20,26 @@ namespace OpenRA.Mods.Common.Traits { public bool IsValidTarget(ActorInfo actorInfo, Actor saboteur) { return false; } // TODO: bridges don't support frozen under fog - public override object Create(ActorInitializer init) { return new LegacyBridgeHut(init); } + public override object Create(ActorInitializer init) { return new LegacyBridgeHut(init, this); } } class LegacyBridgeHut : IDemolishable { - public readonly Bridge FirstBridge; - public readonly Bridge Bridge; + public Bridge FirstBridge { get; private set; } + public Bridge Bridge { get; private set; } public DamageState BridgeDamageState { get { return Bridge.AggregateDamageState(); } } public bool Repairing { get { return repairDirections > 0; } } int repairDirections = 0; - public LegacyBridgeHut(ActorInitializer init) + public LegacyBridgeHut(ActorInitializer init, LegacyBridgeHutInfo info) { - Bridge = init.Get().ActorValue.Trait(); - Bridge.AddHut(this); - FirstBridge = Bridge.Enumerate(0, true).Last(); + var bridge = init.GetOrDefault(info); + init.World.AddFrameEndTask(_ => + { + Bridge = bridge.Value(init.World).Value.Trait(); + Bridge.AddHut(this); + FirstBridge = Bridge.Enumerate(0, true).Last(); + }); } public void Repair(Actor repairer) diff --git a/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs b/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs index 127539f220..16df62756d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs @@ -23,10 +23,10 @@ namespace OpenRA.Mods.Common.Traits public LineBuildDirectionInit() { } public LineBuildDirectionInit(LineBuildDirection init) { value = init; } - public LineBuildDirection Value(World world) { return value; } + public LineBuildDirection Value { get { return value; } } } - public class LineBuildParentInit : IActorInit + public class LineBuildParentInit : IActorInit { [FieldFromYamlKey] public readonly string[] ParentNames = new string[0]; @@ -35,7 +35,8 @@ namespace OpenRA.Mods.Common.Traits public LineBuildParentInit() { } public LineBuildParentInit(Actor[] init) { parents = init; } - public Actor[] Value(World world) + public string[] Value { get { return ParentNames; } } + public Actor[] ActorValue(World world) { if (parents != null) return parents; @@ -79,8 +80,9 @@ namespace OpenRA.Mods.Common.Traits public LineBuild(ActorInitializer init, LineBuildInfo info) { this.info = info; - if (init.Contains()) - parentNodes = init.Get().Value(init.World); + var lineBuildParentInit = init.GetOrDefault(info); + if (lineBuildParentInit != null) + parentNodes = lineBuildParentInit.ActorValue(init.World); } void INotifyLineBuildSegmentsChanged.SegmentAdded(Actor self, Actor segment) diff --git a/OpenRA.Mods.Common/Traits/Buildings/SequencePlaceBuildingPreview.cs b/OpenRA.Mods.Common/Traits/Buildings/SequencePlaceBuildingPreview.cs index 359c491928..ecfa9b9815 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/SequencePlaceBuildingPreview.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/SequencePlaceBuildingPreview.cs @@ -61,15 +61,15 @@ namespace OpenRA.Mods.Common.Traits : base(wr, ai, info, init) { this.info = info; - var owner = init.Get().Value(wr.World); - var faction = init.Get().Value(wr.World); + var ownerName = init.Get().InternalName; + var faction = init.Get().Value; var rsi = ai.TraitInfo(); if (!string.IsNullOrEmpty(info.SequencePalette)) - palette = wr.Palette(info.SequencePaletteIsPlayerPalette ? info.SequencePalette + owner.InternalName : info.SequencePalette); + palette = wr.Palette(info.SequencePaletteIsPlayerPalette ? info.SequencePalette + ownerName : info.SequencePalette); else - palette = wr.Palette(rsi.Palette ?? rsi.PlayerPalette + owner.InternalName); + palette = wr.Palette(rsi.Palette ?? rsi.PlayerPalette + ownerName); preview = new Animation(wr.World, rsi.GetImage(ai, wr.World.Map.Rules.Sequences, faction)); preview.PlayRepeating(info.Sequence); diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index c85314dcea..1140e64fe7 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -129,14 +129,16 @@ namespace OpenRA.Mods.Common.Traits return Util.AdjacentCells(self.World, Target.FromActor(self)).Where(c => loc != c); }); - if (init.Contains()) + var runtimeCargoInit = init.GetOrDefault(info); + var cargoInit = init.GetOrDefault(info); + if (runtimeCargoInit != null) { - cargo = new List(init.Get()); + cargo = runtimeCargoInit.Value.ToList(); totalWeight = cargo.Sum(c => GetWeight(c)); } - else if (init.Contains()) + else if (cargoInit != null) { - foreach (var u in init.Get()) + foreach (var u in cargoInit.Value) { var unit = self.World.CreateActor(false, u.ToLowerInvariant(), new TypeDictionary { new OwnerInit(self.Owner) }); @@ -487,7 +489,7 @@ namespace OpenRA.Mods.Common.Traits readonly Actor[] value = { }; public RuntimeCargoInit() { } public RuntimeCargoInit(Actor[] init) { value = init; } - public Actor[] Value(World world) { return value; } + public Actor[] Value { get { return value; } } } public class CargoInit : IActorInit @@ -496,6 +498,6 @@ namespace OpenRA.Mods.Common.Traits readonly string[] value = { }; public CargoInit() { } public CargoInit(string[] init) { value = init; } - public string[] Value(World world) { return value; } + public string[] Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs index 0e5b964e09..6386d9977a 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs @@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits { var init = actor.Init(); if (init != null) - return init.Value(world) == DeployState.Deployed; + return init.Value == DeployState.Deployed; return false; }, @@ -111,8 +111,7 @@ namespace OpenRA.Mods.Common.Traits checkTerrainType = info.AllowedTerrainTypes.Count > 0; canTurn = self.Info.HasTraitInfo(); move = self.TraitOrDefault(); - if (init.Contains()) - deployState = init.Get(); + deployState = init.GetValue(info, DeployState.Undeployed); } protected override void Created(Actor self) @@ -344,6 +343,6 @@ namespace OpenRA.Mods.Common.Traits readonly DeployState value = DeployState.Deployed; public DeployStateInit() { } public DeployStateInit(DeployState init) { value = init; } - public DeployState Value(World world) { return value; } + public DeployState Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs index 311104836c..6d64cac349 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits public GrantConditionOnFaction(ActorInitializer init, GrantConditionOnFactionInfo info) : base(info) { - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnLineBuildDirection.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnLineBuildDirection.cs index bb0911c73a..20397e9cb5 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnLineBuildDirection.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnLineBuildDirection.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits public GrantConditionOnLineBuildDirection(ActorInitializer init, GrantConditionOnLineBuildDirectionInfo info) { this.info = info; - direction = init.Get().Value(init.World); + direction = init.GetValue(info); } void INotifyCreated.Created(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index 20e2a8b007..4105a6aa45 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -93,8 +93,9 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; this.info = info; - if (init.Contains()) - SetPosition(self, init.Get()); + var locationInit = init.GetOrDefault(info); + if (locationInit != null) + SetPosition(self, locationInit.Value); } void INotifyCreated.Created(Actor self) diff --git a/OpenRA.Mods.Common/Traits/GainsExperience.cs b/OpenRA.Mods.Common/Traits/GainsExperience.cs index 7f5eeb11cc..5026100fde 100644 --- a/OpenRA.Mods.Common/Traits/GainsExperience.cs +++ b/OpenRA.Mods.Common/Traits/GainsExperience.cs @@ -74,9 +74,7 @@ namespace OpenRA.Mods.Common.Traits this.info = info; MaxLevel = info.Conditions.Count; - - if (init.Contains()) - initialExperience = init.Get(); + initialExperience = init.GetValue(info, 0); } void INotifyCreated.Created(Actor self) @@ -154,6 +152,6 @@ namespace OpenRA.Mods.Common.Traits public ExperienceInit() { } public ExperienceInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Health.cs b/OpenRA.Mods.Common/Traits/Health.cs index 5b4045af9b..d8944ad885 100644 --- a/OpenRA.Mods.Common/Traits/Health.cs +++ b/OpenRA.Mods.Common/Traits/Health.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits actor => { var init = actor.Init(); - return init != null ? init.Value(world) : 100; + return init != null ? init.Value : 100; }, (actor, value) => actor.ReplaceInit(new HealthInit((int)value))); } @@ -68,10 +68,12 @@ namespace OpenRA.Mods.Common.Traits public Health(ActorInitializer init, HealthInfo info) { Info = info; - MaxHP = info.HP > 0 ? info.HP : 1; + MaxHP = hp = info.HP > 0 ? info.HP : 1; // Cast to long to avoid overflow when multiplying by the health - hp = init.Contains() ? (int)(init.Get() * (long)MaxHP / 100) : MaxHP; + var healthInit = init.GetOrDefault(info); + if (healthInit != null) + hp = (int)(healthInit.Value * (long)MaxHP / 100); DisplayHP = hp; } @@ -247,12 +249,15 @@ namespace OpenRA.Mods.Common.Traits value = init; } - public int Value(World world) + public int Value { - if (value < 0 || (value == 0 && !allowZero)) - return 1; + get + { + if (value < 0 || (value == 0 && !allowZero)) + return 1; - return value; + return value; + } } } } diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index e11c85c8a7..deefd4ba84 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -78,14 +78,14 @@ namespace OpenRA.Mods.Common.Traits this.info = info; self = init.Self; - TopLeft = init.Get(); - CenterPosition = init.Contains() ? init.Get() : init.World.Map.CenterOfCell(TopLeft); - Facing = init.Contains() ? init.Get() : 128; + TopLeft = init.GetValue(info); + CenterPosition = init.GetValue(info, init.World.Map.CenterOfCell(TopLeft)); + Facing = init.GetValue(info, 128); - dragSpeed = init.Contains() ? init.Get() : 0; + dragSpeed = init.GetValue(info, 0); finalPosition = init.World.Map.CenterOfCell(TopLeft); - effectiveOwner = init.Contains() ? init.Get() : self.Owner; + effectiveOwner = init.GetValue(info, self.Owner); } void INotifyCreated.Created(Actor self) @@ -178,6 +178,6 @@ namespace OpenRA.Mods.Common.Traits public HuskSpeedInit() { } public HuskSpeedInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Immobile.cs b/OpenRA.Mods.Common/Traits/Immobile.cs index c89b5cf4e2..0c8c81b876 100644 --- a/OpenRA.Mods.Common/Traits/Immobile.cs +++ b/OpenRA.Mods.Common/Traits/Immobile.cs @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits public Immobile(ActorInitializer init, ImmobileInfo info) { - location = init.Get(); + location = init.GetValue(info); position = init.World.Map.CenterOfCell(location); if (info.OccupiesSpace) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 80e915eb4d..0464f0a16f 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -128,7 +128,7 @@ namespace OpenRA.Mods.Common.Traits actor => { var init = actor.Init(); - return init != null ? init.Value(world) : InitialFacing; + return init != null ? init.Value : InitialFacing; }, (actor, value) => { @@ -137,18 +137,18 @@ namespace OpenRA.Mods.Common.Traits var turretsInit = actor.Init(); var facingInit = actor.Init(); - var oldFacing = facingInit != null ? facingInit.Value(world) : InitialFacing; + var oldFacing = facingInit != null ? facingInit.Value : InitialFacing; var newFacing = (int)value; if (turretInit != null) { - var newTurretFacing = (turretInit.Value(world) + newFacing - oldFacing + 255) % 255; + var newTurretFacing = (turretInit.Value + newFacing - oldFacing + 255) % 255; actor.ReplaceInit(new TurretFacingInit(newTurretFacing)); } if (turretsInit != null) { - var newTurretFacings = turretsInit.Value(world) + var newTurretFacings = turretsInit.Value .ToDictionary(kv => kv.Key, kv => (kv.Value + newFacing - oldFacing + 255) % 255); actor.ReplaceInit(new TurretFacingsInit(newTurretFacings)); } @@ -263,31 +263,34 @@ namespace OpenRA.Mods.Common.Traits speedModifiers = Exts.Lazy(() => self.TraitsImplementing().ToArray().Select(x => x.GetSpeedModifier())); ToSubCell = FromSubCell = info.LocomotorInfo.SharesCell ? init.World.Map.Grid.DefaultSubCell : SubCell.FullCell; - if (init.Contains()) + + var subCellInit = init.GetOrDefault(info); + if (subCellInit != null) { - FromSubCell = ToSubCell = init.Get(); + FromSubCell = ToSubCell = subCellInit.Value; returnToCellOnCreationRecalculateSubCell = false; } - if (init.Contains()) + var locationInit = init.GetOrDefault(info); + if (locationInit != null) { - fromCell = toCell = init.Get(); + fromCell = toCell = locationInit.Value; SetVisualPosition(self, init.World.Map.CenterOfSubCell(FromCell, FromSubCell)); } - Facing = oldFacing = init.Contains() ? init.Get() : info.InitialFacing; + Facing = oldFacing = init.GetValue(info, info.InitialFacing); // Sets the initial visual position // Unit will move into the cell grid (defined by LocationInit) as its initial activity - if (init.Contains()) + var centerPositionInit = init.GetOrDefault(info); + if (centerPositionInit != null) { - oldPos = init.Get(); + oldPos = centerPositionInit.Value; SetVisualPosition(self, oldPos); returnToCellOnCreation = true; } - if (init.Contains()) - creationActivityDelay = init.Get(); + creationActivityDelay = init.GetValue(info, 0); } protected override void Created(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs index 071ae0c67d..2ce6ef3957 100644 --- a/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs +++ b/OpenRA.Mods.Common/Traits/Modifiers/FrozenUnderFog.cs @@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits // Explore map-placed actors if the "Explore Map" option is enabled var shroudInfo = init.World.Map.Rules.Actors["player"].TraitInfo(); var exploredMap = init.World.LobbyInfo.GlobalSettings.OptionOrDefault("explored", shroudInfo.ExploredMapCheckboxEnabled); - startsRevealed = exploredMap && init.Contains() && !init.Contains(); + startsRevealed = exploredMap && init.Contains(info) && !init.Contains(info); var buildingInfo = init.Self.Info.TraitInfoOrDefault(); var footprintCells = buildingInfo != null ? buildingInfo.FrozenUnderFogTiles(init.Self.Location).ToList() : new List() { init.Self.Location }; footprint = footprintCells.SelectMany(c => map.ProjectedCellsCovering(c.ToMPos(map))).ToArray(); diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index 20a43d2321..5d12c9ab40 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs @@ -131,7 +131,7 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; Info = info; - Faction = init.Contains() ? init.Get() : self.Owner.Faction.InternalName; + Faction = init.GetValue(info, self.Owner.Faction.InternalName); IsValidFaction = !info.Factions.Any() || info.Factions.Contains(Faction); Enabled = IsValidFaction; diff --git a/OpenRA.Mods.Common/Traits/Player/ProvidesPrerequisite.cs b/OpenRA.Mods.Common/Traits/Player/ProvidesPrerequisite.cs index 2681c55fc0..e30fdb9130 100644 --- a/OpenRA.Mods.Common/Traits/Player/ProvidesPrerequisite.cs +++ b/OpenRA.Mods.Common/Traits/Player/ProvidesPrerequisite.cs @@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits if (string.IsNullOrEmpty(prerequisite)) prerequisite = init.Self.Info.Name; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } public IEnumerable ProvidesPrerequisites diff --git a/OpenRA.Mods.Common/Traits/Pluggable.cs b/OpenRA.Mods.Common/Traits/Pluggable.cs index 23681ef9ff..80f39b4d39 100644 --- a/OpenRA.Mods.Common/Traits/Pluggable.cs +++ b/OpenRA.Mods.Common/Traits/Pluggable.cs @@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits { Info = info; - var plugInit = init.Contains() ? init.Get>() : new Dictionary(); + var plugInit = init.GetValue>(info, new Dictionary()); if (plugInit.ContainsKey(Info.Offset)) initialPlug = plugInit[Info.Offset]; @@ -126,6 +126,6 @@ namespace OpenRA.Mods.Common.Traits readonly Dictionary value = new Dictionary(); public PlugsInit() { } public PlugsInit(Dictionary init) { value = init; } - public Dictionary Value(World world) { return value; } + public Dictionary Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index 4efba7cdaf..bd2c6c3b69 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits : base(info) { rp = Exts.Lazy(() => init.Self.IsDead ? null : init.Self.TraitOrDefault()); - Faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + Faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } public virtual void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo, string productionType, TypeDictionary inits) diff --git a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs index db598b9c64..0f8f9199b5 100644 --- a/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs +++ b/OpenRA.Mods.Common/Traits/ProductionFromMapEdge.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using OpenRA.Primitives; +using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { @@ -30,8 +31,10 @@ namespace OpenRA.Mods.Common.Traits : base(init, info) { domainIndex = init.Self.World.WorldActor.Trait(); - if (init.Contains()) - spawnLocation = init.Get(); + + var spawnLocationInit = init.GetOrDefault(info); + if (spawnLocationInit != null) + spawnLocation = spawnLocationInit.Value; } protected override void Created(Actor self) @@ -114,6 +117,6 @@ namespace OpenRA.Mods.Common.Traits public ProductionSpawnLocationInit() { } public ProductionSpawnLocationInit(CPos init) { value = init; } - public CPos Value(World world) { return value; } + public CPos Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs index 83121d6fc6..a7283a412c 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs @@ -49,8 +49,8 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreview(ActorPreviewInitializer init) { var sequenceProvider = init.World.Map.Rules.Sequences; - var faction = init.Get(); - var ownerName = init.Get().PlayerName; + var faction = init.GetValue(this); + var ownerName = init.Get(this).InternalName; var image = GetImage(init.Actor, sequenceProvider, faction); var palette = init.WorldRenderer.Palette(Palette ?? PlayerPalette + ownerName); @@ -169,7 +169,7 @@ namespace OpenRA.Mods.Common.Traits.Render public RenderSprites(ActorInitializer init, RenderSpritesInfo info) { Info = info; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } public string GetImage(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs b/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs index e23001e831..7344020be1 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs @@ -57,8 +57,8 @@ namespace OpenRA.Mods.Common.Traits.Render public virtual IEnumerable RenderPreview(ActorPreviewInitializer init) { var body = init.Actor.TraitInfo(); - var faction = init.Get(); - var ownerName = init.Get().PlayerName; + var faction = init.GetValue(this); + var ownerName = init.Get(this).InternalName; var sequenceProvider = init.World.Map.Rules.Sequences; var image = Image ?? init.Actor.Name; var facings = body.QuantizedFacings == -1 ? diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index ccae38d6e6..dd7bda00b7 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -49,14 +49,15 @@ namespace OpenRA.Mods.Common.Traits.Render p = init.WorldRenderer.Palette(Palette); Func facing; - if (init.Contains()) + var dynamicfacingInit = init.GetOrDefault(this); + if (dynamicfacingInit != null) { - var getFacing = init.Get>(); + var getFacing = dynamicfacingInit.Value; facing = () => WAngle.FromFacing(getFacing()); } else { - var f = WAngle.FromFacing(init.Contains() ? init.Get() : 0); + var f = WAngle.FromFacing(init.GetValue(this, 0)); facing = () => f; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs index c3ecdcbcd9..59be5403a5 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithMakeAnimation.cs @@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.Traits.Render this.info = info; var self = init.Self; wsbs = self.TraitsImplementing().Where(w => info.BodyNames.Contains(w.Info.Name)).ToArray(); - skipMakeAnimation = init.Contains(); + skipMakeAnimation = init.Contains(info); } void INotifyCreated.Created(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs index 3beae82541..a60aa2b239 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs @@ -78,11 +78,12 @@ namespace OpenRA.Mods.Common.Traits.Render p = init.WorldRenderer.Palette(Palette); Func facing; - if (init.Contains()) - facing = init.Get>(); + var dynamicfacingInit = init.GetOrDefault(this); + if (dynamicfacingInit != null) + facing = dynamicfacingInit.Value; else { - var f = init.Contains() ? init.Get() : 0; + var f = init.GetValue(this, 0); facing = () => f; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs index 514a2558f3..3b3b86eb0f 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits.Render var t = init.Actor.TraitInfos() .First(tt => tt.Turret == armament.Turret); - var turretFacing = Turreted.TurretFacingFromInit(init, t.InitialFacing, armament.Turret); + var turretFacing = Turreted.TurretFacingFromInit(init, t); var anim = new Animation(init.World, image, () => WAngle.FromFacing(turretFacing())); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs index 8882c87463..b4174d2a37 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits.Render var t = init.Actor.TraitInfos() .First(tt => tt.Turret == Turret); - var turretFacing = Turreted.TurretFacingFromInit(init, t.InitialFacing, Turret); + var turretFacing = Turreted.TurretFacingFromInit(init, t); var anim = new Animation(init.World, image, () => WAngle.FromFacing(turretFacing())); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits.Render }; if (IsPlayerPalette) - p = init.WorldRenderer.Palette(Palette + init.Get().PlayerName); + p = init.WorldRenderer.Palette(Palette + init.Get(this).InternalName); else if (Palette != null) p = init.WorldRenderer.Palette(Palette); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs index 22e41a7221..91002af780 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits.Render var model = init.World.ModelCache.GetModelSequence(image, Sequence); - var turretFacing = Turreted.TurretFacingFromInit(init, t.InitialFacing, t.Turret); + var turretFacing = Turreted.TurretFacingFromInit(init, t); Func turretOrientation = () => body.QuantizeOrientation(WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw), facings); Func quantizedTurret = () => body.QuantizeOrientation(turretOrientation(), facings); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs index f0b56d51e4..1623a0bdf0 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs @@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits.Render var model = init.World.ModelCache.GetModelSequence(image, Sequence); Func turretOffset = () => body.LocalToWorld(t.Offset.Rotate(orientation())); - var turretFacing = Turreted.TurretFacingFromInit(init, t.InitialFacing, Turret); + var turretFacing = Turreted.TurretFacingFromInit(init, t); Func turretBodyOrientation = () => WRot.FromYaw(WAngle.FromFacing(turretFacing()) - orientation().Yaw); yield return new ModelAnimation(model, turretOffset, () => new[] { turretBodyOrientation(), body.QuantizeOrientation(orientation(), facings) }, () => false, () => 0, ShowShadow); diff --git a/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs b/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs index 29e635541c..96384ec508 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs @@ -37,15 +37,13 @@ namespace OpenRA.Mods.Common.Traits.Render yield break; var adjacent = 0; + var locationInit = init.GetOrDefault(this); + var neighbourInit = init.GetOrDefault(this); - if (init.Contains()) + if (locationInit != null && neighbourInit != null) { - var location = CPos.Zero; - if (init.Contains()) - location = init.Get(); - - var neighbours = init.Get>(); - foreach (var kv in neighbours) + var location = locationInit.Value; + foreach (var kv in neighbourInit.Value) { var haveNeighbour = false; foreach (var n in kv.Value) @@ -177,6 +175,6 @@ namespace OpenRA.Mods.Common.Traits.Render public RuntimeNeighbourInit() { } public RuntimeNeighbourInit(Dictionary init) { value = init; } - public Dictionary Value(World world) { return value; } + public Dictionary Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/ScriptTags.cs b/OpenRA.Mods.Common/Traits/ScriptTags.cs index 718c83160c..c09c4a2d8e 100644 --- a/OpenRA.Mods.Common/Traits/ScriptTags.cs +++ b/OpenRA.Mods.Common/Traits/ScriptTags.cs @@ -26,8 +26,9 @@ namespace OpenRA.Mods.Common.Traits public ScriptTags(ActorInitializer init, ScriptTagsInfo info) { - if (init.Contains()) - foreach (var tag in init.Get()) + var scriptTagsInit = init.GetOrDefault(info); + if (scriptTagsInit != null) + foreach (var tag in scriptTagsInit.Value) tags.Add(tag); } @@ -55,6 +56,6 @@ namespace OpenRA.Mods.Common.Traits public ScriptTagsInit() { } public ScriptTagsInit(string[] init) { value = init; } - public string[] Value(World world) { return value; } + public string[] Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs b/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs index 39a688ee5e..eb0bbe58bb 100644 --- a/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs +++ b/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs @@ -72,7 +72,7 @@ namespace OpenRA.Mods.Common.Traits : base(info) { enabled = !info.RequiresLobbyCreeps || init.Self.World.WorldActor.Trait().Enabled; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } void INotifyKilled.Killed(Actor self, AttackInfo e) diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/ProduceActorPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/ProduceActorPower.cs index c7d96c23c9..b5bfe1531a 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/ProduceActorPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/ProduceActorPower.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits public ProduceActorPower(ActorInitializer init, ProduceActorPowerInfo info) : base(init.Self, info) { - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } public override void SelectTarget(Actor self, string order, SupportPowerManager manager) diff --git a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs index a167278282..21c09a0349 100644 --- a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs +++ b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs @@ -65,9 +65,9 @@ namespace OpenRA.Mods.Common.Traits var body = self.Trait(); // TODO: Carry orientation over from the parent instead of just facing - var bodyFacing = init.Contains() ? init.Get>()() - : init.Contains() ? init.Get() : 0; - facing = WAngle.FromFacing(Turreted.TurretFacingFromInit(init, 0)()); + var dynamicFacingInit = init.GetOrDefault(info); + var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue(info, 0); + facing = WAngle.FromFacing(Turreted.TurretFacingFromInit(init, info, 0)()); // Calculate final position var throwRotation = WRot.FromFacing(Game.CosmeticRandom.Next(1024)); diff --git a/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs b/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs index 9091da2c03..79c2cd3fd1 100644 --- a/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs +++ b/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits public TransformCrusherOnCrush(ActorInitializer init, TransformCrusherOnCrushInfo info) { this.info = info; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } void INotifyCrushed.WarnCrush(Actor self, Actor crusher, BitSet crushClasses) { } diff --git a/OpenRA.Mods.Common/Traits/TransformOnCapture.cs b/OpenRA.Mods.Common/Traits/TransformOnCapture.cs index c932b63d7d..f700b394c2 100644 --- a/OpenRA.Mods.Common/Traits/TransformOnCapture.cs +++ b/OpenRA.Mods.Common/Traits/TransformOnCapture.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits public TransformOnCapture(ActorInitializer init, TransformOnCaptureInfo info) { this.info = info; - faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; + faction = init.GetValue(info, init.Self.Owner.Faction.InternalName); } void INotifyCapture.OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet captureTypes) diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index 7b714a2269..628ef7f2d8 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; actorInfo = self.World.Map.Rules.Actors[info.IntoActor]; buildingInfo = actorInfo.TraitInfoOrDefault(); - faction = init.Contains() ? init.Get() : self.Owner.Faction.InternalName; + faction = init.GetValue(info, self.Owner.Faction.InternalName); } public string VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs index e83358b9e2..ea6df701bb 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -55,11 +55,11 @@ namespace OpenRA.Mods.Common.Traits { var init = actor.Init(); if (init != null) - return init.Value(world); + return init.Value; var facingInit = actor.Init(); if (facingInit != null) - return facingInit.Value(world); + return facingInit.Value; return InitialFacing; }, @@ -94,44 +94,51 @@ namespace OpenRA.Mods.Common.Traits public WVec Offset { get { return Info.Offset + localOffset; } } public string Name { get { return Info.Turret; } } - public static Func TurretFacingFromInit(IActorInitializer init, int def, string turret = null) + public static Func TurretFacingFromInit(IActorInitializer init, TurretedInfo info) { - if (turret != null && init.Contains()) - { - Func facing; - if (init.Get>>().TryGetValue(turret, out facing)) - return facing; - } + return TurretFacingFromInit(init, info, info.InitialFacing, info.Turret); + } - if (turret != null && init.Contains()) + public static Func TurretFacingFromInit(IActorInitializer init, TraitInfo info, int defaultFacing, string turret = null) + { + if (turret != null) { + Func getFacing; + var dynamicTurretFacingsInit = init.GetOrDefault(info); + if (dynamicTurretFacingsInit != null && dynamicTurretFacingsInit.Value.TryGetValue(turret, out getFacing)) + return getFacing; + int facing; - if (init.Get>().TryGetValue(turret, out facing)) + var turretFacingsInit = init.GetOrDefault(info); + if (turretFacingsInit != null && turretFacingsInit.Value.TryGetValue(turret, out facing)) return () => facing; } - if (init.Contains()) + var turretFacingInit = init.GetOrDefault(info); + if (turretFacingInit != null) { - var facing = init.Get(); + var facing = turretFacingInit.Value; return () => facing; } - if (init.Contains()) - return init.Get>(); + var dynamicFacingInit = init.GetOrDefault(info); + if (dynamicFacingInit != null) + return dynamicFacingInit.Value; - if (init.Contains()) + var facingInit = init.GetOrDefault(info); + if (facingInit != null) { - var facing = init.Get(); + var facing = facingInit.Value; return () => facing; } - return () => def; + return () => defaultFacing; } public Turreted(ActorInitializer init, TurretedInfo info) : base(info) { - TurretFacing = TurretFacingFromInit(init, Info.InitialFacing, Info.Turret)(); + TurretFacing = TurretFacingFromInit(init, Info)(); } protected override void Created(Actor self) @@ -228,8 +235,8 @@ namespace OpenRA.Mods.Common.Traits init.Add(facings); } - if (!facings.Value(self.World).ContainsKey(Name)) - facings.Value(self.World).Add(Name, TurretFacing); + if (!facings.Value.ContainsKey(Name)) + facings.Value.Add(Name, TurretFacing); } void IActorPreviewInitModifier.ModifyActorPreviewInit(Actor self, TypeDictionary inits) @@ -245,13 +252,13 @@ namespace OpenRA.Mods.Common.Traits var dynamicFacing = inits.GetOrDefault(); var staticFacing = inits.GetOrDefault(); if (dynamicFacing != null) - bodyFacing = dynamicFacing.Value(self.World); + bodyFacing = dynamicFacing.Value; else if (staticFacing != null) - bodyFacing = () => staticFacing.Value(self.World); + bodyFacing = () => staticFacing.Value; // Freeze the relative turret facing to its current value var facingOffset = TurretFacing - bodyFacing(); - facings.Value(self.World).Add(Name, () => bodyFacing() + facingOffset); + facings.Value.Add(Name, () => bodyFacing() + facingOffset); } protected override void TraitDisabled(Actor self) @@ -268,7 +275,7 @@ namespace OpenRA.Mods.Common.Traits public TurretFacingInit() { } public TurretFacingInit(int init) { value = init; } - public int Value(World world) { return value; } + public int Value { get { return value; } } } public class TurretFacingsInit : IActorInit> @@ -278,7 +285,7 @@ namespace OpenRA.Mods.Common.Traits public TurretFacingsInit() { } public TurretFacingsInit(Dictionary init) { value = init; } - public Dictionary Value(World world) { return value; } + public Dictionary Value { get { return value; } } } public class DynamicTurretFacingsInit : IActorInit>> @@ -286,6 +293,6 @@ namespace OpenRA.Mods.Common.Traits readonly Dictionary> value = new Dictionary>(); public DynamicTurretFacingsInit() { } public DynamicTurretFacingsInit(Dictionary> init) { value = init; } - public Dictionary> Value(World world) { return value; } + public Dictionary> Value { get { return value; } } } } diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs index 361e05d82b..26fb30add8 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs @@ -118,8 +118,7 @@ namespace OpenRA.Mods.Common.Traits public EditorActorPreview Add(string id, ActorReference reference, bool initialSetup = false) { - var owner = Players.Players[reference.InitDict.Get().PlayerName]; - + var owner = Players.Players[reference.InitDict.Get().InternalName]; var preview = new EditorActorPreview(worldRenderer, id, reference, owner); Add(preview, initialSetup); diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs index dbb86d58c8..e02e2df9ba 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs @@ -67,11 +67,11 @@ namespace OpenRA.Mods.Common.Traits CenterPosition = PreviewPosition(world, actor.InitDict); - var location = actor.InitDict.Get().Value(worldRenderer.World); + var location = actor.InitDict.Get().Value; var ios = Info.TraitInfoOrDefault(); var subCellInit = actor.InitDict.GetOrDefault(); - var subCell = subCellInit != null ? subCellInit.Value(worldRenderer.World) : SubCell.Any; + var subCell = subCellInit != null ? subCellInit.Value : SubCell.Any; if (ios != null) Footprint = ios.OccupiedCells(Info, location, subCell); @@ -152,7 +152,7 @@ namespace OpenRA.Mods.Common.Traits Func saveInit = init => { var factionInit = init as FactionInit; - if (factionInit != null && factionInit.Faction == Owner.Faction) + if (factionInit != null && factionInit.Value == Owner.Faction) return false; // TODO: Other default values will need to be filtered @@ -166,15 +166,15 @@ namespace OpenRA.Mods.Common.Traits WPos PreviewPosition(World world, TypeDictionary init) { if (init.Contains()) - return init.Get().Value(world); + return init.Get().Value; if (init.Contains()) { - var cell = init.Get().Value(world); + var cell = init.Get().Value; var offset = WVec.Zero; var subCellInit = Actor.InitDict.GetOrDefault(); - var subCell = subCellInit != null ? subCellInit.Value(worldRenderer.World) : SubCell.Any; + var subCell = subCellInit != null ? subCellInit.Value : SubCell.Any; var buildingInfo = Info.TraitInfoOrDefault(); if (buildingInfo != null) diff --git a/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs b/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs index 147e2c7614..2011e00692 100644 --- a/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs +++ b/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); // If there is no real player associated, don't spawn it. - var ownerName = actorReference.InitDict.Get().PlayerName; + var ownerName = actorReference.InitDict.Get().InternalName; if (!world.Players.Any(p => p.InternalName == ownerName)) continue; @@ -68,9 +68,6 @@ namespace OpenRA.Mods.Common.Traits public readonly string Name; public SpawnedByMapInit(string name) { Name = name; } - public string Value(World world) - { - return Name; - } + public string Value { get { return Name; } } } } diff --git a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs index 36705dc596..64e9e28131 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ResizeMapCommand.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.UtilityCommands foreach (var kv in map.ActorDefinitions) { var actor = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); - var location = actor.InitDict.Get().Value(null); + var location = actor.InitDict.Get().Value; if (!map.Contains(location)) { Console.WriteLine("Removing actor {0} located at {1} due being outside of the new map boundaries.".F(actor.Type, location)); diff --git a/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs b/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs index 5b16073e17..e9751ce698 100644 --- a/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs +++ b/OpenRA.Mods.D2k/Traits/Render/WithCrumbleOverlay.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.D2k.Traits.Render { this.info = info; - if (init.Contains()) + if (init.Contains(info)) return; renderSprites = init.Self.Trait();