From fcb09d069b2a386c40e220c8cd85bef9aee85725 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sat, 4 Aug 2018 01:20:21 +0200 Subject: [PATCH] Add RequiresSpecificOwners trait To enforce specific owners via Lint rules, and possibly other means later. This is for cases where accidentally setting an unfitting owner via editor could cause issues. Example: AI might try to attack Creeps-owned trees and get stuck. --- OpenRA.Mods.Common/Lint/CheckPlayers.cs | 12 +++++++++ OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Traits/RequiresSpecificOwners.cs | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 OpenRA.Mods.Common/Traits/RequiresSpecificOwners.cs diff --git a/OpenRA.Mods.Common/Lint/CheckPlayers.cs b/OpenRA.Mods.Common/Lint/CheckPlayers.cs index 7fa3b7e976..7a0ba26378 100644 --- a/OpenRA.Mods.Common/Lint/CheckPlayers.cs +++ b/OpenRA.Mods.Common/Lint/CheckPlayers.cs @@ -13,6 +13,8 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; +using OpenRA.Scripting; using OpenRA.Traits; namespace OpenRA.Mods.Common.Lint @@ -73,6 +75,11 @@ namespace OpenRA.Mods.Common.Lint emitError("Duplicate spawn point locations detected."); } + // Check for actors that require specific owners + var actorsWithRequiredOwner = map.Rules.Actors + .Where(a => a.Value.HasTraitInfo()) + .ToDictionary(a => a.Key, a => a.Value.TraitInfo()); + foreach (var kv in map.ActorDefinitions) { var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary()); @@ -89,6 +96,11 @@ namespace OpenRA.Mods.Common.Lint emitError("Actor {0} needs to be owned by the player that owns the world. ".F(kv.Key) + "Use the `Spawn` and `LockSpawn` player properties to force players onto a particular spawn instead."); } + + RequiresSpecificOwnersInfo info; + if (actorsWithRequiredOwner.TryGetValue(kv.Value.Value, out info)) + if (!info.ValidOwnerNames.Contains(ownerName)) + emitError("Actor {0} owner {1} is not one of ValidOwnerNames: {2}".F(kv.Key, ownerName, info.ValidOwnerNames.JoinWith(", "))); } } } diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 88c872f078..bb30a78172 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -501,6 +501,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/RequiresSpecificOwners.cs b/OpenRA.Mods.Common/Traits/RequiresSpecificOwners.cs new file mode 100644 index 0000000000..73d3bfcc2b --- /dev/null +++ b/OpenRA.Mods.Common/Traits/RequiresSpecificOwners.cs @@ -0,0 +1,26 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 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.Collections.Generic; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Can be used to enforce specific owners (like 'Neutral' or 'Creeps') for this actor.")] + public class RequiresSpecificOwnersInfo : TraitInfo + { + [Desc("Only allow players listed here as owners.")] + [FieldLoader.Require] + public readonly HashSet ValidOwnerNames = new HashSet(); + } + + public class RequiresSpecificOwners { } +}