From b8566131947a41c90410b9923b6e54c28ed1cbdb Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 30 May 2020 16:48:35 +0100 Subject: [PATCH] Add ISingleInstanceInit interface. Inits that are logically singletons (e.g. actor location or owner) should implement this interface to avoid runtime inconsistencies. Duplicate instances are rejected at init-time, allowing simpler queries when they are used. --- OpenRA.Game/Actor.cs | 9 +++- OpenRA.Game/Map/ActorInitializer.cs | 41 ++++++++++++++++--- OpenRA.Game/Map/ActorReference.cs | 18 +++++++- OpenRA.Game/Primitives/TypeDictionary.cs | 5 +++ OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs | 4 +- OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs | 4 +- .../Infiltration/InfiltrateForTransform.cs | 2 +- .../Traits/Render/WithBuildingBib.cs | 2 +- OpenRA.Mods.Cnc/Traits/TDGunboat.cs | 6 +-- OpenRA.Mods.Common/ActorInitializer.cs | 12 +++--- OpenRA.Mods.Common/Graphics/ActorPreview.cs | 23 +++++++++++ OpenRA.Mods.Common/Traits/Air/Aircraft.cs | 8 ++-- OpenRA.Mods.Common/Traits/AutoTarget.cs | 4 +- OpenRA.Mods.Common/Traits/BodyOrientation.cs | 2 +- .../Traits/Buildings/Building.cs | 2 +- .../Traits/Buildings/FreeActor.cs | 2 +- .../Traits/Buildings/LegacyBridgeHut.cs | 2 +- .../Traits/Buildings/LineBuild.cs | 6 +-- .../Conditions/GrantConditionOnDeploy.cs | 9 ++-- .../Conditions/GrantConditionOnFaction.cs | 2 +- .../GrantConditionOnLineBuildDirection.cs | 2 +- OpenRA.Mods.Common/Traits/Crates/Crate.cs | 2 +- OpenRA.Mods.Common/Traits/Health.cs | 7 +--- OpenRA.Mods.Common/Traits/Husk.cs | 10 ++--- OpenRA.Mods.Common/Traits/Immobile.cs | 2 +- OpenRA.Mods.Common/Traits/Mobile.cs | 10 ++--- .../Traits/Modifiers/FrozenUnderFog.cs | 4 +- .../Traits/Player/ProductionQueue.cs | 2 +- .../Traits/Player/ProvidesPrerequisite.cs | 2 +- OpenRA.Mods.Common/Traits/Pluggable.cs | 2 +- OpenRA.Mods.Common/Traits/Production.cs | 2 +- .../Traits/Render/RenderSprites.cs | 4 +- .../Traits/Render/RenderVoxels.cs | 2 +- .../Traits/Render/WithIdleOverlay.cs | 4 +- .../Traits/Render/WithParachute.cs | 4 +- .../Traits/Render/WithSpriteTurret.cs | 2 +- .../Traits/Render/WithWallSpriteBody.cs | 6 +-- .../Traits/SpawnActorOnDeath.cs | 2 +- .../Traits/SupportPowers/ProduceActorPower.cs | 2 +- OpenRA.Mods.Common/Traits/ThrowsParticle.cs | 4 +- .../Traits/TransformCrusherOnCrush.cs | 2 +- .../Traits/TransformOnCapture.cs | 2 +- OpenRA.Mods.Common/Traits/Transforms.cs | 2 +- OpenRA.Mods.Common/Traits/Turreted.cs | 18 ++++---- .../Traits/World/SpawnMapActors.cs | 2 +- 45 files changed, 169 insertions(+), 95 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 9333f26f46..c9b24a61c6 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Eluant; using Eluant.ObjectBinding; @@ -116,13 +117,19 @@ namespace OpenRA internal Actor(World world, string name, TypeDictionary initDict) { + var duplicateInit = initDict.WithInterface().GroupBy(i => i.GetType()) + .FirstOrDefault(i => i.Count() > 1); + + if (duplicateInit != null) + throw new InvalidDataException("Duplicate initializer '{0}'".F(duplicateInit.Key.Name)); + var init = new ActorInitializer(this, initDict); readOnlyConditionCache = new ReadOnlyDictionary(conditionCache); World = world; ActorID = world.NextAID(); - var ownerInit = init.GetOrDefault(null); + var ownerInit = init.GetOrDefault(); if (ownerInit != null) Owner = ownerInit.Value(world); diff --git a/OpenRA.Game/Map/ActorInitializer.cs b/OpenRA.Game/Map/ActorInitializer.cs index 269391b686..fcf11e2335 100644 --- a/OpenRA.Game/Map/ActorInitializer.cs +++ b/OpenRA.Game/Map/ActorInitializer.cs @@ -26,6 +26,12 @@ namespace OpenRA U GetValue(TraitInfo info) where T : ValueActorInit; U GetValue(TraitInfo info, U fallback) where T : ValueActorInit; bool Contains(TraitInfo info) where T : ActorInit; + + T GetOrDefault() where T : ActorInit, ISingleInstanceInit; + T Get() where T : ActorInit, ISingleInstanceInit; + U GetValue() where T : ValueActorInit, ISingleInstanceInit; + U GetValue(U fallback) where T : ValueActorInit, ISingleInstanceInit; + bool Contains() where T : ActorInit, ISingleInstanceInit; } public class ActorInitializer : IActorInitializer @@ -77,6 +83,29 @@ namespace OpenRA } public bool Contains(TraitInfo info) where T : ActorInit { return GetOrDefault(info) != null; } + + public T GetOrDefault() where T : ActorInit, ISingleInstanceInit + { + return Dict.GetOrDefault(); + } + + public T Get() where T : ActorInit, ISingleInstanceInit + { + return Dict.Get(); + } + + public U GetValue() where T : ValueActorInit, ISingleInstanceInit + { + return Get().Value; + } + + public U GetValue(U fallback) where T : ValueActorInit, ISingleInstanceInit + { + var init = GetOrDefault(); + return init != null ? init.Value : fallback; + } + + public bool Contains() where T : ActorInit, ISingleInstanceInit { return GetOrDefault() != null; } } /* @@ -88,6 +117,9 @@ namespace OpenRA * finds with an argument type that matches the given LuaValue. * - Most ActorInits will want to inherit either ValueActorInit or CompositeActorInit which hide the low-level plumbing. * - Inits that reference actors should use ActorInitActorReference which allows actors to be referenced by name in map.yaml + * - Inits that should only have a single instance defined on an actor should implement ISingleInstanceInit to allow + * direct queries and runtime enforcement. + * - Inits that aren't ISingleInstanceInit should expose a ctor that accepts a TraitInfo to allow per-trait targeting. */ public abstract class ActorInit { @@ -104,6 +136,8 @@ namespace OpenRA public abstract MiniYaml Save(); } + public interface ISingleInstanceInit { } + public abstract class ValueActorInit : ActorInit { protected readonly T value; @@ -181,16 +215,13 @@ namespace OpenRA } } - public class LocationInit : ValueActorInit + public class LocationInit : ValueActorInit, ISingleInstanceInit { - public LocationInit(TraitInfo info, CPos value) - : base(info, value) { } - public LocationInit(CPos value) : base(value) { } } - public class OwnerInit : ActorInit + public class OwnerInit : ActorInit, ISingleInstanceInit { public readonly string InternalName; protected readonly Player value; diff --git a/OpenRA.Game/Map/ActorReference.cs b/OpenRA.Game/Map/ActorReference.cs index 3aee55a924..ba873af104 100644 --- a/OpenRA.Game/Map/ActorReference.cs +++ b/OpenRA.Game/Map/ActorReference.cs @@ -40,7 +40,14 @@ namespace OpenRA { var dict = new TypeDictionary(); foreach (var i in inits) - dict.Add(LoadInit(i.Key, i.Value)); + { + var init = LoadInit(i.Key, i.Value); + if (init is ISingleInstanceInit && dict.Contains(init.GetType())) + throw new InvalidDataException("Duplicate initializer '{0}'".F(init.GetType().Name)); + + dict.Add(init); + } + return dict; }); } @@ -88,7 +95,14 @@ namespace OpenRA } // for initialization syntax - public void Add(object o) { InitDict.Add(o); } + public void Add(ActorInit init) + { + if (init is ISingleInstanceInit && InitDict.Contains(init.GetType())) + throw new InvalidDataException("Duplicate initializer '{0}'".F(init.GetType().Name)); + + InitDict.Add(init); + } + public IEnumerator GetEnumerator() { return InitDict.GetEnumerator(); } public ActorReference Clone() diff --git a/OpenRA.Game/Primitives/TypeDictionary.cs b/OpenRA.Game/Primitives/TypeDictionary.cs index 94c0eb2373..04d7b5d7ed 100644 --- a/OpenRA.Game/Primitives/TypeDictionary.cs +++ b/OpenRA.Game/Primitives/TypeDictionary.cs @@ -41,6 +41,11 @@ namespace OpenRA.Primitives return data.ContainsKey(typeof(T)); } + public bool Contains(Type t) + { + return data.ContainsKey(t); + } + public T Get() { return (T)Get(typeof(T), true); diff --git a/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs b/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs index 890ec6583d..1dfb40ad4a 100644 --- a/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs +++ b/OpenRA.Mods.Cnc/Traits/Chronoshiftable.cs @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Cnc.Traits { self = init.Self; - var returnInit = init.GetOrDefault(info); + var returnInit = init.GetOrDefault(); if (returnInit != null) { ReturnTicks = returnInit.Ticks; @@ -176,7 +176,7 @@ namespace OpenRA.Mods.Cnc.Traits void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); } } - public class ChronoshiftReturnInit : CompositeActorInit + public class ChronoshiftReturnInit : CompositeActorInit, ISingleInstanceInit { public readonly int Ticks; public readonly int Duration; diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index 4ea89117c3..2e1b2eeacd 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -95,9 +95,9 @@ namespace OpenRA.Mods.Cnc.Traits health = self.Trait(); wsb = self.TraitsImplementing().Single(w => w.Info.Name == info.Body); - faction = init.GetValue(info, self.Owner.Faction.InternalName); + faction = init.GetValue(self.Owner.Faction.InternalName); - var returnInit = init.GetOrDefault(info); + var returnInit = init.GetOrDefault(); if (returnInit != null) { returnTicks = returnInit.Ticks; diff --git a/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs b/OpenRA.Mods.Cnc/Traits/Infiltration/InfiltrateForTransform.cs index 708ecd4c68..299967d3a6 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 ef478ec625..271717496c 100644 --- a/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs +++ b/OpenRA.Mods.Cnc/Traits/Render/WithBuildingBib.cs @@ -45,7 +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 = init.GetValue(this, CPos.Zero); + var location = init.GetValue(CPos.Zero); for (var i = 0; i < rows * width; i++) { diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index 8d9b0c65ac..d3186c5599 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -82,15 +82,15 @@ namespace OpenRA.Mods.Cnc.Traits Info = info; self = init.Self; - var locationInit = init.GetOrDefault(info); + var locationInit = init.GetOrDefault(); if (locationInit != null) SetPosition(self, locationInit.Value); - var centerPositionInit = init.GetOrDefault(info); + var centerPositionInit = init.GetOrDefault(); if (centerPositionInit != null) SetPosition(self, centerPositionInit.Value); - Facing = WAngle.FromFacing(init.GetValue(info, Info.GetInitialFacing())); + Facing = WAngle.FromFacing(init.GetValue(Info.GetInitialFacing())); // Prevent mappers from setting bogus facings if (Facing != Left && Facing != Right) diff --git a/OpenRA.Mods.Common/ActorInitializer.cs b/OpenRA.Mods.Common/ActorInitializer.cs index 5405aaccb1..5a25349775 100644 --- a/OpenRA.Mods.Common/ActorInitializer.cs +++ b/OpenRA.Mods.Common/ActorInitializer.cs @@ -16,38 +16,38 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common { - public class FacingInit : ValueActorInit + public class FacingInit : ValueActorInit, ISingleInstanceInit { public FacingInit(int value) : base(value) { } } - public class CreationActivityDelayInit : ValueActorInit + public class CreationActivityDelayInit : ValueActorInit, ISingleInstanceInit { public CreationActivityDelayInit(int value) : base(value) { } } - public class DynamicFacingInit : ValueActorInit> + public class DynamicFacingInit : ValueActorInit>, ISingleInstanceInit { public DynamicFacingInit(Func value) : base(value) { } } - public class SubCellInit : ValueActorInit + public class SubCellInit : ValueActorInit, ISingleInstanceInit { public SubCellInit(SubCell value) : base(value) { } } - public class CenterPositionInit : ValueActorInit + public class CenterPositionInit : ValueActorInit, ISingleInstanceInit { public CenterPositionInit(WPos value) : base(value) { } } // Allows maps / transformations to specify the faction variant of an actor. - public class FactionInit : ValueActorInit + public class FactionInit : ValueActorInit, ISingleInstanceInit { public FactionInit(string value) : base(value) { } diff --git a/OpenRA.Mods.Common/Graphics/ActorPreview.cs b/OpenRA.Mods.Common/Graphics/ActorPreview.cs index ddf7c7f5fb..64dacf065f 100644 --- a/OpenRA.Mods.Common/Graphics/ActorPreview.cs +++ b/OpenRA.Mods.Common/Graphics/ActorPreview.cs @@ -77,6 +77,29 @@ namespace OpenRA.Mods.Common.Graphics return init != null ? init.Value : fallback; } + public bool Contains() where T : ActorInit, ISingleInstanceInit { return GetOrDefault() != null; } + + public T GetOrDefault() where T : ActorInit, ISingleInstanceInit + { + return dict.GetOrDefault(); + } + + public T Get() where T : ActorInit, ISingleInstanceInit + { + return dict.Get(); + } + + public U GetValue() where T : ValueActorInit, ISingleInstanceInit + { + return Get().Value; + } + + public U GetValue(U fallback) where T : ValueActorInit, ISingleInstanceInit + { + var init = GetOrDefault(); + return init != null ? init.Value : fallback; + } + public bool Contains(TraitInfo info) where T : ActorInit { return GetOrDefault(info) != null; } public Func GetOrientation() diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index 24bf8ee431..4ec3eb1094 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -249,16 +249,16 @@ namespace OpenRA.Mods.Common.Traits { self = init.Self; - var locationInit = init.GetOrDefault(info); + var locationInit = init.GetOrDefault(); if (locationInit != null) SetPosition(self, locationInit.Value); - var centerPositionInit = init.GetOrDefault(info); + var centerPositionInit = init.GetOrDefault(); if (centerPositionInit != null) SetPosition(self, centerPositionInit.Value); - Facing = WAngle.FromFacing(init.GetValue(info, Info.InitialFacing)); - creationActivityDelay = init.GetValue(info, 0); + Facing = WAngle.FromFacing(init.GetValue(Info.InitialFacing)); + creationActivityDelay = init.GetValue(0); } public WDist LandAltitude diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index 517aec9ca4..857286348f 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -183,7 +183,7 @@ namespace OpenRA.Mods.Common.Traits var self = init.Self; ActiveAttackBases = self.TraitsImplementing().ToArray().Where(Exts.IsTraitEnabled); - stance = init.GetValue(info, self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance); + stance = init.GetValue(self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance); PredictedStance = stance; @@ -445,7 +445,7 @@ namespace OpenRA.Mods.Common.Traits } } - public class StanceInit : ValueActorInit + public class StanceInit : ValueActorInit, ISingleInstanceInit { public StanceInit(TraitInfo info, UnitStance value) : base(info, value) { } diff --git a/OpenRA.Mods.Common/Traits/BodyOrientation.cs b/OpenRA.Mods.Common/Traits/BodyOrientation.cs index 6b13657b2a..b4589b224f 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.GetValue(info, self.Owner.Faction.InternalName); + var faction = init.GetValue(self.Owner.Faction.InternalName); quantizedFacings = Exts.Lazy(() => { diff --git a/OpenRA.Mods.Common/Traits/Buildings/Building.cs b/OpenRA.Mods.Common/Traits/Buildings/Building.cs index 44e74b9d41..2d78c4c320 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.GetValue(info); + topLeft = init.GetValue(); 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 607c7522e1..dce1f0e31d 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/FreeActor.cs @@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits : base(info, value) { } } - public class ParentActorInit : ValueActorInit + public class ParentActorInit : ValueActorInit, ISingleInstanceInit { public ParentActorInit(Actor value) : base(value) { } diff --git a/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs b/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs index 24b8143784..a96ea987c6 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/LegacyBridgeHut.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits public LegacyBridgeHut(ActorInitializer init, LegacyBridgeHutInfo info) { - var bridge = init.Get(info).Value; + var bridge = init.Get().Value; init.World.AddFrameEndTask(_ => { Bridge = bridge.Actor(init.World).Value.Trait(); diff --git a/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs b/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs index 413fa179cb..3aa4ba7f7e 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/LineBuild.cs @@ -16,13 +16,13 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { public enum LineBuildDirection { Unset, X, Y } - public class LineBuildDirectionInit : ValueActorInit + public class LineBuildDirectionInit : ValueActorInit, ISingleInstanceInit { public LineBuildDirectionInit(LineBuildDirection value) : base(value) { } } - public class LineBuildParentInit : ValueActorInit + public class LineBuildParentInit : ValueActorInit, ISingleInstanceInit { readonly Actor[] parents = null; @@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Traits public LineBuild(ActorInitializer init, LineBuildInfo info) { this.info = info; - var lineBuildParentInit = init.GetOrDefault(info); + var lineBuildParentInit = init.GetOrDefault(); if (lineBuildParentInit != null) parentNodes = lineBuildParentInit.ActorValue(init.World); } diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs index 4e12f2b0aa..e759ecc854 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs @@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits }, (actor, value) => { - actor.ReplaceInit(new DeployStateInit(this, value ? DeployState.Deployed : DeployState.Undeployed)); + actor.ReplaceInit(new DeployStateInit(value ? DeployState.Deployed : DeployState.Undeployed)); }); } @@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits checkTerrainType = info.AllowedTerrainTypes.Count > 0; canTurn = self.Info.HasTraitInfo(); move = self.TraitOrDefault(); - deployState = init.GetValue(info, DeployState.Undeployed); + deployState = init.GetValue(DeployState.Undeployed); } protected override void Created(Actor self) @@ -337,11 +337,8 @@ namespace OpenRA.Mods.Common.Traits } } - public class DeployStateInit : ValueActorInit + public class DeployStateInit : ValueActorInit, ISingleInstanceInit { - public DeployStateInit(TraitInfo info, DeployState value) - : base(info, value) { } - public DeployStateInit(DeployState value) : base(value) { } } diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnFaction.cs index 6d64cac349..52739b5325 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 20397e9cb5..6d29451803 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.GetValue(info); + direction = init.GetValue(); } void INotifyCreated.Created(Actor self) diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index 4105a6aa45..84bc140a9f 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; this.info = info; - var locationInit = init.GetOrDefault(info); + var locationInit = init.GetOrDefault(); if (locationInit != null) SetPosition(self, locationInit.Value); } diff --git a/OpenRA.Mods.Common/Traits/Health.cs b/OpenRA.Mods.Common/Traits/Health.cs index 8bcd58b655..d98368ca4b 100644 --- a/OpenRA.Mods.Common/Traits/Health.cs +++ b/OpenRA.Mods.Common/Traits/Health.cs @@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Traits MaxHP = hp = info.HP > 0 ? info.HP : 1; // Cast to long to avoid overflow when multiplying by the health - var healthInit = init.GetOrDefault(info); + var healthInit = init.GetOrDefault(); if (healthInit != null) hp = (int)(healthInit.Value * (long)MaxHP / 100); @@ -233,13 +233,10 @@ namespace OpenRA.Mods.Common.Traits } } - public class HealthInit : ValueActorInit + public class HealthInit : ValueActorInit, ISingleInstanceInit { readonly bool allowZero; - public HealthInit(TraitInfo info, int value, bool allowZero = false) - : base(info, value) { this.allowZero = allowZero; } - public HealthInit(int value, bool allowZero = false) : base(value) { this.allowZero = allowZero; } diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index 973d998d8a..2c00487f73 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -78,11 +78,11 @@ namespace OpenRA.Mods.Common.Traits this.info = info; self = init.Self; - TopLeft = init.GetValue(info); - CenterPosition = init.GetValue(info, init.World.Map.CenterOfCell(TopLeft)); - Facing = WAngle.FromFacing(init.GetValue(info, 128)); + TopLeft = init.GetValue(); + CenterPosition = init.GetValue(init.World.Map.CenterOfCell(TopLeft)); + Facing = WAngle.FromFacing(init.GetValue(128)); - dragSpeed = init.GetValue(info, 0); + dragSpeed = init.GetValue(0); finalPosition = init.World.Map.CenterOfCell(TopLeft); effectiveOwner = init.GetValue(info, self.Owner); @@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Traits Player IEffectiveOwner.Owner { get { return effectiveOwner; } } } - public class HuskSpeedInit : ValueActorInit + public class HuskSpeedInit : ValueActorInit, ISingleInstanceInit { public HuskSpeedInit(int value) : base(value) { } diff --git a/OpenRA.Mods.Common/Traits/Immobile.cs b/OpenRA.Mods.Common/Traits/Immobile.cs index 0c8c81b876..8c21fde1c4 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.GetValue(info); + location = init.GetValue(); 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 4eeb35b705..575f14550a 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -267,25 +267,25 @@ namespace OpenRA.Mods.Common.Traits ToSubCell = FromSubCell = info.LocomotorInfo.SharesCell ? init.World.Map.Grid.DefaultSubCell : SubCell.FullCell; - var subCellInit = init.GetOrDefault(info); + var subCellInit = init.GetOrDefault(); if (subCellInit != null) { FromSubCell = ToSubCell = subCellInit.Value; returnToCellOnCreationRecalculateSubCell = false; } - var locationInit = init.GetOrDefault(info); + var locationInit = init.GetOrDefault(); if (locationInit != null) { fromCell = toCell = locationInit.Value; SetVisualPosition(self, init.World.Map.CenterOfSubCell(FromCell, FromSubCell)); } - Facing = oldFacing = WAngle.FromFacing(init.GetValue(info, info.InitialFacing)); + Facing = oldFacing = WAngle.FromFacing(init.GetValue(info.InitialFacing)); // Sets the initial visual position // Unit will move into the cell grid (defined by LocationInit) as its initial activity - var centerPositionInit = init.GetOrDefault(info); + var centerPositionInit = init.GetOrDefault(); if (centerPositionInit != null) { oldPos = centerPositionInit.Value; @@ -293,7 +293,7 @@ namespace OpenRA.Mods.Common.Traits returnToCellOnCreation = true; } - creationActivityDelay = init.GetValue(info, 0); + creationActivityDelay = init.GetValue(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 0a836d5db3..63efcf5c1d 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(info) && !init.Contains(info); + startsRevealed = exploredMap && init.Contains() && !init.Contains(); 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(); @@ -195,5 +195,5 @@ namespace OpenRA.Mods.Common.Traits } } - public class HiddenUnderFogInit : RuntimeFlagInit { } + public class HiddenUnderFogInit : RuntimeFlagInit, ISingleInstanceInit { } } diff --git a/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs b/OpenRA.Mods.Common/Traits/Player/ProductionQueue.cs index 5ace8b60d9..0c25914e15 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.GetValue(info, self.Owner.Faction.InternalName); + Faction = init.GetValue(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 75fb476790..09190906c6 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 351b43d21e..d5f7ecc218 100644 --- a/OpenRA.Mods.Common/Traits/Pluggable.cs +++ b/OpenRA.Mods.Common/Traits/Pluggable.cs @@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits } } - public class PlugsInit : ValueActorInit> + public class PlugsInit : ValueActorInit>, ISingleInstanceInit { public PlugsInit(Dictionary value) : base(value) { } diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index bd2c6c3b69..209af80eb3 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.GetValue(info, init.Self.Owner.Faction.InternalName); + Faction = init.GetValue(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/Render/RenderSprites.cs b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs index 3d8d338962..fdc2fa84f3 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderSprites.cs @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits.Render { var sequenceProvider = init.World.Map.Rules.Sequences; var faction = init.GetValue(this); - var ownerName = init.Get(this).InternalName; + var ownerName = init.Get().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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 7344020be1..2bff688bf5 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderVoxels.cs @@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits.Render { var body = init.Actor.TraitInfo(); var faction = init.GetValue(this); - var ownerName = init.Get(this).InternalName; + var ownerName = init.Get().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 dd7bda00b7..b7a7956ab9 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits.Render p = init.WorldRenderer.Palette(Palette); Func facing; - var dynamicfacingInit = init.GetOrDefault(this); + var dynamicfacingInit = init.GetOrDefault(); if (dynamicfacingInit != null) { var getFacing = dynamicfacingInit.Value; @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits.Render } else { - var f = WAngle.FromFacing(init.GetValue(this, 0)); + var f = WAngle.FromFacing(init.GetValue(0)); facing = () => f; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs index a60aa2b239..f52913fb86 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs @@ -78,12 +78,12 @@ namespace OpenRA.Mods.Common.Traits.Render p = init.WorldRenderer.Palette(Palette); Func facing; - var dynamicfacingInit = init.GetOrDefault(this); + var dynamicfacingInit = init.GetOrDefault(); if (dynamicfacingInit != null) facing = dynamicfacingInit.Value; else { - var f = init.GetValue(this, 0); + var f = init.GetValue(0); facing = () => f; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs index b4174d2a37..1bc1371419 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits.Render }; if (IsPlayerPalette) - p = init.WorldRenderer.Palette(Palette + init.Get(this).InternalName); + p = init.WorldRenderer.Palette(Palette + init.Get().InternalName); else if (Palette != null) p = init.WorldRenderer.Palette(Palette); diff --git a/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs b/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs index edabc58255..677645ed9e 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithWallSpriteBody.cs @@ -37,8 +37,8 @@ namespace OpenRA.Mods.Common.Traits.Render yield break; var adjacent = 0; - var locationInit = init.GetOrDefault(this); - var neighbourInit = init.GetOrDefault(this); + var locationInit = init.GetOrDefault(); + var neighbourInit = init.GetOrDefault(); if (locationInit != null && neighbourInit != null) { @@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Traits.Render } } - public class RuntimeNeighbourInit : ValueActorInit>, ISuppressInitExport + public class RuntimeNeighbourInit : ValueActorInit>, ISuppressInitExport, ISingleInstanceInit { public RuntimeNeighbourInit(Dictionary value) : base(value) { } diff --git a/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs b/OpenRA.Mods.Common/Traits/SpawnActorOnDeath.cs index eb0bbe58bb..4f983834bb 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 b5bfe1531a..7747909d36 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 21c09a0349..38814c98bc 100644 --- a/OpenRA.Mods.Common/Traits/ThrowsParticle.cs +++ b/OpenRA.Mods.Common/Traits/ThrowsParticle.cs @@ -65,8 +65,8 @@ namespace OpenRA.Mods.Common.Traits var body = self.Trait(); // TODO: Carry orientation over from the parent instead of just facing - var dynamicFacingInit = init.GetOrDefault(info); - var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue(info, 0); + var dynamicFacingInit = init.GetOrDefault(); + var bodyFacing = dynamicFacingInit != null ? dynamicFacingInit.Value() : init.GetValue(0); facing = WAngle.FromFacing(Turreted.TurretFacingFromInit(init, info, 0)()); // Calculate final position diff --git a/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs b/OpenRA.Mods.Common/Traits/TransformCrusherOnCrush.cs index 79c2cd3fd1..eb9fc613dd 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 f700b394c2..a5d9673f7a 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.GetValue(info, init.Self.Owner.Faction.InternalName); + faction = init.GetValue(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 5a3ca05219..6d6e70943b 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.GetValue(info, self.Owner.Faction.InternalName); + faction = init.GetValue(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 2052b0da9f..395df8ad15 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -106,12 +106,12 @@ namespace OpenRA.Mods.Common.Traits if (turret != null) { Func getFacing; - var dynamicTurretFacingsInit = init.GetOrDefault(info); + var dynamicTurretFacingsInit = init.GetOrDefault(); if (dynamicTurretFacingsInit != null && dynamicTurretFacingsInit.Value.TryGetValue(turret, out getFacing)) return getFacing; int facing; - var turretFacingsInit = init.GetOrDefault(info); + var turretFacingsInit = init.GetOrDefault(); if (turretFacingsInit != null && turretFacingsInit.Value.TryGetValue(turret, out facing)) return () => facing; } @@ -123,11 +123,11 @@ namespace OpenRA.Mods.Common.Traits return () => facing; } - var dynamicFacingInit = init.GetOrDefault(info); + var dynamicFacingInit = init.GetOrDefault(); if (dynamicFacingInit != null) return dynamicFacingInit.Value; - var facingInit = init.GetOrDefault(info); + var facingInit = init.GetOrDefault(); if (facingInit != null) { var facing = facingInit.Value; @@ -245,7 +245,7 @@ namespace OpenRA.Mods.Common.Traits var facings = inits.GetOrDefault(); if (facings == null) { - facings = new DynamicTurretFacingsInit(Info, new Dictionary>()); + facings = new DynamicTurretFacingsInit(new Dictionary>()); inits.Add(facings); } @@ -278,15 +278,15 @@ namespace OpenRA.Mods.Common.Traits : base(value) { } } - public class TurretFacingsInit : ValueActorInit> + public class TurretFacingsInit : ValueActorInit>, ISingleInstanceInit { public TurretFacingsInit(Dictionary value) : base(value) { } } - public class DynamicTurretFacingsInit : ValueActorInit>> + public class DynamicTurretFacingsInit : ValueActorInit>>, ISingleInstanceInit { - public DynamicTurretFacingsInit(TraitInfo info, Dictionary> value) - : base(info, value) { } + public DynamicTurretFacingsInit(Dictionary> value) + : base(value) { } } } diff --git a/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs b/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs index 20feb914df..26eb50e445 100644 --- a/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs +++ b/OpenRA.Mods.Common/Traits/World/SpawnMapActors.cs @@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits } public class SkipMakeAnimsInit : RuntimeFlagInit { } - public class SpawnedByMapInit : ValueActorInit, ISuppressInitExport + public class SpawnedByMapInit : ValueActorInit, ISuppressInitExport, ISingleInstanceInit { public SpawnedByMapInit(string value) : base(value) { }