diff --git a/Content.Server/GameObjects/Components/AI/AiFactionPrototype.cs b/Content.Server/GameObjects/Components/AI/AiFactionPrototype.cs new file mode 100644 index 0000000000..1a1a762b5b --- /dev/null +++ b/Content.Server/GameObjects/Components/AI/AiFactionPrototype.cs @@ -0,0 +1,27 @@ +#nullable enable +using System.Collections.Generic; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using YamlDotNet.RepresentationModel; + +namespace Content.Server.GameObjects.Components.AI +{ + [Prototype("aiFaction")] + public class AiFactionPrototype : IIndexedPrototype, IPrototype + { + // These are immutable so any dynamic changes aren't saved back over. + // AiFactionSystem will just read these and then store them. + + public string ID { get; private set; } = default!; + + public IReadOnlyList Hostile { get; private set; } = default!; + + public void LoadFrom(YamlMappingNode mapping) + { + var serializer = YamlObjectSerializer.NewReader(mapping); + + serializer.DataField(this, x => x.ID, "id", string.Empty); + serializer.DataField(this, x => x.Hostile, "hostile", new List()); + } + } +} diff --git a/Content.Server/GameObjects/Components/AI/AiFactionTagComponent.cs b/Content.Server/GameObjects/Components/AI/AiFactionTagComponent.cs index 146a7d52ed..8a87590260 100644 --- a/Content.Server/GameObjects/Components/AI/AiFactionTagComponent.cs +++ b/Content.Server/GameObjects/Components/AI/AiFactionTagComponent.cs @@ -1,5 +1,7 @@ +#nullable enable using System; using System.Collections.Generic; +using Content.Server.GameObjects.EntitySystems.AI; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; @@ -35,15 +37,4 @@ namespace Content.Server.GameObjects.Components.AI }); } } - - [Flags] - public enum Faction - { - None = 0, - NanoTrasen = 1 << 0, - SimpleHostile = 1 << 1, - SimpleNeutral = 1 << 2, - Syndicate = 1 << 3, - Xeno = 1 << 4, - } } diff --git a/Content.Server/GameObjects/EntitySystems/AI/AiFactionTagSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/AiFactionTagSystem.cs index 9e6b06a4b7..2602b09a09 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/AiFactionTagSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/AiFactionTagSystem.cs @@ -1,6 +1,11 @@ +#nullable enable +using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.AI; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; +using Robust.Shared.Prototypes; namespace Content.Server.GameObjects.EntitySystems.AI { @@ -14,27 +19,44 @@ namespace Content.Server.GameObjects.EntitySystems.AI * This may change where specified friendly factions are listed. (e.g. to get number of friendlies in area). */ + private readonly Dictionary _hostileFactions = new(); + + public override void Initialize() + { + base.Initialize(); + var protoManager = IoCManager.Resolve(); + + foreach (var faction in protoManager.EnumeratePrototypes()) + { + if (Enum.TryParse(faction.ID, out Faction @enum)) + { + var parsedFaction = Faction.None; + + foreach (var hostile in faction.Hostile) + { + if (Enum.TryParse(hostile, out Faction parsedHostile)) + { + parsedFaction |= parsedHostile; + } + else + { + Logger.Error($"Unable to parse hostile faction {hostile} for {faction.ID}"); + } + } + + _hostileFactions[@enum] = parsedFaction; + } + else + { + Logger.Error($"Unable to parse AI faction {faction.ID}"); + } + } + } + public Faction GetHostileFactions(Faction faction) => _hostileFactions.TryGetValue(faction, out var hostiles) ? hostiles : Faction.None; - private readonly Dictionary _hostileFactions = new() - { - {Faction.NanoTrasen, - Faction.SimpleHostile | Faction.Syndicate | Faction.Xeno}, - {Faction.SimpleHostile, - Faction.NanoTrasen | Faction.Syndicate - }, - // What makes a man turn neutral? - {Faction.SimpleNeutral, - Faction.None - }, - {Faction.Syndicate, - Faction.NanoTrasen | Faction.SimpleHostile | Faction.Xeno}, - {Faction.Xeno, - Faction.NanoTrasen | Faction.Syndicate}, - }; - public Faction GetFactions(IEntity entity) => - entity.TryGetComponent(out AiFactionTagComponent factionTags) + entity.TryGetComponent(out AiFactionTagComponent? factionTags) ? factionTags.Factions : Faction.None; @@ -83,4 +105,15 @@ namespace Content.Server.GameObjects.EntitySystems.AI _hostileFactions[source] = hostileFactions; } } + + [Flags] + public enum Faction + { + None = 0, + NanoTrasen = 1 << 0, + SimpleHostile = 1 << 1, + SimpleNeutral = 1 << 2, + Syndicate = 1 << 3, + Xeno = 1 << 4, + } } diff --git a/Resources/Prototypes/ai_factions.yml b/Resources/Prototypes/ai_factions.yml new file mode 100644 index 0000000000..1a60f55763 --- /dev/null +++ b/Resources/Prototypes/ai_factions.yml @@ -0,0 +1,28 @@ +- type: aiFaction + id: NanoTrasen + hostile: + - SimpleHostile + - Syndicate + - Xeno + +- type: aiFaction + id: SimpleHostile + hostile: + - NanoTrasen + - Syndicate + +- type: aiFaction + id: SimpleNeutral + +- type: aiFaction + id: Syndicate + hostile: + - NanoTrasen + - SimpleHostile + - Xeno + +- type: aiFaction + id: Xeno + hostile: + - NanoTrasen + - Syndicate