Replace IActorInit with an abstract class.
A shared ValueActorInit<T> is introduced to reduce duplication in the most common init cases, and an ActorInitActorReference allow actors to be referenced by map.yaml name.
This commit is contained in:
@@ -10,7 +10,9 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
@@ -19,11 +21,11 @@ namespace OpenRA
|
|||||||
public interface IActorInitializer
|
public interface IActorInitializer
|
||||||
{
|
{
|
||||||
World World { get; }
|
World World { get; }
|
||||||
T GetOrDefault<T>(TraitInfo info) where T : IActorInit;
|
T GetOrDefault<T>(TraitInfo info) where T : ActorInit;
|
||||||
T Get<T>(TraitInfo info) where T : IActorInit;
|
T Get<T>(TraitInfo info) where T : ActorInit;
|
||||||
U GetValue<T, U>(TraitInfo info) where T : IActorInit<U>;
|
U GetValue<T, U>(TraitInfo info) where T : ValueActorInit<U>;
|
||||||
U GetValue<T, U>(TraitInfo info, U fallback) where T : IActorInit<U>;
|
U GetValue<T, U>(TraitInfo info, U fallback) where T : ValueActorInit<U>;
|
||||||
bool Contains<T>(TraitInfo info) where T : IActorInit;
|
bool Contains<T>(TraitInfo info) where T : ActorInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ActorInitializer : IActorInitializer
|
public class ActorInitializer : IActorInitializer
|
||||||
@@ -39,12 +41,12 @@ namespace OpenRA
|
|||||||
Dict = dict;
|
Dict = dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetOrDefault<T>(TraitInfo info) where T : IActorInit
|
public T GetOrDefault<T>(TraitInfo info) where T : ActorInit
|
||||||
{
|
{
|
||||||
return Dict.GetOrDefault<T>();
|
return Dict.GetOrDefault<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get<T>(TraitInfo info) where T : IActorInit
|
public T Get<T>(TraitInfo info) where T : ActorInit
|
||||||
{
|
{
|
||||||
var init = GetOrDefault<T>(info);
|
var init = GetOrDefault<T>(info);
|
||||||
if (init == null)
|
if (init == null)
|
||||||
@@ -53,59 +55,119 @@ namespace OpenRA
|
|||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public U GetValue<T, U>(TraitInfo info) where T : IActorInit<U>
|
public U GetValue<T, U>(TraitInfo info) where T : ValueActorInit<U>
|
||||||
{
|
{
|
||||||
return Get<T>(info).Value;
|
return Get<T>(info).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public U GetValue<T, U>(TraitInfo info, U fallback) where T : IActorInit<U>
|
public U GetValue<T, U>(TraitInfo info, U fallback) where T : ValueActorInit<U>
|
||||||
{
|
{
|
||||||
var init = GetOrDefault<T>(info);
|
var init = GetOrDefault<T>(info);
|
||||||
return init != null ? init.Value : fallback;
|
return init != null ? init.Value : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains<T>(TraitInfo info) where T : IActorInit { return GetOrDefault<T>(info) != null; }
|
public bool Contains<T>(TraitInfo info) where T : ActorInit { return GetOrDefault<T>(info) != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IActorInit { }
|
/*
|
||||||
|
* Things to be aware of when writing ActorInits:
|
||||||
public interface IActorInit<T> : IActorInit
|
*
|
||||||
|
* - ActorReference and ActorGlobal can dynamically create objects without calling a constructor.
|
||||||
|
* The object will be allocated directly then the best matching Initialize() method will be called to set valid state.
|
||||||
|
* - ActorReference will always attempt to call Initialize(MiniYaml). ActorGlobal will use whichever one it first
|
||||||
|
* finds with an argument type that matches the given LuaValue.
|
||||||
|
* - Most ActorInits will want to inherit ValueActorInit<T> which hides the low-level plumbing.
|
||||||
|
* - Inits that reference actors should use ActorInitActorReference which allows actors to be referenced by name in map.yaml
|
||||||
|
*/
|
||||||
|
public abstract class ActorInit
|
||||||
{
|
{
|
||||||
T Value { get; }
|
public abstract MiniYaml Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LocationInit : IActorInit<CPos>
|
public abstract class ValueActorInit<T> : ActorInit
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
protected readonly T value;
|
||||||
readonly CPos value = CPos.Zero;
|
|
||||||
|
|
||||||
public LocationInit() { }
|
protected ValueActorInit(TraitInfo info, T value) { this.value = value; }
|
||||||
public LocationInit(CPos init) { value = init; }
|
|
||||||
public CPos Value { get { return value; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OwnerInit : IActorInit
|
protected ValueActorInit(T value) { this.value = value; }
|
||||||
{
|
|
||||||
[FieldFromYamlKey]
|
|
||||||
public readonly string InternalName = "Neutral";
|
|
||||||
|
|
||||||
Player player;
|
public virtual T Value { get { return value; } }
|
||||||
|
|
||||||
public OwnerInit() { }
|
public virtual void Initialize(MiniYaml yaml)
|
||||||
public OwnerInit(string playerName) { InternalName = playerName; }
|
|
||||||
|
|
||||||
public OwnerInit(Player player)
|
|
||||||
{
|
{
|
||||||
this.player = player;
|
var valueType = typeof(T).IsEnum ? Enum.GetUnderlyingType(typeof(T)) : typeof(T);
|
||||||
InternalName = player.InternalName;
|
Initialize((T)FieldLoader.GetValue("value", valueType, yaml.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Initialize(T value)
|
||||||
|
{
|
||||||
|
var field = GetType().GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
if (field != null)
|
||||||
|
field.SetValue(this, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MiniYaml Save()
|
||||||
|
{
|
||||||
|
return new MiniYaml(FieldSaver.FormatValue(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LocationInit : ValueActorInit<CPos>
|
||||||
|
{
|
||||||
|
public LocationInit(TraitInfo info, CPos value)
|
||||||
|
: base(info, value) { }
|
||||||
|
|
||||||
|
public LocationInit(CPos value)
|
||||||
|
: base(value) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OwnerInit : ActorInit
|
||||||
|
{
|
||||||
|
public readonly string InternalName;
|
||||||
|
protected readonly Player value;
|
||||||
|
|
||||||
|
public OwnerInit(Player value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
InternalName = value.InternalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnerInit(string value)
|
||||||
|
{
|
||||||
|
InternalName = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player Value(World world)
|
public Player Value(World world)
|
||||||
{
|
{
|
||||||
if (player != null)
|
return value ?? world.Players.First(x => x.InternalName == InternalName);
|
||||||
return player;
|
}
|
||||||
|
|
||||||
return world.Players.First(x => x.InternalName == InternalName);
|
public void Initialize(MiniYaml yaml)
|
||||||
|
{
|
||||||
|
var field = GetType().GetField("InternalName", BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
if (field != null)
|
||||||
|
field.SetValue(this, yaml.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(Player player)
|
||||||
|
{
|
||||||
|
var field = GetType().GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
if (field != null)
|
||||||
|
field.SetValue(this, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override MiniYaml Save()
|
||||||
|
{
|
||||||
|
return new MiniYaml(InternalName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class RuntimeFlagInit : ActorInit, ISuppressInitExport
|
||||||
|
{
|
||||||
|
public override MiniYaml Save()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("RuntimeFlagInit cannot be saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
@@ -43,26 +45,36 @@ namespace OpenRA
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static IActorInit LoadInit(string traitName, MiniYaml my)
|
static ActorInit LoadInit(string initName, MiniYaml initYaml)
|
||||||
{
|
{
|
||||||
var info = Game.CreateObject<IActorInit>(traitName + "Init");
|
var type = Game.ModData.ObjectCreator.FindType(initName + "Init");
|
||||||
FieldLoader.Load(info, my);
|
if (type == null)
|
||||||
return info;
|
throw new InvalidDataException("Unknown initializer type '{0}Init'".F(initName));
|
||||||
|
|
||||||
|
var init = (ActorInit)FormatterServices.GetUninitializedObject(type);
|
||||||
|
var loader = type.GetMethod("Initialize", new[] { typeof(MiniYaml) });
|
||||||
|
if (loader == null)
|
||||||
|
throw new InvalidDataException("{0}Init does not define a yaml-assignable type.".F(initName));
|
||||||
|
|
||||||
|
loader.Invoke(init, new[] { initYaml });
|
||||||
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MiniYaml Save(Func<object, bool> initFilter = null)
|
public MiniYaml Save(Func<ActorInit, bool> initFilter = null)
|
||||||
{
|
{
|
||||||
var ret = new MiniYaml(Type);
|
var ret = new MiniYaml(Type);
|
||||||
foreach (var init in InitDict)
|
foreach (var o in InitDict)
|
||||||
{
|
{
|
||||||
if (init is ISuppressInitExport)
|
var init = o as ActorInit;
|
||||||
|
if (init == null || o is ISuppressInitExport)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (initFilter != null && !initFilter(init))
|
if (initFilter != null && !initFilter(init))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var initName = init.GetType().Name;
|
var initTypeName = init.GetType().Name;
|
||||||
ret.Nodes.Add(new MiniYamlNode(initName.Substring(0, initName.Length - 4), FieldSaver.Save(init)));
|
var initName = initTypeName.Substring(0, initTypeName.Length - 4);
|
||||||
|
ret.Nodes.Add(new MiniYamlNode(initName, init.Save()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using OpenRA.Mods.Cnc.Activities;
|
using OpenRA.Mods.Cnc.Activities;
|
||||||
|
using OpenRA.Mods.Common;
|
||||||
using OpenRA.Mods.Common.Activities;
|
using OpenRA.Mods.Common.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
@@ -66,7 +67,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
// Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet
|
// Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet
|
||||||
var chronosphereInit = init.GetOrDefault<ChronoshiftChronosphereInit>(info);
|
var chronosphereInit = init.GetOrDefault<ChronoshiftChronosphereInit>(info);
|
||||||
if (chronosphereInit != null)
|
if (chronosphereInit != null)
|
||||||
init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value(init.World).Value);
|
init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value.Actor(init.World).Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ITick.Tick(Actor self)
|
void ITick.Tick(Actor self)
|
||||||
@@ -176,40 +177,27 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); }
|
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init) { ModifyActorInit(init); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChronoshiftReturnInit : IActorInit<int>
|
public class ChronoshiftReturnInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ChronoshiftReturnInit(int value)
|
||||||
readonly int value = 0;
|
: base(value) { }
|
||||||
|
|
||||||
public ChronoshiftReturnInit() { }
|
|
||||||
public ChronoshiftReturnInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChronoshiftDurationInit : IActorInit<int>
|
public class ChronoshiftDurationInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ChronoshiftDurationInit(int value)
|
||||||
readonly int value = 0;
|
: base(value) { }
|
||||||
|
|
||||||
public ChronoshiftDurationInit() { }
|
|
||||||
public ChronoshiftDurationInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChronoshiftOriginInit : IActorInit<CPos>
|
public class ChronoshiftOriginInit : ValueActorInit<CPos>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ChronoshiftOriginInit(CPos value)
|
||||||
readonly CPos value;
|
: base(value) { }
|
||||||
|
|
||||||
public ChronoshiftOriginInit(CPos init) { value = init; }
|
|
||||||
public CPos Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChronoshiftChronosphereInit : IActorInit
|
public class ChronoshiftChronosphereInit : ValueActorInit<ActorInitActorReference>
|
||||||
{
|
{
|
||||||
readonly Actor value;
|
public ChronoshiftChronosphereInit(Actor value)
|
||||||
public ChronoshiftChronosphereInit(Actor init) { value = init; }
|
: base(value) { }
|
||||||
|
|
||||||
public Lazy<Actor> Value(World world) { return new Lazy<Actor>(() => value); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
// Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet
|
// Defer to the end of tick as the lazy value may reference an actor that hasn't been created yet
|
||||||
var chronosphereInit = init.GetOrDefault<ChronoshiftChronosphereInit>(info);
|
var chronosphereInit = init.GetOrDefault<ChronoshiftChronosphereInit>(info);
|
||||||
if (chronosphereInit != null)
|
if (chronosphereInit != null)
|
||||||
init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value(init.World).Value);
|
init.World.AddFrameEndTask(w => chronosphere = chronosphereInit.Value.Actor(init.World).Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<VariableObserver> IObservesVariables.GetVariableObservers()
|
IEnumerable<VariableObserver> IObservesVariables.GetVariableObservers()
|
||||||
|
|||||||
@@ -133,8 +133,5 @@ namespace OpenRA.Mods.Cnc.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HideBibPreviewInit : IActorInit, ISuppressInitExport
|
class HideBibPreviewInit : RuntimeFlagInit { }
|
||||||
{
|
|
||||||
public HideBibPreviewInit() { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,13 +95,9 @@ namespace OpenRA.Mods.Cnc.Traits.Render
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BodyAnimationFrameInit : IActorInit<uint>
|
public class BodyAnimationFrameInit : ValueActorInit<uint>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public BodyAnimationFrameInit(uint value)
|
||||||
readonly uint value = 0;
|
: base(value) { }
|
||||||
|
|
||||||
public BodyAnimationFrameInit() { }
|
|
||||||
public BodyAnimationFrameInit(uint init) { value = init; }
|
|
||||||
public uint Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,77 +10,128 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common
|
namespace OpenRA.Mods.Common
|
||||||
{
|
{
|
||||||
public class FacingInit : IActorInit<int>
|
public class FacingInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public FacingInit(int value)
|
||||||
readonly int value = 128;
|
: base(value) { }
|
||||||
|
|
||||||
public FacingInit() { }
|
|
||||||
public FacingInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CreationActivityDelayInit : IActorInit<int>
|
public class CreationActivityDelayInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public CreationActivityDelayInit(int value)
|
||||||
readonly int value = 0;
|
: base(value) { }
|
||||||
|
|
||||||
public CreationActivityDelayInit() { }
|
|
||||||
public CreationActivityDelayInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DynamicFacingInit : IActorInit<Func<int>>
|
public class DynamicFacingInit : ValueActorInit<Func<int>>
|
||||||
{
|
{
|
||||||
readonly Func<int> func;
|
public DynamicFacingInit(Func<int> value)
|
||||||
|
: base(value) { }
|
||||||
public DynamicFacingInit(Func<int> func) { this.func = func; }
|
|
||||||
public Func<int> Value { get { return func; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SubCellInit : IActorInit<SubCell>
|
public class SubCellInit : ValueActorInit<SubCell>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public SubCellInit(SubCell value)
|
||||||
readonly byte value = (byte)SubCell.FullCell;
|
: base(value) { }
|
||||||
|
|
||||||
public SubCellInit() { }
|
|
||||||
public SubCellInit(byte init) { value = init; }
|
|
||||||
public SubCellInit(SubCell init) { value = (byte)init; }
|
|
||||||
public SubCell Value { get { return (SubCell)value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CenterPositionInit : IActorInit<WPos>
|
public class CenterPositionInit : ValueActorInit<WPos>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public CenterPositionInit(WPos value)
|
||||||
readonly WPos value = WPos.Zero;
|
: base(value) { }
|
||||||
|
|
||||||
public CenterPositionInit() { }
|
|
||||||
public CenterPositionInit(WPos init) { value = init; }
|
|
||||||
public WPos Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allows maps / transformations to specify the faction variant of an actor.
|
// Allows maps / transformations to specify the faction variant of an actor.
|
||||||
public class FactionInit : IActorInit<string>
|
public class FactionInit : ValueActorInit<string>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public FactionInit(string value)
|
||||||
public readonly string Faction;
|
: base(value) { }
|
||||||
|
|
||||||
public FactionInit() { }
|
|
||||||
public FactionInit(string faction) { Faction = faction; }
|
|
||||||
public string Value { get { return Faction; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EffectiveOwnerInit : IActorInit<Player>
|
public class EffectiveOwnerInit : ValueActorInit<Player>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public EffectiveOwnerInit(Player value)
|
||||||
readonly Player value = null;
|
: base(value) { }
|
||||||
|
}
|
||||||
|
|
||||||
public EffectiveOwnerInit() { }
|
internal class ActorInitLoader : TypeConverter
|
||||||
public EffectiveOwnerInit(Player owner) { value = owner; }
|
{
|
||||||
public Player Value { get { return value; } }
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||||
|
{
|
||||||
|
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
|
||||||
|
{
|
||||||
|
return new ActorInitActorReference(value as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
|
||||||
|
{
|
||||||
|
if (destinationType == typeof(string))
|
||||||
|
{
|
||||||
|
var reference = value as ActorInitActorReference;
|
||||||
|
if (reference != null)
|
||||||
|
return reference.InternalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.ConvertTo(context, culture, value, destinationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TypeConverter(typeof(ActorInitLoader))]
|
||||||
|
public class ActorInitActorReference
|
||||||
|
{
|
||||||
|
public readonly string InternalName;
|
||||||
|
readonly Actor actor;
|
||||||
|
|
||||||
|
public ActorInitActorReference(Actor actor)
|
||||||
|
{
|
||||||
|
this.actor = actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActorInitActorReference(string internalName)
|
||||||
|
{
|
||||||
|
InternalName = internalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor InnerValue(World world)
|
||||||
|
{
|
||||||
|
if (actor != null)
|
||||||
|
return actor;
|
||||||
|
|
||||||
|
var sma = world.WorldActor.Trait<SpawnMapActors>();
|
||||||
|
return sma.Actors[InternalName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The lazy value may reference other actors that have not been created
|
||||||
|
/// yet, so must not be resolved from the actor constructor or Created method.
|
||||||
|
/// Use a FrameEndTask or wait until it is actually needed.
|
||||||
|
/// </summary>
|
||||||
|
public Lazy<Actor> Actor(World world)
|
||||||
|
{
|
||||||
|
return new Lazy<Actor>(() => InnerValue(world));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator ActorInitActorReference(Actor a)
|
||||||
|
{
|
||||||
|
return new ActorInitActorReference(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator ActorInitActorReference(string mapName)
|
||||||
|
{
|
||||||
|
return new ActorInitActorReference(mapName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
@@ -41,12 +42,12 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
this.dict = dict;
|
this.dict = dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetOrDefault<T>(TraitInfo info) where T : IActorInit
|
public T GetOrDefault<T>(TraitInfo info) where T : ActorInit
|
||||||
{
|
{
|
||||||
return dict.GetOrDefault<T>();
|
return dict.GetOrDefault<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get<T>(TraitInfo info) where T : IActorInit
|
public T Get<T>(TraitInfo info) where T : ActorInit
|
||||||
{
|
{
|
||||||
var init = GetOrDefault<T>(info);
|
var init = GetOrDefault<T>(info);
|
||||||
if (init == null)
|
if (init == null)
|
||||||
@@ -55,18 +56,18 @@ namespace OpenRA.Mods.Common.Graphics
|
|||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public U GetValue<T, U>(TraitInfo info) where T : IActorInit<U>
|
public U GetValue<T, U>(TraitInfo info) where T : ValueActorInit<U>
|
||||||
{
|
{
|
||||||
return Get<T>(info).Value;
|
return Get<T>(info).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public U GetValue<T, U>(TraitInfo info, U fallback) where T : IActorInit<U>
|
public U GetValue<T, U>(TraitInfo info, U fallback) where T : ValueActorInit<U>
|
||||||
{
|
{
|
||||||
var init = GetOrDefault<T>(info);
|
var init = GetOrDefault<T>(info);
|
||||||
return init != null ? init.Value : fallback;
|
return init != null ? init.Value : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains<T>(TraitInfo info) where T : IActorInit { return GetOrDefault<T>(info) != null; }
|
public bool Contains<T>(TraitInfo info) where T : ActorInit { return GetOrDefault<T>(info) != null; }
|
||||||
|
|
||||||
public Func<WRot> GetOrientation()
|
public Func<WRot> GetOrientation()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using Eluant;
|
using Eluant;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
@@ -24,6 +27,37 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
public ActorGlobal(ScriptContext context)
|
public ActorGlobal(ScriptContext context)
|
||||||
: base(context) { }
|
: base(context) { }
|
||||||
|
|
||||||
|
ActorInit CreateInit(string initName, LuaValue value)
|
||||||
|
{
|
||||||
|
// Find the requested type
|
||||||
|
var initType = Game.ModData.ObjectCreator.FindType(initName + "Init");
|
||||||
|
if (initType == null)
|
||||||
|
throw new LuaException("Unknown initializer type '{0}'".F(initName));
|
||||||
|
|
||||||
|
// Construct the ActorInit.
|
||||||
|
var init = (ActorInit)FormatterServices.GetUninitializedObject(initType);
|
||||||
|
var initializers = initType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
||||||
|
.Where(m => m.Name == "Initialize" && m.GetParameters().Length == 1);
|
||||||
|
|
||||||
|
foreach (var initializer in initializers)
|
||||||
|
{
|
||||||
|
var parameterType = initializer.GetParameters().First().ParameterType;
|
||||||
|
var valueType = parameterType.IsEnum ? Enum.GetUnderlyingType(parameterType) : parameterType;
|
||||||
|
|
||||||
|
// Try and coerce the table value to the required type
|
||||||
|
object clrValue;
|
||||||
|
if (!value.TryGetClrValue(valueType, out clrValue))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
initializer.Invoke(init, new[] { clrValue });
|
||||||
|
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
var types = initializers.Select(y => y.GetParameters()[0].ParameterType.Name).JoinWith(", ");
|
||||||
|
throw new LuaException("Invalid data type for '{0}' (expected one of {1})".F(initName, types));
|
||||||
|
}
|
||||||
|
|
||||||
[Desc("Create a new actor. initTable specifies a list of key-value pairs that defines the initial parameters for the actor's traits.")]
|
[Desc("Create a new actor. initTable specifies a list of key-value pairs that defines the initial parameters for the actor's traits.")]
|
||||||
public Actor Create(string type, bool addToWorld, LuaTable initTable)
|
public Actor Create(string type, bool addToWorld, LuaTable initTable)
|
||||||
{
|
{
|
||||||
@@ -34,35 +68,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
{
|
{
|
||||||
using (kv.Key)
|
using (kv.Key)
|
||||||
using (kv.Value)
|
using (kv.Value)
|
||||||
{
|
initDict.Add(CreateInit(kv.Key.ToString(), kv.Value));
|
||||||
// Find the requested type
|
|
||||||
var typeName = kv.Key.ToString();
|
|
||||||
var initType = Game.ModData.ObjectCreator.FindType(typeName + "Init");
|
|
||||||
if (initType == null)
|
|
||||||
throw new LuaException("Unknown initializer type '{0}'".F(typeName));
|
|
||||||
|
|
||||||
// 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<T>
|
|
||||||
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;
|
|
||||||
if (!kv.Value.TryGetClrValue(valueType, out value))
|
|
||||||
throw new LuaException("Invalid data type for '{0}' (expected '{1}')".F(typeName, valueType.Name));
|
|
||||||
|
|
||||||
// Construct the ActorInit. Phew!
|
|
||||||
var test = initType.GetConstructor(new[] { innerType }).Invoke(new[] { value });
|
|
||||||
initDict.Add(test);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var owner = initDict.GetOrDefault<OwnerInit>();
|
var owner = initDict.GetOrDefault<OwnerInit>();
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var stance = init != null ? init.Value : InitialStance;
|
var stance = init != null ? init.Value : InitialStance;
|
||||||
return stances[(int)stance];
|
return stances[(int)stance];
|
||||||
},
|
},
|
||||||
(actor, value) => actor.ReplaceInit(new StanceInit((UnitStance)stances.IndexOf(value))));
|
(actor, value) => actor.ReplaceInit(new StanceInit(this, (UnitStance)stances.IndexOf(value))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,13 +445,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StanceInit : IActorInit<UnitStance>
|
public class StanceInit : ValueActorInit<UnitStance>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public StanceInit(TraitInfo info, UnitStance value)
|
||||||
readonly UnitStance value = UnitStance.AttackAnything;
|
: base(info, value) { }
|
||||||
|
|
||||||
public StanceInit() { }
|
|
||||||
public StanceInit(UnitStance init) { value = init; }
|
|
||||||
public UnitStance Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
},
|
},
|
||||||
(actor, value) =>
|
(actor, value) =>
|
||||||
{
|
{
|
||||||
actor.ReplaceInit(new FreeActorInit(value));
|
actor.ReplaceInit(new FreeActorInit(this, value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,20 +87,15 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FreeActorInit : IActorInit<bool>
|
public class FreeActorInit : ValueActorInit<bool>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public FreeActorInit(TraitInfo info, bool value)
|
||||||
public readonly bool ActorValue = true;
|
: base(info, value) { }
|
||||||
public FreeActorInit() { }
|
|
||||||
public FreeActorInit(bool init) { ActorValue = init; }
|
|
||||||
public bool Value { get { return ActorValue; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ParentActorInit : IActorInit
|
public class ParentActorInit : ValueActorInit<ActorInitActorReference>
|
||||||
{
|
{
|
||||||
readonly Actor value;
|
public ParentActorInit(Actor value)
|
||||||
public ParentActorInit(Actor init) { value = init; }
|
: base(value) { }
|
||||||
|
|
||||||
public Lazy<Actor> Value(World world) { return new Lazy<Actor>(() => value); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public LegacyBridgeHut(ActorInitializer init, LegacyBridgeHutInfo info)
|
public LegacyBridgeHut(ActorInitializer init, LegacyBridgeHutInfo info)
|
||||||
{
|
{
|
||||||
var bridge = init.GetOrDefault<ParentActorInit>(info);
|
var bridge = init.Get<ParentActorInit>(info).Value;
|
||||||
init.World.AddFrameEndTask(_ =>
|
init.World.AddFrameEndTask(_ =>
|
||||||
{
|
{
|
||||||
Bridge = bridge.Value(init.World).Value.Trait<Bridge>();
|
Bridge = bridge.Actor(init.World).Value.Trait<Bridge>();
|
||||||
Bridge.AddHut(this);
|
Bridge.AddHut(this);
|
||||||
FirstBridge = Bridge.Enumerate(0, true).Last();
|
FirstBridge = Bridge.Enumerate(0, true).Last();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,33 +16,29 @@ using OpenRA.Traits;
|
|||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
public enum LineBuildDirection { Unset, X, Y }
|
public enum LineBuildDirection { Unset, X, Y }
|
||||||
public class LineBuildDirectionInit : IActorInit<LineBuildDirection>
|
public class LineBuildDirectionInit : ValueActorInit<LineBuildDirection>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public LineBuildDirectionInit(LineBuildDirection value)
|
||||||
readonly LineBuildDirection value = LineBuildDirection.Unset;
|
: base(value) { }
|
||||||
|
|
||||||
public LineBuildDirectionInit() { }
|
|
||||||
public LineBuildDirectionInit(LineBuildDirection init) { value = init; }
|
|
||||||
public LineBuildDirection Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LineBuildParentInit : IActorInit<string[]>
|
public class LineBuildParentInit : ValueActorInit<string[]>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
|
||||||
public readonly string[] ParentNames = new string[0];
|
|
||||||
|
|
||||||
readonly Actor[] parents = null;
|
readonly Actor[] parents = null;
|
||||||
|
|
||||||
public LineBuildParentInit() { }
|
public LineBuildParentInit(Actor[] value)
|
||||||
public LineBuildParentInit(Actor[] init) { parents = init; }
|
: base(new string[0])
|
||||||
public string[] Value { get { return ParentNames; } }
|
{
|
||||||
|
parents = value;
|
||||||
|
}
|
||||||
|
|
||||||
public Actor[] ActorValue(World world)
|
public Actor[] ActorValue(World world)
|
||||||
{
|
{
|
||||||
if (parents != null)
|
if (parents != null)
|
||||||
return parents;
|
return parents;
|
||||||
|
|
||||||
var sma = world.WorldActor.Trait<SpawnMapActors>();
|
var sma = world.WorldActor.Trait<SpawnMapActors>();
|
||||||
return ParentNames.Select(n => sma.Actors[n]).ToArray();
|
return value.Select(n => sma.Actors[n]).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -479,25 +479,19 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init)
|
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init)
|
||||||
{
|
{
|
||||||
init.Add(new RuntimeCargoInit(Passengers.ToArray()));
|
init.Add(new RuntimeCargoInit(Info, Passengers.ToArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RuntimeCargoInit : IActorInit<Actor[]>, ISuppressInitExport
|
public class RuntimeCargoInit : ValueActorInit<Actor[]>, ISuppressInitExport
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public RuntimeCargoInit(TraitInfo info, Actor[] value)
|
||||||
readonly Actor[] value = { };
|
: base(info, value) { }
|
||||||
public RuntimeCargoInit() { }
|
|
||||||
public RuntimeCargoInit(Actor[] init) { value = init; }
|
|
||||||
public Actor[] Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CargoInit : IActorInit<string[]>
|
public class CargoInit : ValueActorInit<string[]>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public CargoInit(TraitInfo info, string[] value)
|
||||||
readonly string[] value = { };
|
: base(info, value) { }
|
||||||
public CargoInit() { }
|
|
||||||
public CargoInit(string[] init) { value = init; }
|
|
||||||
public string[] Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
},
|
},
|
||||||
(actor, value) =>
|
(actor, value) =>
|
||||||
{
|
{
|
||||||
actor.ReplaceInit(new DeployStateInit(value ? DeployState.Deployed : DeployState.Undeployed));
|
actor.ReplaceInit(new DeployStateInit(this, value ? DeployState.Deployed : DeployState.Undeployed));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,12 +337,12 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeployStateInit : IActorInit<DeployState>
|
public class DeployStateInit : ValueActorInit<DeployState>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public DeployStateInit(TraitInfo info, DeployState value)
|
||||||
readonly DeployState value = DeployState.Deployed;
|
: base(info, value) { }
|
||||||
public DeployStateInit() { }
|
|
||||||
public DeployStateInit(DeployState init) { value = init; }
|
public DeployStateInit(DeployState value)
|
||||||
public DeployState Value { get { return value; } }
|
: base(value) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,17 +141,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init)
|
void ITransformActorInitModifier.ModifyTransformActorInit(Actor self, TypeDictionary init)
|
||||||
{
|
{
|
||||||
init.Add(new ExperienceInit(experience));
|
init.Add(new ExperienceInit(info, experience));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExperienceInit : IActorInit<int>
|
class ExperienceInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ExperienceInit(TraitInfo info, int value)
|
||||||
readonly int value;
|
: base(info, value) { }
|
||||||
|
|
||||||
public ExperienceInit() { }
|
|
||||||
public ExperienceInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,23 +233,17 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HealthInit : IActorInit<int>
|
public class HealthInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
|
||||||
readonly int value = 100;
|
|
||||||
|
|
||||||
readonly bool allowZero;
|
readonly bool allowZero;
|
||||||
public HealthInit() { }
|
|
||||||
public HealthInit(int init)
|
|
||||||
: this(init, false) { }
|
|
||||||
|
|
||||||
public HealthInit(int init, bool allowZero)
|
public HealthInit(TraitInfo info, int value, bool allowZero = false)
|
||||||
{
|
: base(info, value) { this.allowZero = allowZero; }
|
||||||
this.allowZero = allowZero;
|
|
||||||
value = init;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Value
|
public HealthInit(int value, bool allowZero = false)
|
||||||
|
: base(value) { this.allowZero = allowZero; }
|
||||||
|
|
||||||
|
public override int Value
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -171,13 +171,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
Player IEffectiveOwner.Owner { get { return effectiveOwner; } }
|
Player IEffectiveOwner.Owner { get { return effectiveOwner; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HuskSpeedInit : IActorInit<int>
|
public class HuskSpeedInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public HuskSpeedInit(int value)
|
||||||
readonly int value = 0;
|
: base(value) { }
|
||||||
|
|
||||||
public HuskSpeedInit() { }
|
|
||||||
public HuskSpeedInit(int init) { value = init; }
|
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (turretInit != null)
|
if (turretInit != null)
|
||||||
{
|
{
|
||||||
var newTurretFacing = (turretInit.Value + newFacing - oldFacing + 255) % 255;
|
var newTurretFacing = (turretInit.Value + newFacing - oldFacing + 255) % 255;
|
||||||
actor.ReplaceInit(new TurretFacingInit(newTurretFacing));
|
actor.ReplaceInit(new TurretFacingInit(this, newTurretFacing));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turretsInit != null)
|
if (turretsInit != null)
|
||||||
|
|||||||
@@ -195,5 +195,5 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HiddenUnderFogInit : IActorInit { }
|
public class HiddenUnderFogInit : RuntimeFlagInit { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ using OpenRA.Traits;
|
|||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
// Allows third party mods to detect whether an actor was created by PlaceBuilding.
|
// Allows third party mods to detect whether an actor was created by PlaceBuilding.
|
||||||
public class PlaceBuildingInit : IActorInit { }
|
public class PlaceBuildingInit : RuntimeFlagInit { }
|
||||||
|
|
||||||
[Desc("Allows the player to execute build orders.", " Attach this to the player actor.")]
|
[Desc("Allows the player to execute build orders.", " Attach this to the player actor.")]
|
||||||
public class PlaceBuildingInfo : TraitInfo
|
public class PlaceBuildingInfo : TraitInfo
|
||||||
|
|||||||
@@ -120,12 +120,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlugsInit : IActorInit<Dictionary<CVec, string>>
|
public class PlugsInit : ValueActorInit<Dictionary<CVec, string>>
|
||||||
{
|
{
|
||||||
[DictionaryFromYamlKey]
|
public PlugsInit(Dictionary<CVec, string> value)
|
||||||
readonly Dictionary<CVec, string> value = new Dictionary<CVec, string>();
|
: base(value) { }
|
||||||
public PlugsInit() { }
|
|
||||||
public PlugsInit(Dictionary<CVec, string> init) { value = init; }
|
|
||||||
public Dictionary<CVec, string> Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,13 +110,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProductionSpawnLocationInit : IActorInit<CPos>
|
public class ProductionSpawnLocationInit : ValueActorInit<CPos>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ProductionSpawnLocationInit(TraitInfo info, CPos value)
|
||||||
readonly CPos value = CPos.Zero;
|
: base(info, value) { }
|
||||||
|
|
||||||
public ProductionSpawnLocationInit() { }
|
|
||||||
public ProductionSpawnLocationInit(CPos init) { value = init; }
|
|
||||||
public CPos Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,13 +168,9 @@ namespace OpenRA.Mods.Common.Traits.Render
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RuntimeNeighbourInit : IActorInit<Dictionary<CPos, string[]>>, ISuppressInitExport
|
public class RuntimeNeighbourInit : ValueActorInit<Dictionary<CPos, string[]>>, ISuppressInitExport
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public RuntimeNeighbourInit(Dictionary<CPos, string[]> value)
|
||||||
readonly Dictionary<CPos, string[]> value = null;
|
: base(value) { }
|
||||||
|
|
||||||
public RuntimeNeighbourInit() { }
|
|
||||||
public RuntimeNeighbourInit(Dictionary<CPos, string[]> init) { value = init; }
|
|
||||||
public Dictionary<CPos, string[]> Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,13 +49,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Allows mappers to 'tag' actors with arbitrary strings that may have meaning in their scripts.</summary>
|
/// <summary>Allows mappers to 'tag' actors with arbitrary strings that may have meaning in their scripts.</summary>
|
||||||
public class ScriptTagsInit : IActorInit<string[]>
|
public class ScriptTagsInit : ValueActorInit<string[]>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public ScriptTagsInit(string[] value)
|
||||||
readonly string[] value = new string[0];
|
: base(value) { }
|
||||||
|
|
||||||
public ScriptTagsInit() { }
|
|
||||||
public ScriptTagsInit(string[] init) { value = init; }
|
|
||||||
public string[] Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// HACK: The ActorInit system does not support multiple instances of the same type
|
// HACK: The ActorInit system does not support multiple instances of the same type
|
||||||
// Make sure that we only return one TurretFacingInit, even for actors with multiple turrets
|
// Make sure that we only return one TurretFacingInit, even for actors with multiple turrets
|
||||||
if (ai.TraitInfos<TurretedInfo>().FirstOrDefault() == this)
|
if (ai.TraitInfos<TurretedInfo>().FirstOrDefault() == this)
|
||||||
yield return new TurretFacingInit(PreviewFacing);
|
yield return new TurretFacingInit(this, PreviewFacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<EditorActorOption> IEditorActorOptions.ActorOptions(ActorInfo ai, World world)
|
IEnumerable<EditorActorOption> IEditorActorOptions.ActorOptions(ActorInfo ai, World world)
|
||||||
@@ -66,6 +66,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
(actor, value) =>
|
(actor, value) =>
|
||||||
{
|
{
|
||||||
actor.RemoveInit<TurretFacingsInit>();
|
actor.RemoveInit<TurretFacingsInit>();
|
||||||
|
|
||||||
|
// Force a single global turret facing for multi-turret actors by not passing this TraitInfo instance
|
||||||
actor.ReplaceInit(new TurretFacingInit((int)value));
|
actor.ReplaceInit(new TurretFacingInit((int)value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -230,7 +232,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var facings = init.GetOrDefault<TurretFacingsInit>();
|
var facings = init.GetOrDefault<TurretFacingsInit>();
|
||||||
if (facings == null)
|
if (facings == null)
|
||||||
{
|
{
|
||||||
facings = new TurretFacingsInit();
|
facings = new TurretFacingsInit(new Dictionary<string, int>());
|
||||||
init.Add(facings);
|
init.Add(facings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +245,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var facings = inits.GetOrDefault<DynamicTurretFacingsInit>();
|
var facings = inits.GetOrDefault<DynamicTurretFacingsInit>();
|
||||||
if (facings == null)
|
if (facings == null)
|
||||||
{
|
{
|
||||||
facings = new DynamicTurretFacingsInit();
|
facings = new DynamicTurretFacingsInit(Info, new Dictionary<string, Func<int>>());
|
||||||
inits.Add(facings);
|
inits.Add(facings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,31 +269,24 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TurretFacingInit : IActorInit<int>
|
public class TurretFacingInit : ValueActorInit<int>
|
||||||
{
|
{
|
||||||
[FieldFromYamlKey]
|
public TurretFacingInit(TraitInfo info, int value)
|
||||||
readonly int value = 128;
|
: base(info, value) { }
|
||||||
|
|
||||||
public TurretFacingInit() { }
|
public TurretFacingInit(int value)
|
||||||
public TurretFacingInit(int init) { value = init; }
|
: base(value) { }
|
||||||
public int Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TurretFacingsInit : IActorInit<Dictionary<string, int>>
|
public class TurretFacingsInit : ValueActorInit<Dictionary<string, int>>
|
||||||
{
|
{
|
||||||
[DictionaryFromYamlKey]
|
public TurretFacingsInit(Dictionary<string, int> value)
|
||||||
readonly Dictionary<string, int> value = new Dictionary<string, int>();
|
: base(value) { }
|
||||||
|
|
||||||
public TurretFacingsInit() { }
|
|
||||||
public TurretFacingsInit(Dictionary<string, int> init) { value = init; }
|
|
||||||
public Dictionary<string, int> Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DynamicTurretFacingsInit : IActorInit<Dictionary<string, Func<int>>>
|
public class DynamicTurretFacingsInit : ValueActorInit<Dictionary<string, Func<int>>>
|
||||||
{
|
{
|
||||||
readonly Dictionary<string, Func<int>> value = new Dictionary<string, Func<int>>();
|
public DynamicTurretFacingsInit(TraitInfo info, Dictionary<string, Func<int>> value)
|
||||||
public DynamicTurretFacingsInit() { }
|
: base(info, value) { }
|
||||||
public DynamicTurretFacingsInit(Dictionary<string, Func<int>> init) { value = init; }
|
|
||||||
public Dictionary<string, Func<int>> Value { get { return value; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,12 +62,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SkipMakeAnimsInit : IActorInit, ISuppressInitExport { }
|
public class SkipMakeAnimsInit : RuntimeFlagInit { }
|
||||||
public class SpawnedByMapInit : IActorInit<string>, ISuppressInitExport
|
public class SpawnedByMapInit : ValueActorInit<string>, ISuppressInitExport
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public SpawnedByMapInit(string value)
|
||||||
public SpawnedByMapInit(string name) { Name = name; }
|
: base(value) { }
|
||||||
|
|
||||||
public string Value { get { return Name; } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ using OpenRA.Graphics;
|
|||||||
using OpenRA.Mods.Common.FileFormats;
|
using OpenRA.Mods.Common.FileFormats;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.UtilityCommands
|
namespace OpenRA.Mods.Common.UtilityCommands
|
||||||
{
|
{
|
||||||
@@ -416,7 +417,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
|||||||
initDict.Add(new FacingInit(255 - facing));
|
initDict.Add(new FacingInit(255 - facing));
|
||||||
|
|
||||||
if (section == "INFANTRY")
|
if (section == "INFANTRY")
|
||||||
actor.Add(new SubCellInit(Exts.ParseByte(parts[4])));
|
actor.Add(new SubCellInit((SubCell)Exts.ParseByte(parts[4])));
|
||||||
|
|
||||||
var actorCount = map.ActorDefinitions.Count;
|
var actorCount = map.ActorDefinitions.Count;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user