Add a lint check for trait placement on hardcoded actor names.
This commit is contained in:
committed by
reaperrr
parent
0d3c624bbc
commit
5a0bcc01a6
@@ -24,6 +24,15 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
[Flags]
|
||||
public enum SystemActors
|
||||
{
|
||||
Player = 0,
|
||||
EditorPlayer = 1,
|
||||
World = 2,
|
||||
EditorWorld = 4
|
||||
}
|
||||
|
||||
public sealed class Actor : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding, IEquatable<Actor>, IDisposable
|
||||
{
|
||||
internal readonly struct SyncHash
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA
|
||||
{
|
||||
public class Ruleset
|
||||
{
|
||||
public readonly IReadOnlyDictionary<string, ActorInfo> Actors;
|
||||
public readonly ActorInfoDictionary Actors;
|
||||
public readonly IReadOnlyDictionary<string, WeaponInfo> Weapons;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Voices;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Notifications;
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA
|
||||
SequenceProvider sequences,
|
||||
IReadOnlyDictionary<string, MiniYamlNode> modelSequences)
|
||||
{
|
||||
Actors = actors;
|
||||
Actors = new ActorInfoDictionary(actors);
|
||||
Weapons = weapons;
|
||||
Voices = voices;
|
||||
Notifications = notifications;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
// Overwrite previous definitions if there are duplicates
|
||||
var pals = new Dictionary<string, IProvidesCursorPaletteInfo>();
|
||||
foreach (var p in modData.DefaultRules.Actors["world"].TraitInfos<IProvidesCursorPaletteInfo>())
|
||||
foreach (var p in modData.DefaultRules.Actors[SystemActors.World].TraitInfos<IProvidesCursorPaletteInfo>())
|
||||
if (p.Palette != null)
|
||||
pals[p.Palette] = p;
|
||||
|
||||
|
||||
@@ -708,7 +708,7 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
// ResourceLayer is on world actor, which isn't caught above, so an extra check for it.
|
||||
var worldActorInfo = Rules.Actors["world"];
|
||||
var worldActorInfo = Rules.Actors[SystemActors.World];
|
||||
var worldimpsis = worldActorInfo.TraitInfos<IMapPreviewSignatureInfo>();
|
||||
foreach (var worldimpsi in worldimpsis)
|
||||
worldimpsi.PopulateMapPreviewSignatureCells(this, worldActorInfo, null, positions);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA
|
||||
|
||||
public MapPlayers(Ruleset rules, int playerCount)
|
||||
{
|
||||
var firstFaction = rules.Actors["world"].TraitInfos<FactionInfo>()
|
||||
var firstFaction = rules.Actors[SystemActors.World].TraitInfos<FactionInfo>()
|
||||
.First(f => f.Selectable).InternalName;
|
||||
|
||||
Players = new Dictionary<string, PlayerReference>
|
||||
|
||||
@@ -37,9 +37,6 @@ namespace OpenRA
|
||||
|
||||
public class Player : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding
|
||||
{
|
||||
public const string PlayerActorType = "Player";
|
||||
public const string EditorPlayerActorType = "EditorPlayer";
|
||||
|
||||
struct StanceColors
|
||||
{
|
||||
public Color Self;
|
||||
@@ -129,13 +126,13 @@ namespace OpenRA
|
||||
|
||||
static FactionInfo ResolveFaction(World world, string factionName, MersenneTwister playerRandom, bool requireSelectable)
|
||||
{
|
||||
var factionInfos = world.Map.Rules.Actors["world"].TraitInfos<FactionInfo>();
|
||||
var factionInfos = world.Map.Rules.Actors[SystemActors.World].TraitInfos<FactionInfo>();
|
||||
return ResolveFaction(factionName, factionInfos, playerRandom, requireSelectable);
|
||||
}
|
||||
|
||||
static FactionInfo ResolveDisplayFaction(World world, string factionName)
|
||||
{
|
||||
var factions = world.Map.Rules.Actors["world"].TraitInfos<FactionInfo>().ToArray();
|
||||
var factions = world.Map.Rules.Actors[SystemActors.World].TraitInfos<FactionInfo>().ToArray();
|
||||
|
||||
return factions.FirstOrDefault(f => f.InternalName == factionName) ?? factions.First();
|
||||
}
|
||||
@@ -165,7 +162,7 @@ namespace OpenRA
|
||||
{
|
||||
ClientIndex = client.Index;
|
||||
Color = client.Color;
|
||||
PlayerName = ResolvePlayerName(client, world.LobbyInfo.Clients, world.Map.Rules.Actors["player"].TraitInfos<IBotInfo>());
|
||||
PlayerName = ResolvePlayerName(client, world.LobbyInfo.Clients, world.Map.Rules.Actors[SystemActors.Player].TraitInfos<IBotInfo>());
|
||||
|
||||
BotType = client.Bot;
|
||||
Faction = ResolveFaction(world, client.Faction, playerRandom, !pr.LockFaction);
|
||||
@@ -206,8 +203,8 @@ namespace OpenRA
|
||||
// querying player traits in INotifyCreated.Created would crash.
|
||||
// Therefore assign the uninitialized actor and run the Created callbacks
|
||||
// by calling Initialize ourselves.
|
||||
var playerActorType = world.Type == WorldType.Editor ? EditorPlayerActorType : PlayerActorType;
|
||||
PlayerActor = new Actor(world, playerActorType, new TypeDictionary { new OwnerInit(this) });
|
||||
var playerActorType = world.Type == WorldType.Editor ? SystemActors.EditorPlayer : SystemActors.Player;
|
||||
PlayerActor = new Actor(world, playerActorType.ToString(), new TypeDictionary { new OwnerInit(this) });
|
||||
PlayerActor.Initialize(true);
|
||||
|
||||
Shroud = PlayerActor.Trait<Shroud>();
|
||||
|
||||
48
OpenRA.Game/Primitives/ActorInfoDictionary.cs
Normal file
48
OpenRA.Game/Primitives/ActorInfoDictionary.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class ActorInfoDictionary : IReadOnlyDictionary<string, ActorInfo>
|
||||
{
|
||||
readonly Dictionary<string, ActorInfo> dict;
|
||||
|
||||
public ActorInfoDictionary(IReadOnlyDictionary<string, ActorInfo> dict)
|
||||
{
|
||||
if (dict == null)
|
||||
throw new ArgumentNullException(nameof(dict));
|
||||
|
||||
this.dict = new Dictionary<string, ActorInfo>(dict);
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key) => dict.ContainsKey(key);
|
||||
|
||||
public bool TryGetValue(string key, out ActorInfo value) => dict.TryGetValue(key, out value);
|
||||
|
||||
public int Count => dict.Count;
|
||||
|
||||
public ActorInfo this[string key] => dict[key];
|
||||
public ActorInfo this[SystemActors key] => dict[key.ToString().ToLowerInvariant()];
|
||||
|
||||
IEnumerable<string> IReadOnlyDictionary<string, ActorInfo>.Keys => dict.Keys;
|
||||
IEnumerable<ActorInfo> IReadOnlyDictionary<string, ActorInfo>.Values => dict.Values;
|
||||
|
||||
public ICollection<string> Keys => dict.Keys;
|
||||
public ICollection<ActorInfo> Values => dict.Values;
|
||||
|
||||
public IEnumerator<KeyValuePair<string, ActorInfo>> GetEnumerator() => dict.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => dict.GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ namespace OpenRA.Scripting
|
||||
var knownPlayerCommands = Game.ModData.ObjectCreator
|
||||
.GetTypesImplementing<ScriptPlayerProperties>()
|
||||
.ToArray();
|
||||
PlayerCommands = FilterCommands(world.Map.Rules.Actors["player"], knownPlayerCommands);
|
||||
PlayerCommands = FilterCommands(world.Map.Rules.Actors[SystemActors.Player], knownPlayerCommands);
|
||||
|
||||
runtime.Globals["EngineDir"] = Platform.EngineDir;
|
||||
runtime.DoBuffer(File.Open(Path.Combine(Platform.EngineDir, "lua", "scriptwrapper.lua"), FileMode.Open, FileAccess.Read).ReadAllText(), "scriptwrapper.lua").Dispose();
|
||||
|
||||
@@ -1209,7 +1209,7 @@ namespace OpenRA.Server
|
||||
// The null padding is needed to keep the player indexes in sync with world.Players on the clients
|
||||
// This will need to change if future code wants to use worldPlayers for other purposes
|
||||
var playerRandom = new MersenneTwister(LobbyInfo.GlobalSettings.RandomSeed);
|
||||
foreach (var cmpi in Map.Rules.Actors["world"].TraitInfos<ICreatePlayersInfo>())
|
||||
foreach (var cmpi in Map.Rules.Actors[SystemActors.World].TraitInfos<ICreatePlayersInfo>())
|
||||
cmpi.CreateServerPlayers(Map, LobbyInfo, worldPlayers, playerRandom);
|
||||
|
||||
if (recorder != null)
|
||||
|
||||
@@ -403,7 +403,7 @@ namespace OpenRA
|
||||
public static string SanitizedPlayerName(string dirty)
|
||||
{
|
||||
var forbiddenNames = new string[] { "Open", "Closed" };
|
||||
var botNames = OpenRA.Game.ModData.DefaultRules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
|
||||
var botNames = OpenRA.Game.ModData.DefaultRules.Actors[SystemActors.Player].TraitInfos<IBotInfo>().Select(t => t.Name);
|
||||
|
||||
var clean = SanitizedName(dirty);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Checks for pause related desyncs. Attach this to the world actor.")]
|
||||
public class DebugPauseStateInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -105,4 +105,14 @@ namespace OpenRA.Traits
|
||||
PlayerPaletteReferenceSwitch = playerPaletteReferenceSwitch;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class TraitLocationAttribute : Attribute
|
||||
{
|
||||
public readonly SystemActors SystemActors;
|
||||
public TraitLocationAttribute(SystemActors systemActors)
|
||||
{
|
||||
SystemActors = systemActors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace OpenRA.Traits
|
||||
void OnVisibilityChanged(FrozenActor frozen);
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Required for FrozenUnderFog to work. Attach this to the player actor.")]
|
||||
public class FrozenActorLayerInfo : TraitInfo, Requires<ShroudInfo>
|
||||
{
|
||||
|
||||
@@ -14,7 +14,8 @@ using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[Desc("Add this to the Player actor definition.")]
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Add this to the World actor definition.")]
|
||||
public class PlayerColorPaletteInfo : TraitInfo
|
||||
{
|
||||
[PaletteReference]
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player | SystemActors.EditorPlayer)]
|
||||
[Desc("Required for shroud and fog visibility checks. Add this to the player actor.")]
|
||||
public class ShroudInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Enables visualization commands. Attach this to the world actor.")]
|
||||
public class DebugVisualizationsInfo : TraitInfo<DebugVisualizations> { }
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[Desc("Attach this to the `World` actor.")]
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
public class FactionInfo : TraitInfo<Faction>
|
||||
{
|
||||
[Desc("This is the name exposed to the players.")]
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace OpenRA.Traits
|
||||
public override string ToString() { return "{0}->{1}".F(Actor.Info.Name, Bounds.GetType().Name); }
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
public class ScreenMapInfo : TraitInfo
|
||||
{
|
||||
[Desc("Size of partition bins (world pixels)")]
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class ScreenShakerInfo : TraitInfo
|
||||
{
|
||||
public readonly float2 MinMultiplier = new float2(-3, -3);
|
||||
|
||||
@@ -202,8 +202,8 @@ namespace OpenRA
|
||||
|
||||
ModelCache = modData.ModelSequenceLoader.CacheModels(map, modData, map.Rules.ModelSequences);
|
||||
|
||||
var worldActorType = type == WorldType.Editor ? "EditorWorld" : "World";
|
||||
WorldActor = CreateActor(worldActorType, new TypeDictionary());
|
||||
var worldActorType = type == WorldType.Editor ? SystemActors.EditorWorld : SystemActors.World;
|
||||
WorldActor = CreateActor(worldActorType.ToString(), new TypeDictionary());
|
||||
ActorMap = WorldActor.Trait<IActorMap>();
|
||||
ScreenMap = WorldActor.Trait<ScreenMap>();
|
||||
Selection = WorldActor.Trait<ISelection>();
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Required for `GpsPower`. Attach this to the player actor.")]
|
||||
class GpsWatcherInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Apply palette full screen rotations during chronoshifts. Add this to the world actor.")]
|
||||
public class ChronoshiftPaletteEffectInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Palette effect used for blinking \"animations\" on actors.")]
|
||||
class LightPaletteRotatorInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Adds the hard-coded shroud palette to the game")]
|
||||
class ShroudPaletteInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Adds the hard-coded shroud palette to the game")]
|
||||
class TSShroudPaletteInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -42,13 +42,13 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
var srcModData = new ModData(utility.Mods[srcMod], utility.Mods);
|
||||
Game.ModData = srcModData;
|
||||
|
||||
var srcPaletteInfo = srcModData.DefaultRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var srcPaletteInfo = srcModData.DefaultRules.Actors[SystemActors.Player].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var srcRemapIndex = srcPaletteInfo.RemapIndex;
|
||||
|
||||
var destMod = args[2].Split(':')[0];
|
||||
var destModData = new ModData(utility.Mods[destMod], utility.Mods);
|
||||
Game.ModData = destModData;
|
||||
var destPaletteInfo = destModData.DefaultRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var destPaletteInfo = destModData.DefaultRules.Actors[SystemActors.Player].TraitInfo<PlayerColorPaletteInfo>();
|
||||
var destRemapIndex = destPaletteInfo.RemapIndex;
|
||||
var shadowIndex = new int[] { };
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Commands
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Enables commands triggered by typing them into the chatbox. Attach this to the world actor.")]
|
||||
public class ChatCommandsInfo : TraitInfo<ChatCommands> { }
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Commands
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Enables visualization commands via the chatbox. Attach this to the world actor.")]
|
||||
public class DebugVisualizationCommandsInfo : TraitInfo<DebugVisualizationCommands> { }
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Commands
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Enables developer cheats via the chatbox. Attach this to the world actor.")]
|
||||
public class DevCommandsInfo : TraitInfo<DevCommands> { }
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Commands
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Shows a list of available commands in the chatbox. Attach this to the world actor.")]
|
||||
public class HelpCommandInfo : TraitInfo<HelpCommand> { }
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Commands
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Allows the player to pause or surrender the game via the chatbox. Attach this to the world actor.")]
|
||||
public class PlayerCommandsInfo : TraitInfo<PlayerCommands> { }
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
|
||||
{
|
||||
var worldActor = rules.Actors["world"];
|
||||
var worldActor = rules.Actors[SystemActors.World];
|
||||
var locomotorInfos = worldActor.TraitInfos<LocomotorInfo>().ToArray();
|
||||
foreach (var li in locomotorInfos)
|
||||
foreach (var otherLocomotor in locomotorInfos)
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (!worldOwnerFound)
|
||||
emitError("Found no player owning the world.");
|
||||
|
||||
var worldActor = map.Rules.Actors["world"];
|
||||
var worldActor = map.Rules.Actors[SystemActors.World];
|
||||
var factions = worldActor.TraitInfos<FactionInfo>().Select(f => f.InternalName).ToHashSet();
|
||||
foreach (var player in players.Values)
|
||||
if (!string.IsNullOrWhiteSpace(player.Faction) && !factions.Contains(player.Faction))
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
void Run(Action<string> emitError, Action<string> emitWarning, Ruleset rules, SequenceProvider sequences)
|
||||
{
|
||||
var factions = rules.Actors["world"].TraitInfos<FactionInfo>().Select(f => f.InternalName).ToArray();
|
||||
var factions = rules.Actors[SystemActors.World].TraitInfos<FactionInfo>().Select(f => f.InternalName).ToArray();
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
// Actors may have 0 or 1 RenderSprites traits
|
||||
|
||||
43
OpenRA.Mods.Common/Lint/CheckTraitLocation.cs
Normal file
43
OpenRA.Mods.Common/Lint/CheckTraitLocation.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using DiscordRPC.Helper;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
public class CheckTraitLocation : ILintRulesPass
|
||||
{
|
||||
void ILintRulesPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules)
|
||||
{
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
|
||||
{
|
||||
var traitLocation = traitInfo.GetType().GetCustomAttributes<TraitLocationAttribute>(true).FirstOrDefault();
|
||||
if (traitLocation == null)
|
||||
continue;
|
||||
|
||||
if (!Enum.TryParse(actorInfo.Key, true, out SystemActors systemActor) || !traitLocation.SystemActors.HasFlag(systemActor))
|
||||
{
|
||||
// Remove the "Info" suffix
|
||||
var traitName = traitInfo.GetType().Name;
|
||||
traitName = traitName.Remove(traitName.Length - 4);
|
||||
var locations = traitLocation.SystemActors.ToString().Replace(", ", " or ");
|
||||
emitError("{0} does not belong on {1}. It is a system trait meant for {2}.".F(traitName, actorInfo.Key, locations));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,7 +357,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
}
|
||||
|
||||
var botType = parts[2];
|
||||
var botInfo = server.Map.Rules.Actors["player"].TraitInfos<IBotInfo>()
|
||||
var botInfo = server.Map.Rules.Actors[SystemActors.Player].TraitInfos<IBotInfo>()
|
||||
.FirstOrDefault(b => b.Type == botType);
|
||||
|
||||
if (botInfo == null)
|
||||
@@ -440,7 +440,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
LoadMapSettings(server, server.LobbyInfo.GlobalSettings, server.Map.Rules);
|
||||
|
||||
// Reset client states
|
||||
var selectableFactions = server.Map.Rules.Actors["world"].TraitInfos<FactionInfo>()
|
||||
var selectableFactions = server.Map.Rules.Actors[SystemActors.World].TraitInfos<FactionInfo>()
|
||||
.Where(f => f.Selectable)
|
||||
.Select(f => f.InternalName)
|
||||
.ToList();
|
||||
@@ -457,7 +457,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
// - Players who now lack a slot are made observers
|
||||
// - Bots who now lack a slot are dropped
|
||||
// - Bots who are not defined in the map rules are dropped
|
||||
var botTypes = server.Map.Rules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Type);
|
||||
var botTypes = server.Map.Rules.Actors[SystemActors.Player].TraitInfos<IBotInfo>().Select(t => t.Type);
|
||||
var slots = server.LobbyInfo.Slots.Keys.ToArray();
|
||||
var i = 0;
|
||||
foreach (var os in oldSlots)
|
||||
@@ -534,8 +534,8 @@ namespace OpenRA.Mods.Common.Server
|
||||
return true;
|
||||
}
|
||||
|
||||
var allOptions = server.Map.Rules.Actors["player"].TraitInfos<ILobbyOptions>()
|
||||
.Concat(server.Map.Rules.Actors["world"].TraitInfos<ILobbyOptions>())
|
||||
var allOptions = server.Map.Rules.Actors[SystemActors.Player].TraitInfos<ILobbyOptions>()
|
||||
.Concat(server.Map.Rules.Actors[SystemActors.World].TraitInfos<ILobbyOptions>())
|
||||
.SelectMany(t => t.LobbyOptions(server.Map.Rules));
|
||||
|
||||
// Overwrite keys with duplicate ids
|
||||
@@ -775,7 +775,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
if (server.LobbyInfo.Slots[targetClient.Slot].LockFaction)
|
||||
return true;
|
||||
|
||||
var factions = server.Map.Rules.Actors["world"].TraitInfos<FactionInfo>()
|
||||
var factions = server.Map.Rules.Actors[SystemActors.World].TraitInfos<FactionInfo>()
|
||||
.Where(f => f.Selectable).Select(f => f.InternalName);
|
||||
|
||||
if (!factions.Contains(parts[1]))
|
||||
@@ -1045,8 +1045,8 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
lock (server.LobbyInfo)
|
||||
{
|
||||
var options = rules.Actors["player"].TraitInfos<ILobbyOptions>()
|
||||
.Concat(rules.Actors["world"].TraitInfos<ILobbyOptions>())
|
||||
var options = rules.Actors[SystemActors.Player].TraitInfos<ILobbyOptions>()
|
||||
.Concat(rules.Actors[SystemActors.World].TraitInfos<ILobbyOptions>())
|
||||
.SelectMany(t => t.LobbyOptions(rules));
|
||||
|
||||
foreach (var o in options)
|
||||
@@ -1100,7 +1100,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
static string MissionBriefingOrDefault(S server)
|
||||
{
|
||||
var missionData = server.Map.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
|
||||
var missionData = server.Map.Rules.Actors[SystemActors.World].TraitInfoOrDefault<MissionDataInfo>();
|
||||
if (missionData != null && !string.IsNullOrEmpty(missionData.Briefing))
|
||||
return missionData.Briefing.Replace("\\n", "\n");
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace OpenRA.Mods.Common.Server
|
||||
var defaults = new Session.Global();
|
||||
LobbyCommands.LoadMapSettings(server, defaults, server.Map.Rules);
|
||||
|
||||
var options = server.Map.Rules.Actors["player"].TraitInfos<ILobbyOptions>()
|
||||
.Concat(server.Map.Rules.Actors["world"].TraitInfos<ILobbyOptions>())
|
||||
var options = server.Map.Rules.Actors[SystemActors.Player].TraitInfos<ILobbyOptions>()
|
||||
.Concat(server.Map.Rules.Actors[SystemActors.World].TraitInfos<ILobbyOptions>())
|
||||
.SelectMany(t => t.LobbyOptions(server.Map.Rules))
|
||||
.ToDictionary(o => o.Id, o => o);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
if (!rules.Actors["world"].HasTraitInfo<ITiledTerrainRendererInfo>())
|
||||
if (!rules.Actors[SystemActors.World].HasTraitInfo<ITiledTerrainRendererInfo>())
|
||||
throw new YamlException("Bridge requires a tile-based terrain renderer.");
|
||||
|
||||
if (string.IsNullOrEmpty(DemolishWeapon))
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("A dictionary of buildings placed on the map. Attach this to the world actor.")]
|
||||
public class BuildingInfluenceInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var locomotorInfos = rules.Actors["world"].TraitInfos<LocomotorInfo>();
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>();
|
||||
LocomotorInfo = locomotorInfos.FirstOrDefault(li => li.Name == Locomotor);
|
||||
if (LocomotorInfo == null)
|
||||
throw new YamlException("A locomotor named '{0}' doesn't exist.".F(Locomotor));
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var locomotorInfos = rules.Actors["world"].TraitInfos<LocomotorInfo>();
|
||||
var locomotorInfos = rules.Actors[SystemActors.World].TraitInfos<LocomotorInfo>();
|
||||
LocomotorInfo = locomotorInfos.FirstOrDefault(li => li.Name == Locomotor);
|
||||
if (LocomotorInfo == null)
|
||||
throw new YamlException("A locomotor named '{0}' doesn't exist.".F(Locomotor));
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var map = init.World.Map;
|
||||
|
||||
// Explore map-placed actors if the "Explore Map" option is enabled
|
||||
var shroudInfo = init.World.Map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
|
||||
var shroudInfo = init.World.Map.Rules.Actors[SystemActors.Player].TraitInfo<ShroudInfo>();
|
||||
var exploredMap = init.World.LobbyInfo.GlobalSettings.OptionOrDefault("explored", shroudInfo.ExploredMapCheckboxEnabled);
|
||||
startsRevealed = exploredMap && init.Contains<SpawnedByMapInit>() && !init.Contains<HiddenUnderFogInit>();
|
||||
var buildingInfo = init.Self.Info.TraitInfoOrDefault<BuildingInfo>();
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
using GUtil = OpenRA.Graphics.Util;
|
||||
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Used for bursted one-colored whole screen effects. Add this to the world actor.")]
|
||||
public class FlashPaletteEffectInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Fades the world from/to black at the start/end of the game, and can (optionally) desaturate the world")]
|
||||
public class MenuPaletteEffectInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Palette effect used for sprinkle \"animations\".")]
|
||||
class RotationPaletteEffectInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor to allow building repair by team mates.")]
|
||||
class AllyRepairInfo : TraitInfo<AllyRepair> { }
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Plays an audio notification and shows a radar ping when a building is attacked.",
|
||||
"Attach this to the player actor.")]
|
||||
public class BaseAttackNotifierInfo : TraitInfo
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"Will only work together with the Production: trait on the actor that actually does the production.",
|
||||
"You will also want to add PrimaryBuildings: to let the user choose where new units should exit.",
|
||||
"The production speed depends on the number of production buildings and units queued at the same time.")]
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class ClassicParallelProductionQueueInfo : ProductionQueueInfo, Requires<TechTreeInfo>, Requires<PlayerResourcesInfo>
|
||||
{
|
||||
[Desc("If you build more actors of the same type,", "the same queue will get its build time lowered for every actor produced there.")]
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor (not a building!) to define a new shared build queue.",
|
||||
"Will only work together with the Production: trait on the actor that actually does the production.",
|
||||
"You will also want to add PrimaryBuildings: to let the user choose where new units should exit.")]
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class ConquestVictoryConditionsInfo : TraitInfo, Requires<MissionObjectivesInfo>
|
||||
{
|
||||
[Desc("Delay for the end game notification in milliseconds.")]
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor.")]
|
||||
public class DeveloperModeInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Tracks neutral and enemy actors' visibility and notifies the player.",
|
||||
"Attach this to the player actor. The actors to track need the 'AnnounceOnSeen' trait.")]
|
||||
class EnemyWatcherInfo : TraitInfo
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor.")]
|
||||
public class GrantConditionOnPrerequisiteManagerInfo : TraitInfo, Requires<TechTreeInfo>
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Plays an audio notification and shows a radar ping when a harvester is attacked.",
|
||||
"Attach this to the player actor.")]
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class HarvesterAttackNotifierInfo : TraitInfo
|
||||
{
|
||||
[Desc("Minimum duration (in seconds) between notification events.")]
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class MissionObjectivesInfo : TraitInfo
|
||||
{
|
||||
[Desc("Set this to true if multiple cooperative players have a distinct set of " +
|
||||
@@ -258,6 +259,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Provides game mode progress information for players.",
|
||||
"Goes on WorldActor - observers don't have a player it can live on.",
|
||||
"Current options for PanelName are 'SKIRMISH_STATS' and 'MISSION_OBJECTIVES'.")]
|
||||
@@ -271,6 +273,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public override object Create(ActorInitializer init) { return new ObjectivesPanel(this); }
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class ObjectivesPanel : IObjectivesPanel
|
||||
{
|
||||
readonly ObjectivesPanelInfo info;
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("A beacon that is constructed from a circle sprite that is animated once and a moving arrow sprite.")]
|
||||
public class PlaceBeaconInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// Allows third party mods to detect whether an actor was created by PlaceBuilding.
|
||||
public class PlaceBuildingInit : RuntimeFlagInit { }
|
||||
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Allows the player to execute build orders.", " Attach this to the player actor.")]
|
||||
public class PlaceBuildingInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("This trait can be used to track player experience based on units killed with the `GivesExperience` trait.",
|
||||
"It can also be used as a point score system in scripted maps, for example.",
|
||||
"Attach this to the player actor.")]
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class PlayerRadarTerrainInfo : TraitInfo, Requires<ShroudInfo>
|
||||
{
|
||||
public override object Create(ActorInitializer init)
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player | SystemActors.EditorPlayer)]
|
||||
public class PlayerResourcesInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[Desc("Descriptive label for the starting cash option in the lobby.")]
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor to collect observer stats.")]
|
||||
public class PlayerStatisticsInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class ProvidesTechPrerequisiteInfo : TraitInfo, ITechTreePrerequisiteInfo
|
||||
{
|
||||
[Desc("Internal id for this tech level.")]
|
||||
|
||||
@@ -13,6 +13,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Provides the player with an audible warning when their storage is nearing full.")]
|
||||
public class ResourceStorageWarningInfo : TraitInfo, Requires<PlayerResourcesInfo>
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Manages build limits and pre-requisites.", " Attach this to the player actor.")]
|
||||
public class TechTreeInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("This trait allows setting a time limit on matches. Attach this to the World actor.")]
|
||||
public class TimeLimitManagerInfo : TraitInfo, ILobbyOptions, IRulesetLoaded
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor.")]
|
||||
public class PowerManagerInfo : TraitInfo, Requires<DeveloperModeInfo>
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
class ProductionQueueFromSelectionInfo : TraitInfo
|
||||
{
|
||||
public string ProductionTabsWidget = null;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void RulesetLoaded(Ruleset rules, ActorInfo info)
|
||||
{
|
||||
var pci = rules.Actors["player"].TraitInfoOrDefault<ProximityCaptorInfo>();
|
||||
var pci = rules.Actors[SystemActors.Player].TraitInfoOrDefault<ProximityCaptorInfo>();
|
||||
if (pci == null)
|
||||
throw new YamlException("ProximityCapturable requires the `Player` actor to have the ProximityCaptor trait.");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Displays custom terrain types.")]
|
||||
class CustomTerrainDebugOverlayInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
|
||||
// No queues available - check for classic production queues
|
||||
if (queue == null)
|
||||
queue = rules.Actors["player"].TraitInfos<ProductionQueueInfo>().FirstOrDefault(q => ProductionType == q.Type);
|
||||
queue = rules.Actors[SystemActors.Player].TraitInfos<ProductionQueueInfo>().FirstOrDefault(q => ProductionType == q.Type);
|
||||
|
||||
if (queue == null)
|
||||
throw new YamlException("Can't find a queue with ProductionType '{0}'".F(ProductionType));
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor. When attached, enables all actors possessing the ProducibleWithLevel ",
|
||||
"trait to have their production queue icons render with an overlay defined in this trait. ",
|
||||
"The icon change occurs when ProducibleWithLevel.Prerequisites are met.")]
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Attach this to the player actor.")]
|
||||
public class SupportPowerManagerInfo : TraitInfo, Requires<DeveloperModeInfo>, Requires<TechTreeInfo>
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
if (!rules.Actors["world"].HasTraitInfo<TerrainLightingInfo>())
|
||||
if (!rules.Actors[SystemActors.World].HasTraitInfo<TerrainLightingInfo>())
|
||||
throw new YamlException("TerrainLightSource can only be used with the world TerrainLighting trait.");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
public class ActorMapInfo : TraitInfo
|
||||
{
|
||||
[Desc("Size of partition bins (cells)")]
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Controls the spawning of specified actor types. Attach this to the world actor.")]
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class ActorSpawnManagerInfo : ConditionalTraitInfo, Requires<MapCreepsInfo>
|
||||
{
|
||||
[Desc("Minimum number of actors.")]
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class CrateSpawnerInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[Desc("Descriptive label for the crates checkbox in the lobby.")]
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Attach this to the world actor.")]
|
||||
public class CreateMapPlayersInfo : TraitInfo<CreateMapPlayers>, ICreatePlayersInfo
|
||||
{
|
||||
@@ -27,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
/// </summary>
|
||||
void ICreatePlayersInfo.CreateServerPlayers(MapPreview map, Session lobbyInfo, List<GameInformation.Player> players, MersenneTwister playerRandom)
|
||||
{
|
||||
var worldInfo = map.Rules.Actors["world"];
|
||||
var worldInfo = map.Rules.Actors[SystemActors.World];
|
||||
var factions = worldInfo.TraitInfos<FactionInfo>().ToArray();
|
||||
var assignSpawnLocations = worldInfo.TraitInfoOrDefault<IAssignSpawnPointsInfo>();
|
||||
var spawnState = assignSpawnLocations?.InitializeState(map, lobbyInfo);
|
||||
@@ -41,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
// Create the regular playable players.
|
||||
var bots = map.Rules.Actors["player"].TraitInfos<IBotInfo>().ToArray();
|
||||
var bots = map.Rules.Actors[SystemActors.Player].TraitInfos<IBotInfo>().ToArray();
|
||||
|
||||
foreach (var kv in lobbyInfo.Slots)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Identify untraversable regions of the map for faster pathfinding, especially with AI.",
|
||||
"This trait is required. Every mod needs it attached to the world actor.")]
|
||||
class DomainIndexInfo : TraitInfo<DomainIndex> { }
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.EditorWorld)]
|
||||
public class EditorActionManagerInfo : TraitInfo<EditorActionManager> { }
|
||||
|
||||
public class EditorActionManager : IWorldLoaded
|
||||
|
||||
@@ -21,6 +21,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.EditorWorld)]
|
||||
[Desc("Required for the map editor to work. Attach this to the world actor.")]
|
||||
public class EditorActorLayerInfo : TraitInfo, ICreatePlayersInfo
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public enum EditorCursorType { None, Actor, TerrainTemplate, Resource }
|
||||
|
||||
[TraitLocation(SystemActors.EditorWorld)]
|
||||
[Desc("Required for the map editor to work. Attach this to the world actor.")]
|
||||
public class EditorCursorLayerInfo : TraitInfo, Requires<EditorActorLayerInfo>, Requires<ITiledTerrainRendererInfo>
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.EditorWorld)]
|
||||
[Desc("Required for the map editor to work. Attach this to the world actor.")]
|
||||
public class EditorResourceLayerInfo : TraitInfo, IResourceLayerInfo, IMapPreviewSignatureInfo
|
||||
{
|
||||
@@ -94,7 +95,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (w.Type != WorldType.Editor)
|
||||
return;
|
||||
|
||||
var playerResourcesInfo = w.Map.Rules.Actors["player"].TraitInfoOrDefault<PlayerResourcesInfo>();
|
||||
var playerResourcesInfo = w.Map.Rules.Actors[SystemActors.Player].TraitInfoOrDefault<PlayerResourcesInfo>();
|
||||
resourceValues = playerResourcesInfo?.ResourceValues ?? new Dictionary<string, int>();
|
||||
|
||||
foreach (var cell in Map.AllCells)
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.EditorWorld)]
|
||||
[Desc("Required for the map editor to work. Attach this to the world actor.")]
|
||||
public class EditorSelectionLayerInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
public class GameSaveViewportManagerInfo : TraitInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new GameSaveViewportManager(); }
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Define a palette by swapping palette indices.")]
|
||||
public class IndexedPaletteInfo : TraitInfo, IRulesetLoaded
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
class LegacyBridgeLayerInfo : TraitInfo
|
||||
{
|
||||
[ActorReference]
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
public class LoadWidgetAtGameStartInfo : TraitInfo
|
||||
{
|
||||
[Desc("The widget tree to open when a shellmap is loaded (i.e. the main menu).")]
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.Player)]
|
||||
[Desc("Enables defined prerequisites at game start for all players if the checkbox is enabled.")]
|
||||
public class LobbyPrerequisiteCheckboxInfo : TraitInfo, ILobbyOptions, ITechTreePrerequisiteInfo
|
||||
{
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public const byte ElevatedBridge = 4;
|
||||
}
|
||||
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Used by Mobile. Attach these to the world actor. You can have multiple variants by adding @suffixes.")]
|
||||
public class LocomotorInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Controls the build radius checkboxes in the lobby options.")]
|
||||
public class MapBuildRadiusInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Controls the 'Creeps' checkbox in the lobby options.")]
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class MapCreepsInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[Desc("Descriptive label for the creeps checkbox in the lobby.")]
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Controls the game speed, tech level, and short game lobby options.")]
|
||||
public class MapOptionsInfo : TraitInfo, ILobbyOptions, IRulesetLoaded
|
||||
{
|
||||
@@ -77,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
yield return new LobbyBooleanOption("shortgame", ShortGameCheckboxLabel, ShortGameCheckboxDescription,
|
||||
ShortGameCheckboxVisible, ShortGameCheckboxDisplayOrder, ShortGameCheckboxEnabled, ShortGameCheckboxLocked);
|
||||
|
||||
var techLevels = rules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>()
|
||||
var techLevels = rules.Actors[SystemActors.Player].TraitInfos<ProvidesTechPrerequisiteInfo>()
|
||||
.ToDictionary(t => t.Id, t => t.Name);
|
||||
|
||||
if (techLevels.Any())
|
||||
|
||||
@@ -19,6 +19,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Allows the map to have working spawnpoints. Also controls the 'Separate Team Spawns' checkbox in the lobby options.")]
|
||||
public class MapStartingLocationsInfo : TraitInfo, ILobbyOptions, IAssignSpawnPointsInfo
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
[Desc("Used by SpawnStartingUnits. Attach these to the world actor. You can have multiple variants by adding @suffixes.")]
|
||||
public class StartingUnitsInfo : TraitInfo<StartingUnits>
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Trait for music handling. Attach this to the world actor.")]
|
||||
public class MusicPlaylistInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Load VGA palette (.pal) registers.")]
|
||||
class PaletteFromFileInfo : TraitInfo, IProvidesCursorPaletteInfo
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Load a GIMP .gpl or JASC .pal palette file. Supports per-color alpha.")]
|
||||
class PaletteFromGimpOrJascFileInfo : TraitInfo, IProvidesCursorPaletteInfo
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Create a palette by applying alpha transparency to another palette.")]
|
||||
class PaletteFromPaletteWithAlphaInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Create player palettes by applying alpha transparency to another player palette.")]
|
||||
class PaletteFromPlayerPaletteWithAlphaInfo : TraitInfo
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Load a PNG and use its embedded palette.")]
|
||||
class PaletteFromPngInfo : TraitInfo, IProvidesCursorPaletteInfo
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user