Merge pull request #8703 from atlimit8/RequireInMiniYaml
Require trait properties in MiniYaml
This commit is contained in:
@@ -24,6 +24,26 @@ namespace OpenRA
|
||||
{
|
||||
public static class FieldLoader
|
||||
{
|
||||
public class MissingFieldsException : YamlException
|
||||
{
|
||||
public readonly string[] Missing;
|
||||
public readonly string Header;
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string.IsNullOrEmpty(Header) ? "" : Header + ": ") + Missing[0]
|
||||
+ string.Concat(Missing.Skip(1).Select(m => ", " + m));
|
||||
}
|
||||
}
|
||||
|
||||
public MissingFieldsException(string[] missing, string header = null, string headerSingle = null) : base(null)
|
||||
{
|
||||
Header = missing.Length > 1 ? header : headerSingle ?? header;
|
||||
Missing = missing;
|
||||
}
|
||||
}
|
||||
|
||||
public static Func<string, Type, string, object> InvalidValueAction = (s, t, f) =>
|
||||
{
|
||||
throw new InvalidOperationException("FieldLoader: Cannot parse `{0}` into `{1}.{2}` ".F(s, f, t));
|
||||
@@ -45,6 +65,7 @@ namespace OpenRA
|
||||
public static void Load(object self, MiniYaml my)
|
||||
{
|
||||
var loadInfo = TypeLoadInfo[self.GetType()];
|
||||
var missing = new List<string>();
|
||||
|
||||
Dictionary<string, MiniYaml> md = null;
|
||||
|
||||
@@ -52,19 +73,33 @@ namespace OpenRA
|
||||
{
|
||||
object val;
|
||||
|
||||
if (md == null)
|
||||
md = my.ToDictionary();
|
||||
if (fli.Loader != null)
|
||||
val = fli.Loader(my);
|
||||
{
|
||||
if (!fli.Attribute.Required || md.ContainsKey(fli.YamlName))
|
||||
val = fli.Loader(my);
|
||||
else
|
||||
{
|
||||
missing.Add(fli.YamlName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (md == null)
|
||||
md = my.ToDictionary();
|
||||
|
||||
if (!TryGetValueFromYaml(fli.YamlName, fli.Field, md, out val))
|
||||
{
|
||||
if (fli.Attribute.Required)
|
||||
missing.Add(fli.YamlName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fli.Field.SetValue(self, val);
|
||||
}
|
||||
|
||||
if (missing.Any())
|
||||
throw new MissingFieldsException(missing.ToArray());
|
||||
}
|
||||
|
||||
static bool TryGetValueFromYaml(string yamlName, FieldInfo field, Dictionary<string, MiniYaml> md, out object ret)
|
||||
@@ -557,12 +592,20 @@ namespace OpenRA
|
||||
: base(false) { }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public sealed class RequireAttribute : SerializeAttribute
|
||||
{
|
||||
public RequireAttribute()
|
||||
: base(true, true) { }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public sealed class LoadUsingAttribute : SerializeAttribute
|
||||
{
|
||||
public LoadUsingAttribute(string loader)
|
||||
public LoadUsingAttribute(string loader, bool required = false)
|
||||
{
|
||||
Loader = loader;
|
||||
Required = required;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,10 +620,12 @@ namespace OpenRA
|
||||
public string YamlName;
|
||||
public string Loader;
|
||||
public bool FromYamlKey;
|
||||
public bool Required;
|
||||
|
||||
public SerializeAttribute(bool serialize = true)
|
||||
public SerializeAttribute(bool serialize = true, bool required = false)
|
||||
{
|
||||
Serialize = serialize;
|
||||
Required = required;
|
||||
}
|
||||
|
||||
internal Func<MiniYaml, object> GetLoader(Type type)
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace OpenRA
|
||||
try
|
||||
{
|
||||
var allParents = new HashSet<string>();
|
||||
var abstractActorType = name.StartsWith("^");
|
||||
|
||||
// Guard against circular inheritance
|
||||
allParents.Add(name);
|
||||
@@ -49,7 +50,15 @@ namespace OpenRA
|
||||
throw new YamlException("Bogus trait removal: " + t.Key);
|
||||
|
||||
if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
|
||||
Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
|
||||
try
|
||||
{
|
||||
Traits.Add(LoadTraitInfo(t.Key.Split('@')[0], t.Value));
|
||||
}
|
||||
catch (FieldLoader.MissingFieldsException e)
|
||||
{
|
||||
if (!abstractActorType)
|
||||
throw new YamlException(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (YamlException e)
|
||||
@@ -94,7 +103,16 @@ namespace OpenRA
|
||||
throw new YamlException("Junk value `{0}` on trait node {1}"
|
||||
.F(my.Value, traitName));
|
||||
var info = Game.CreateObject<ITraitInfo>(traitName + "Info");
|
||||
FieldLoader.Load(info, my);
|
||||
try
|
||||
{
|
||||
FieldLoader.Load(info, my);
|
||||
}
|
||||
catch (FieldLoader.MissingFieldsException e)
|
||||
{
|
||||
var header = "Trait name " + traitName + ": " + (e.Missing.Length > 1 ? "Required properties missing" : "Required property missing");
|
||||
throw new FieldLoader.MissingFieldsException(e.Missing, header);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public readonly string Name = "primary";
|
||||
|
||||
[WeaponReference]
|
||||
[Desc("Has to be defined here and in weapons.yaml.")]
|
||||
[WeaponReference, FieldLoader.Require]
|
||||
[Desc("Has to be defined in weapons.yaml as well.")]
|
||||
public readonly string Weapon = null;
|
||||
|
||||
[Desc("Which limited ammo pool (if present) should this armament be assigned to.")]
|
||||
|
||||
@@ -27,14 +27,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Cargo can fire their weapons out of fire ports.")]
|
||||
public class AttackGarrisonedInfo : AttackFollowInfo, Requires<CargoInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Fire port offsets in local coordinates.")]
|
||||
public readonly WVec[] PortOffsets = { };
|
||||
public readonly WVec[] PortOffsets = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("Fire port yaw angles.")]
|
||||
public readonly WAngle[] PortYaws = { };
|
||||
public readonly WAngle[] PortYaws = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("Fire port yaw cone angle.")]
|
||||
public readonly WAngle[] PortCones = { };
|
||||
public readonly WAngle[] PortCones = null;
|
||||
|
||||
public readonly string MuzzlePalette = "effect";
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"If you want more than one unit to appear copy this section and assign IDs like FreeActor@2, ...")]
|
||||
public class FreeActorInfo : ITraitInfo
|
||||
{
|
||||
[ActorReference]
|
||||
[ActorReference, FieldLoader.Require]
|
||||
[Desc("Name of the actor.")]
|
||||
public readonly string Actor = null;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class TargetableBuildingInfo : ITraitInfo, ITargetableInfo, Requires<BuildingInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly string[] TargetTypes = { };
|
||||
public string[] GetTargetTypes() { return TargetTypes; }
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
class ExplodeCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
[Desc("The weapon to fire upon collection.")]
|
||||
[WeaponReference] public string Weapon = null;
|
||||
[WeaponReference, FieldLoader.Require] public string Weapon = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ExplodeCrateAction(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
class GiveUnitCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
[Desc("The list of units to spawn.")]
|
||||
[ActorReference]
|
||||
[ActorReference, FieldLoader.Require]
|
||||
public readonly string[] Units = { };
|
||||
|
||||
[Desc("Races that are allowed to trigger this action")]
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Grants an upgrade to the collector.")]
|
||||
public class GrantUpgradeCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
[UpgradeGrantedReference]
|
||||
[UpgradeGrantedReference, FieldLoader.Require]
|
||||
[Desc("The upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
class SupportPowerCrateActionInfo : CrateActionInfo
|
||||
{
|
||||
[Desc("Which proxy actor, which grants the support power, to spawn.")]
|
||||
[ActorReference] public readonly string Proxy = null;
|
||||
[ActorReference, FieldLoader.Require] public readonly string Proxy = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new SupportPowerCrateAction(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Overrides the build time calculated by actor value.")]
|
||||
public class CustomBuildTimeValueInfo : TraitInfo<CustomBuildTimeValue>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Measured in ticks.")]
|
||||
public readonly int Value = 0;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"Examples: bridge huts and crates.")]
|
||||
public class CustomSelectionSizeInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly int[] CustomBounds = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new CustomSelectionSize(this); }
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Allow a non-standard sell/repair value to avoid buy-sell exploits.")]
|
||||
public class CustomSellValueInfo : TraitInfo<CustomSellValue>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly int Value = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("This actor's experience increases when it has killed a GivesExperience actor.")]
|
||||
public class GainsExperienceInfo : ITraitInfo, Requires<ValuedInfo>, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
[FieldLoader.LoadUsing("LoadUpgrades")]
|
||||
[Desc("Upgrades to grant at each level. (Required property)",
|
||||
[FieldLoader.LoadUsing("LoadUpgrades", true)]
|
||||
[Desc("Upgrades to grant at each level.",
|
||||
"Key is the XP requirements for each level as a percentage of our own value.",
|
||||
"Value is a list of the upgrade types to grant")]
|
||||
public readonly Dictionary<int, string[]> Upgrades = null;
|
||||
@@ -36,10 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
static object LoadUpgrades(MiniYaml y)
|
||||
{
|
||||
MiniYaml upgrades;
|
||||
|
||||
if (!y.ToDictionary().TryGetValue("Upgrades", out upgrades))
|
||||
throw new YamlException("GainsExperience is missing Upgrades.");
|
||||
MiniYaml upgrades = y.ToDictionary()["Upgrades"];
|
||||
|
||||
return upgrades.Nodes.ToDictionary(
|
||||
kv => FieldLoader.GetValue<int>("(key)", kv.Key),
|
||||
|
||||
@@ -16,10 +16,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Grants upgrades to the actor this is attached to when prerequisites are available.")]
|
||||
public class GlobalUpgradableInfo : ITraitInfo, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
[UpgradeGrantedReference]
|
||||
[UpgradeGrantedReference, FieldLoader.Require]
|
||||
[Desc("List of upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("List of required prerequisites.")]
|
||||
public readonly string[] Prerequisites = { };
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Prone movement speed as a percentage of the normal speed.")]
|
||||
public readonly int SpeedModifier = 50;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("Damage types that trigger prone state. Defined on the warheads.")]
|
||||
public readonly string[] DamageTriggers = new string[0];
|
||||
public readonly string[] DamageTriggers = null;
|
||||
|
||||
[FieldLoader.LoadUsing("LoadModifiers")]
|
||||
[Desc("Damage modifiers for each damage type (defined on the warheads) while the unit is prone.")]
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class TerrainModifiesDamageInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.LoadUsing("LoadPercents")]
|
||||
[FieldLoader.LoadUsing("LoadPercents", true)]
|
||||
[Desc("Damage percentage for specific terrain types. 120 = 120%, 80 = 80%, etc.")]
|
||||
public readonly Dictionary<string, int> TerrainModifier = null;
|
||||
|
||||
@@ -28,12 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
static object LoadPercents(MiniYaml y)
|
||||
{
|
||||
MiniYaml percents;
|
||||
|
||||
if (!y.ToDictionary().TryGetValue("TerrainModifier", out percents))
|
||||
return new Dictionary<string, int>();
|
||||
|
||||
return percents.Nodes.ToDictionary(
|
||||
return y.ToDictionary()["TerrainModifier"].Nodes.ToDictionary(
|
||||
kv => FieldLoader.GetValue<string>("(key)", kv.Key),
|
||||
kv => FieldLoader.GetValue<int>("(value)", kv.Value.Value));
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Unit is able to move.")]
|
||||
public class MobileInfo : IMoveInfo, IOccupySpaceInfo, IFacingInfo, UsesInit<FacingInit>, UsesInit<LocationInit>, UsesInit<SubCellInit>
|
||||
{
|
||||
[FieldLoader.LoadUsing("LoadSpeeds")]
|
||||
[FieldLoader.LoadUsing("LoadSpeeds", true)]
|
||||
[Desc("Set Water: 0 for ground units and lower the value on rough terrain.")]
|
||||
public readonly Dictionary<string, TerrainInfo> TerrainSpeeds;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"at the same time. Will only work together with the Production: trait.")]
|
||||
public class ProductionQueueInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("What kind of production will be added (e.g. Building, Infantry, Vehicle, ...)")]
|
||||
public readonly string Type = null;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class PlugInfo : TraitInfo<Plug>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Plug type (matched against Upgrades in Pluggable)")]
|
||||
public readonly string Type = null;
|
||||
}
|
||||
|
||||
@@ -19,18 +19,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Footprint cell offset where a plug can be placed.")]
|
||||
public readonly CVec Offset = CVec.Zero;
|
||||
|
||||
[FieldLoader.LoadUsing("LoadUpgrades")]
|
||||
[FieldLoader.LoadUsing("LoadUpgrades", true)]
|
||||
[Desc("Upgrades to grant for each accepted plug type.")]
|
||||
public readonly Dictionary<string, string[]> Upgrades = null;
|
||||
|
||||
static object LoadUpgrades(MiniYaml y)
|
||||
{
|
||||
MiniYaml upgrades;
|
||||
|
||||
if (!y.ToDictionary().TryGetValue("Upgrades", out upgrades))
|
||||
return new Dictionary<string, string[]>();
|
||||
|
||||
return upgrades.Nodes.ToDictionary(
|
||||
return y.ToDictionary()["Upgrades"].Nodes.ToDictionary(
|
||||
kv => kv.Key,
|
||||
kv => FieldLoader.GetValue<string[]>("(value)", kv.Value.Value));
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("This unit has access to build queues.")]
|
||||
public class ProductionInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("e.g. Infantry, Vehicles, Aircraft, Buildings")]
|
||||
public readonly string[] Produces = { };
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Actor can capture ProximityCapturable actors.")]
|
||||
public class ProximityCaptorInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly string[] Types = { };
|
||||
public object Create(ActorInitializer init) { return new ProximityCaptor(this); }
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Visualizes the remaining time for an upgrade.")]
|
||||
class TimedUpgradeBarInfo : ITraitInfo, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Upgrade that this bar corresponds to")]
|
||||
public readonly string Upgrade = null;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Plays a looping audio file at the actor position. Attach this to the `World` actor to cover the whole map.")]
|
||||
class AmbientSoundInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly string SoundFile = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new AmbientSound(init.Self, this); }
|
||||
|
||||
@@ -18,9 +18,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Used for silos.")]
|
||||
class StoresResourcesInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Number of little squares used to display how filled unit is.")]
|
||||
public readonly int PipCount = 0;
|
||||
public readonly PipType PipColor = PipType.Yellow;
|
||||
[FieldLoader.Require]
|
||||
public readonly int Capacity = 0;
|
||||
public object Create(ActorInitializer init) { return new StoresResources(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
class GrantUpgradePowerInfo : SupportPowerInfo
|
||||
{
|
||||
[UpgradeGrantedReference]
|
||||
[UpgradeGrantedReference, FieldLoader.Require]
|
||||
[Desc("The upgrades to apply.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
|
||||
@@ -12,12 +12,14 @@ using OpenRA.Effects;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Effects;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Spawns an actor that stays for a limited amount of time.")]
|
||||
public class SpawnActorPowerInfo : SupportPowerInfo
|
||||
{
|
||||
[ActorReference, FieldLoader.Require]
|
||||
[Desc("Actor to spawn.")]
|
||||
public readonly string Actor = null;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
class ThrowsParticleInfo : ITraitInfo, Requires<WithSpriteBodyInfo>, Requires<IBodyOrientationInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
public readonly string Anim = null;
|
||||
|
||||
[Desc("Initial position relative to body")]
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Throws particles when the actor is destroyed that do damage on impact.")]
|
||||
public class ThrowsShrapnelInfo : ITraitInfo
|
||||
{
|
||||
[WeaponReference]
|
||||
[WeaponReference, FieldLoader.Require]
|
||||
public string[] Weapons = { };
|
||||
public int[] Pieces = { 3, 10 };
|
||||
public WDist[] Range = { WDist.FromCells(2), WDist.FromCells(5) };
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class TransformOnPassengerInfo : ITraitInfo
|
||||
{
|
||||
[ActorReference] public readonly string[] PassengerTypes = { };
|
||||
[ActorReference, FieldLoader.Require] public readonly string[] PassengerTypes = { };
|
||||
[ActorReference] public readonly string OnEnter = null;
|
||||
[ActorReference] public readonly string OnExit = null;
|
||||
public readonly bool SkipMakeAnims = false;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Actor becomes a specified actor type when this trait is triggered.")]
|
||||
public class TransformsInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Actor to transform into."), ActorReference]
|
||||
[Desc("Actor to transform into."), ActorReference, FieldLoader.Require]
|
||||
public readonly string IntoActor = null;
|
||||
|
||||
[Desc("Offset to spawn the transformed actor relative to the current cell.")]
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class DeployToUpgradeInfo : ITraitInfo, Requires<UpgradeManagerInfo>
|
||||
{
|
||||
[UpgradeGrantedReference]
|
||||
[UpgradeGrantedReference, FieldLoader.Require]
|
||||
[Desc("The upgrades to grant when deploying and revoke when undeploying.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Applies an upgrade to actors within a specified range.")]
|
||||
public class UpgradeActorsNearInfo : ITraitInfo
|
||||
{
|
||||
[UpgradeGrantedReference]
|
||||
[UpgradeGrantedReference, FieldLoader.Require]
|
||||
[Desc("The upgrades to grant.")]
|
||||
public readonly string[] Upgrades = { };
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("How much the unit is worth.")]
|
||||
public class ValuedInfo : TraitInfo<Valued>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Used in production, but also for bounties so remember to set it > 0 even for NPCs.")]
|
||||
public readonly int Cost = 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The icon change occurs when LevelupWhenCreated.Prerequisites are met.")]
|
||||
public class VeteranProductionIconOverlayInfo : ITraitInfo, Requires<TechTreeInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Image used for the overlay.")]
|
||||
public readonly string Image = null;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("This actor has a voice.")]
|
||||
public class VoicedInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Which voice set to use.")]
|
||||
[VoiceSetReference] public readonly string VoiceSet = null;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Loads the palette specified in the tileset definition")]
|
||||
class PaletteFromCurrentTilesetInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[Desc("Map listed indices to shadow. Ignores previous color.")]
|
||||
|
||||
@@ -17,10 +17,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
class PaletteFromFileInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[Desc("If defined, load the palette only for this tileset.")]
|
||||
public readonly string Tileset = null;
|
||||
[FieldLoader.Require]
|
||||
[Desc("filename to load")]
|
||||
public readonly string Filename = null;
|
||||
[Desc("Map listed indices to shadow. Ignores previous color.")]
|
||||
|
||||
@@ -19,9 +19,11 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
[Desc("Create a palette by applying alpha transparency to another palette.")]
|
||||
class PaletteFromPaletteWithAlphaInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Internal palette name")]
|
||||
public readonly string Name = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("The name of the palette to base off.")]
|
||||
public readonly string BasePalette = null;
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
[Desc("Create player palettes by applying alpha transparency to another player palette.")]
|
||||
class PaletteFromPlayerPaletteWithAlphaInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("The prefix for the resulting player palettes")]
|
||||
public readonly string BaseName = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("The name of the player palette to base off.")]
|
||||
public readonly string BasePalette = null;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Creates a single color palette without any base palette file.")]
|
||||
class PaletteFromRGBAInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[Desc("If defined, load the palette only for this tileset.")]
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
class PlayerPaletteFromCurrentTilesetInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[Desc("Map listed indices to shadow.")]
|
||||
|
||||
@@ -86,7 +86,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
{
|
||||
var fieldDescLines = info.Field.GetCustomAttributes<DescAttribute>(true).SelectMany(d => d.Lines);
|
||||
var fieldType = FriendlyTypeName(info.Field.FieldType);
|
||||
var defaultValue = FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value;
|
||||
var loadInfo = info.Field.GetCustomAttributes<FieldLoader.SerializeAttribute>(true).FirstOrDefault();
|
||||
var defaultValue = loadInfo != null && loadInfo.Required ? "<em>(required)</em>" : FieldSaver.SaveField(liveTraitInfo, info.Field.Name).Value.Value;
|
||||
doc.Append("<tr><td>{0}</td><td>{1}</td><td>{2}</td>".F(info.YamlName, defaultValue, fieldType));
|
||||
doc.Append("<td>");
|
||||
foreach (var line in fieldDescLines)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
"If you want more than one unit to be delivered, copy this section and assign IDs like FreeActorWithDelivery@2, ...")]
|
||||
public class FreeActorWithDeliveryInfo : FreeActorInfo
|
||||
{
|
||||
[ActorReference]
|
||||
[ActorReference, FieldLoader.Require]
|
||||
[Desc("Name of the delivering actor. This actor must have the `Carryall` trait")]
|
||||
public readonly string DeliveringActor = null;
|
||||
|
||||
@@ -43,11 +43,6 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
|
||||
public FreeActorWithDelivery(ActorInitializer init, FreeActorWithDeliveryInfo info)
|
||||
{
|
||||
if (string.IsNullOrEmpty(info.Actor))
|
||||
throw new InvalidDataException("Actor type was not specified!");
|
||||
if (string.IsNullOrEmpty(info.DeliveringActor))
|
||||
throw new InvalidDataException("Delivering actor type was not specified!");
|
||||
|
||||
self = init.Self;
|
||||
Info = info;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
"the actor footprint will be filled with this tile.")]
|
||||
public readonly ushort Template = 0;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("The terrain types that this template will be placed on")]
|
||||
public readonly string[] TerrainTypes = { };
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
[Desc("Rendered together with an attack.")]
|
||||
public class WithAttackOverlayInfo : ITraitInfo, Requires<RenderSpritesInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Sequence name to use")]
|
||||
[SequenceReference] public readonly string Sequence = null;
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
{
|
||||
class FogPaletteFromR8Info : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[FieldLoader.Require]
|
||||
[Desc("Filename to load")]
|
||||
public readonly string Filename = null;
|
||||
[Desc("Palette byte offset")]
|
||||
|
||||
@@ -19,8 +19,10 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
{
|
||||
class PaletteFromR8Info : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Internal palette name")]
|
||||
public readonly string Name = null;
|
||||
[FieldLoader.Require]
|
||||
[Desc("Filename to load")]
|
||||
public readonly string Filename = null;
|
||||
[Desc("Palette byte offset")]
|
||||
|
||||
@@ -19,9 +19,11 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
[Desc("Create a palette by applying a scale and offset to the colors in another palette.")]
|
||||
class PaletteFromScaledPaletteInfo : ITraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Internal palette name")]
|
||||
public readonly string Name = null;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[Desc("The name of the palette to base off.")]
|
||||
public readonly string BasePalette = null;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
[Desc("Creates a free duplicate of produced units.")]
|
||||
public class ClonesProducedUnitsInfo : ITraitInfo, Requires<ProductionInfo>, Requires<ExitInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("Uses the \"Cloneable\" trait to determine whether or not we should clone a produced unit.")]
|
||||
public readonly string[] CloneableTypes = { };
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
[Desc("Actors with the \"ClonesProducedUnits\" trait will produce a free duplicate of me.")]
|
||||
public class CloneableInfo : TraitInfo<Cloneable>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[Desc("This unit's cloneable type is:")]
|
||||
public readonly string[] Types = { };
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
{
|
||||
class InfiltrateForSupportPowerInfo : ITraitInfo
|
||||
{
|
||||
[ActorReference] public readonly string Proxy = null;
|
||||
[ActorReference, FieldLoader.Require] public readonly string Proxy = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new InfiltrateForSupportPower(this); }
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Traits
|
||||
[Desc("Spawn another actor immediately upon death.")]
|
||||
public class LeavesHuskInfo : ITraitInfo
|
||||
{
|
||||
[ActorReference]
|
||||
[ActorReference, FieldLoader.Require]
|
||||
public readonly string HuskActor = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new LeavesHusk(init, this); }
|
||||
|
||||
Reference in New Issue
Block a user