diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index b2e011e01a..b8ab52922e 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -84,7 +84,7 @@ namespace Content.Client.Entry prototypes.RegisterIgnore("htnCompound"); prototypes.RegisterIgnore("htnPrimitive"); prototypes.RegisterIgnore("gameMap"); - prototypes.RegisterIgnore("behaviorSet"); + prototypes.RegisterIgnore("faction"); prototypes.RegisterIgnore("lobbyBackground"); prototypes.RegisterIgnore("advertisementsPack"); prototypes.RegisterIgnore("metabolizerType"); diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index ce0e9ecc15..58c133a42d 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -45,11 +45,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IMapLoader _mapLoader = default!; [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IPlayerManager _playerSystem = default!; + [Dependency] private readonly FactionSystem _faction = default!; [Dependency] private readonly StationSpawningSystem _stationSpawningSystem = default!; [Dependency] private readonly StationSystem _stationSystem = default!; [Dependency] private readonly ShuttleSystem _shuttleSystem = default!; [Dependency] private readonly RoundEndSystem _roundEndSystem = default!; - [Dependency] private readonly IPlayerManager _playerSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; @@ -667,9 +668,8 @@ public sealed class NukeopsRuleSystem : GameRuleSystem if(_startingGearPrototypes.TryGetValue(gear, out var gearPrototype)) _stationSpawningSystem.EquipStartingGear(mob, gearPrototype, null); - var faction = EnsureComp(mob); - faction.Factions |= Faction.Syndicate; - faction.Factions &= ~Faction.NanoTrasen; + _faction.RemoveFaction(mob, "NanoTrasen", false); + _faction.AddFaction(mob, "Syndicate", true); } private void SpawnOperatives(int spawnCount, List sessions, bool addSpawnPoints) diff --git a/Content.Server/NPC/Commands/FactionCommand.cs b/Content.Server/NPC/Commands/FactionCommand.cs deleted file mode 100644 index a052c0a9f7..0000000000 --- a/Content.Server/NPC/Commands/FactionCommand.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Text; -using Content.Server.Administration; -using Content.Server.NPC.Systems; -using Content.Shared.Administration; -using Robust.Shared.Console; - -namespace Content.Server.NPC.Commands -{ - [AdminCommand(AdminFlags.Fun)] - public sealed class FactionCommand : IConsoleCommand - { - public string Command => "factions"; - public string Description => Loc.GetString("faction-command-description"); - public string Help => Loc.GetString("faction-command-help-text"); - - public void Execute(IConsoleShell shell, string argStr, string[] args) - { - if (args.Length == 0) - { - var result = new StringBuilder(); - foreach (Faction value in Enum.GetValues(typeof(Faction))) - { - if (value == Faction.None) - continue; - result.Append(value + "\n"); - } - - shell.WriteLine(result.ToString()); - return; - } - - if (args.Length < 2) - { - shell.WriteLine(Loc.GetString("shell-wrong-arguments-number")); - return; - } - - if (!Enum.TryParse(args[0], true, out Faction faction)) - { - shell.WriteLine(Loc.GetString("faction-command-invalid-faction-error")); - return; - } - - Faction targetFaction; - - switch (args[1]) - { - case "friendly": - if (args.Length < 3) - { - shell.WriteLine(Loc.GetString("faction-command-no-target-faction-error")); - return; - } - - if (!Enum.TryParse(args[2], true, out targetFaction)) - { - shell.WriteLine(Loc.GetString("faction-command-invalid-target-faction-error")); - return; - } - - EntitySystem.Get().MakeFriendly(faction, targetFaction); - shell.WriteLine(Loc.GetString("shell-command-success")); - break; - case "hostile": - if (args.Length < 3) - { - shell.WriteLine(Loc.GetString("faction-command-no-target-faction-error")); - return; - } - - if (!Enum.TryParse(args[2], true, out targetFaction)) - { - shell.WriteLine(Loc.GetString("faction-command-invalid-target-faction-error")); - return; - } - - EntitySystem.Get().MakeHostile(faction, targetFaction); - shell.WriteLine(Loc.GetString("shell-command-success")); - break; - case "list": - shell.WriteLine(EntitySystem.Get().GetHostileFactions(faction).ToString()); - break; - default: - shell.WriteLine(Loc.GetString("faction-command-unknown-faction-argument-error")); - break; - } - } - } -} diff --git a/Content.Server/NPC/Components/AiFactionPrototype.cs b/Content.Server/NPC/Components/AiFactionPrototype.cs deleted file mode 100644 index 4abe23fb6b..0000000000 --- a/Content.Server/NPC/Components/AiFactionPrototype.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Robust.Shared.Prototypes; - -namespace Content.Server.NPC.Components -{ - [Prototype("aiFaction")] - public sealed class AiFactionPrototype : IPrototype - { - // These are immutable so any dynamic changes aren't saved back over. - // AiFactionSystem will just read these and then store them. - [ViewVariables] - [IdDataField] - public string ID { get; } = default!; - - [DataField("hostile")] - public IReadOnlyList Hostile { get; private set; } = new List(); - } -} diff --git a/Content.Server/NPC/Components/AiFactionTagComponent.cs b/Content.Server/NPC/Components/AiFactionTagComponent.cs deleted file mode 100644 index 00ac79eb32..0000000000 --- a/Content.Server/NPC/Components/AiFactionTagComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Content.Server.NPC.Systems; - -namespace Content.Server.NPC.Components -{ - [RegisterComponent] - public sealed class AiFactionTagComponent : Component - { - [DataField("factions")] - public Faction Factions { get; set; } = Faction.None; - } -} diff --git a/Content.Server/NPC/Components/FactionComponent.cs b/Content.Server/NPC/Components/FactionComponent.cs new file mode 100644 index 0000000000..9ea3f75cad --- /dev/null +++ b/Content.Server/NPC/Components/FactionComponent.cs @@ -0,0 +1,29 @@ +using Content.Server.NPC.Systems; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; + +namespace Content.Server.NPC.Components +{ + [RegisterComponent] + [Access(typeof(FactionSystem))] + public sealed class FactionComponent : Component + { + /// + /// Factions this entity is a part of. + /// + [ViewVariables(VVAccess.ReadWrite), + DataField("factions", customTypeSerializer:typeof(PrototypeIdHashSetSerializer))] + public HashSet Factions = new(); + + /// + /// Cached friendly factions. + /// + [ViewVariables] + public readonly HashSet FriendlyFactions = new(); + + /// + /// Cached hostile factions. + /// + [ViewVariables] + public readonly HashSet HostileFactions = new(); + } +} diff --git a/Content.Server/NPC/Components/FactionPrototype.cs b/Content.Server/NPC/Components/FactionPrototype.cs new file mode 100644 index 0000000000..ddb6dd07eb --- /dev/null +++ b/Content.Server/NPC/Components/FactionPrototype.cs @@ -0,0 +1,23 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; + +namespace Content.Server.NPC.Components +{ + /// + /// Contains data about this faction's relations with other factions. + /// + [Prototype("faction")] + public sealed class FactionPrototype : IPrototype + { + [ViewVariables] + [IdDataField] + public string ID { get; } = default!; + + [ViewVariables(VVAccess.ReadWrite), DataField("friendly", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List Friendly = new(); + + [ViewVariables(VVAccess.ReadWrite), DataField("hostile", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List Hostile = new(); + } +} diff --git a/Content.Server/NPC/FactionData.cs b/Content.Server/NPC/FactionData.cs new file mode 100644 index 0000000000..b74150acc9 --- /dev/null +++ b/Content.Server/NPC/FactionData.cs @@ -0,0 +1,13 @@ +namespace Content.Server.NPC; + +/// +/// Cached data for the faction prototype. Can be modified at runtime. +/// +public sealed class FactionData +{ + [ViewVariables] + public HashSet Friendly = new(); + + [ViewVariables] + public HashSet Hostile = new(); +} diff --git a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/NPCCombatOperator.cs b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/NPCCombatOperator.cs index 0c2ee3f5ed..c151b8030f 100644 --- a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/NPCCombatOperator.cs +++ b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/NPCCombatOperator.cs @@ -10,7 +10,7 @@ namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators; public abstract class NPCCombatOperator : HTNOperator { [Dependency] protected readonly IEntityManager EntManager = default!; - private AiFactionTagSystem _tags = default!; + private FactionSystem _tags = default!; protected InteractionSystem Interaction = default!; [ViewVariables, DataField("key")] public string Key = "CombatTarget"; @@ -24,7 +24,7 @@ public abstract class NPCCombatOperator : HTNOperator public override void Initialize(IEntitySystemManager sysManager) { base.Initialize(sysManager); - _tags = sysManager.GetEntitySystem(); + _tags = sysManager.GetEntitySystem(); Interaction = sysManager.GetEntitySystem(); } diff --git a/Content.Server/NPC/Systems/AiFactionTagSystem.cs b/Content.Server/NPC/Systems/AiFactionTagSystem.cs deleted file mode 100644 index 3631a2a94a..0000000000 --- a/Content.Server/NPC/Systems/AiFactionTagSystem.cs +++ /dev/null @@ -1,123 +0,0 @@ -using Content.Server.NPC.Components; -using Robust.Shared.Prototypes; - -namespace Content.Server.NPC.Systems -{ - /// - /// Outlines faction relationships with each other for AI. - /// - public sealed class AiFactionTagSystem : EntitySystem - { - /* - * Currently factions are implicitly friendly if they are not hostile. - * 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; - - public Faction GetFactions(EntityUid entity) => - EntityManager.TryGetComponent(entity, out AiFactionTagComponent? factionTags) - ? factionTags.Factions - : Faction.None; - - public IEnumerable GetNearbyHostiles(EntityUid entity, float range) - { - var ourFaction = GetFactions(entity); - var hostile = GetHostileFactions(ourFaction); - if (ourFaction == Faction.None || hostile == Faction.None) - { - yield break; - } - - // TODO: Yes I know this system is shithouse - var xformQuery = GetEntityQuery(); - var xform = xformQuery.GetComponent(entity); - - foreach (var component in EntityManager.EntityQuery(true)) - { - if ((component.Factions & hostile) == 0) - continue; - - if (!xformQuery.TryGetComponent(component.Owner, out var targetXform)) - continue; - - if (targetXform.MapID != xform.MapID) - continue; - - if (!targetXform.Coordinates.InRange(EntityManager, xform.Coordinates, range)) - continue; - - yield return component.Owner; - } - } - - public void MakeFriendly(Faction source, Faction target) - { - if (!_hostileFactions.TryGetValue(source, out var hostileFactions)) - { - return; - } - - hostileFactions &= ~target; - _hostileFactions[source] = hostileFactions; - } - - public void MakeHostile(Faction source, Faction target) - { - if (!_hostileFactions.TryGetValue(source, out var hostileFactions)) - { - _hostileFactions[source] = target; - return; - } - - hostileFactions |= target; - _hostileFactions[source] = hostileFactions; - } - } - - [Flags] - public enum Faction - { - None = 0, - Dragon = 1 << 0, - NanoTrasen = 1 << 1, - SimpleHostile = 1 << 2, - SimpleNeutral = 1 << 3, - Syndicate = 1 << 4, - Xeno = 1 << 5, - } -} diff --git a/Content.Server/NPC/Systems/FactionSystem.cs b/Content.Server/NPC/Systems/FactionSystem.cs new file mode 100644 index 0000000000..d177fe8f2e --- /dev/null +++ b/Content.Server/NPC/Systems/FactionSystem.cs @@ -0,0 +1,207 @@ +using System.Linq; +using Content.Server.NPC.Components; +using Robust.Shared.Prototypes; + +namespace Content.Server.NPC.Systems +{ + /// + /// Outlines faction relationships with each other. + /// + public sealed class FactionSystem : EntitySystem + { + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + + private ISawmill _sawmill = default!; + + /// + /// To avoid prototype mutability we store an intermediary data class that gets used instead. + /// + private Dictionary _factions = new(); + + public override void Initialize() + { + base.Initialize(); + _sawmill = Logger.GetSawmill("faction"); + SubscribeLocalEvent(OnFactionStartup); + _protoManager.PrototypesReloaded += OnProtoReload; + RefreshFactions(); + } + + public override void Shutdown() + { + base.Shutdown(); + _protoManager.PrototypesReloaded -= OnProtoReload; + } + + private void OnProtoReload(PrototypesReloadedEventArgs obj) + { + RefreshFactions(); + } + + private void OnFactionStartup(EntityUid uid, FactionComponent component, ComponentStartup args) + { + RefreshFactions(component); + } + + /// + /// Refreshes the cached factions for this component. + /// + private void RefreshFactions(FactionComponent component) + { + foreach (var faction in component.Factions) + { + // YAML Linter already yells about this + if (!_factions.TryGetValue(faction, out var factionData)) + continue; + + component.FriendlyFactions.UnionWith(factionData.Friendly); + component.HostileFactions.UnionWith(factionData.Hostile); + } + } + + /// + /// Adds this entity to the particular faction. + /// + public void AddFaction(EntityUid uid, string faction, bool dirty = true) + { + if (!_protoManager.HasIndex(faction)) + { + _sawmill.Error($"Unable to find faction {faction}"); + return; + } + + var comp = EnsureComp(uid); + if (!comp.Factions.Add(faction)) + return; + + if (dirty) + { + RefreshFactions(comp); + } + } + + /// + /// Removes this entity from the particular faction. + /// + public void RemoveFaction(EntityUid uid, string faction, bool dirty = true) + { + if (!_protoManager.HasIndex(faction)) + { + _sawmill.Error($"Unable to find faction {faction}"); + return; + } + + if (!TryComp(uid, out var component)) + return; + + if (!component.Factions.Remove(faction)) + return; + + if (dirty) + { + RefreshFactions(component); + } + } + + public IEnumerable GetNearbyHostiles(EntityUid entity, float range, FactionComponent? component = null) + { + if (!Resolve(entity, ref component, false)) + return Array.Empty(); + + return GetNearbyFactions(entity, range, component.HostileFactions); + } + + public IEnumerable GetNearbyFriendlies(EntityUid entity, float range, FactionComponent? component = null) + { + if (!Resolve(entity, ref component, false)) + return Array.Empty(); + + return GetNearbyFactions(entity, range, component.FriendlyFactions); + } + + private IEnumerable GetNearbyFactions(EntityUid entity, float range, HashSet factions) + { + var xformQuery = GetEntityQuery(); + + if (!xformQuery.TryGetComponent(entity, out var entityXform)) + yield break; + + foreach (var comp in _lookup.GetComponentsInRange(entityXform.MapPosition, range)) + { + if (comp.Owner == entity) + continue; + + if (!factions.Overlaps(comp.Factions)) + continue; + + yield return comp.Owner; + } + } + + /// + /// Makes the source faction friendly to the target faction, 1-way. + /// + public void MakeFriendly(string source, string target) + { + if (!_factions.TryGetValue(source, out var sourceFaction)) + { + _sawmill.Error($"Unable to find faction {source}"); + return; + } + + if (!_factions.ContainsKey(target)) + { + _sawmill.Error($"Unable to find faction {target}"); + return; + } + + sourceFaction.Friendly.Add(target); + sourceFaction.Hostile.Remove(target); + RefreshFactions(); + } + + private void RefreshFactions() + { + _factions.Clear(); + + foreach (var faction in _protoManager.EnumeratePrototypes()) + { + _factions[faction.ID] = new FactionData() + { + Friendly = faction.Friendly.ToHashSet(), + Hostile = faction.Hostile.ToHashSet(), + }; + } + + foreach (var comp in EntityQuery(true)) + { + comp.FriendlyFactions.Clear(); + comp.HostileFactions.Clear(); + RefreshFactions(comp); + } + } + + /// + /// Makes the source faction hostile to the target faction, 1-way. + /// + public void MakeHostile(string source, string target) + { + if (!_factions.TryGetValue(source, out var sourceFaction)) + { + _sawmill.Error($"Unable to find faction {source}"); + return; + } + + if (!_factions.ContainsKey(target)) + { + _sawmill.Error($"Unable to find faction {target}"); + return; + } + + sourceFaction.Friendly.Remove(target); + sourceFaction.Hostile.Add(target); + RefreshFactions(); + } + } +} diff --git a/Resources/Locale/en-US/ai/commands/faction-command.ftl b/Resources/Locale/en-US/ai/commands/faction-command.ftl deleted file mode 100644 index 164e7120da..0000000000 --- a/Resources/Locale/en-US/ai/commands/faction-command.ftl +++ /dev/null @@ -1,8 +0,0 @@ -faction-command-no-target-faction-error = Need to supply a target faction -faction-command-unknown-faction-argument-error = Unknown faction argument - -faction-command-description = Update / list factional relationships for NPCs. -faction-command-help-text = faction target - faction list: hostile factions -faction-command-invalid-faction-error = Invalid faction -faction-command-invalid-target-faction-error = Invalid target faction diff --git a/Resources/Locale/en-US/ai/medibot.ftl b/Resources/Locale/en-US/npc/medibot.ftl similarity index 100% rename from Resources/Locale/en-US/ai/medibot.ftl rename to Resources/Locale/en-US/npc/medibot.ftl diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 90c5ae7bca..52a50ea13d 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -143,7 +143,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Bloodstream @@ -668,7 +668,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - SimpleHostile @@ -1151,7 +1151,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - Syndicate - type: Sprite @@ -1309,7 +1309,7 @@ id: MobGiantSpiderAngry suffix: Angry components: - - type: AiFactionTag + - type: Faction factions: - Xeno - type: InputMover diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml index 42116cf970..f6ee14d2df 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml @@ -6,7 +6,7 @@ components: - type: InputMover - type: MobMover - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Sprite diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 58b20e0ce4..bbcaefdfe0 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -9,7 +9,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Sprite diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/human.yml b/Resources/Prototypes/Entities/Mobs/NPCs/human.yml index f10b8d3d75..6e4970f5d4 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/human.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/human.yml @@ -8,7 +8,7 @@ - type: MobMover - type: Loadout prototype: PassengerGear - - type: AiFactionTag + - type: Faction factions: - NanoTrasen @@ -18,7 +18,7 @@ id: MobSpirate description: Yarr! components: - - type: AiFactionTag + - type: Faction factions: - Syndicate - type: InputMover diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml index 5f97dd0882..ec93855a44 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml @@ -9,7 +9,7 @@ - FootstepSound - type: InputMover - type: MobMover - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Hands diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index ae3c4ba883..0c9dd8d7da 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -87,7 +87,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: InteractionPopup diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index ae120aa1d9..6067817821 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -14,7 +14,7 @@ groups: Flammable: [Touch] Extinguish: [Touch] - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Sprite @@ -177,7 +177,7 @@ groups: Flammable: [Touch] Extinguish: [Touch] - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Sprite diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index d2605294c3..191f563bc6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -39,7 +39,7 @@ netsync: false - type: Recyclable safe: false - - type: AiFactionTag + - type: Faction factions: - SimpleNeutral - type: HealthExaminable diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index b43bd82394..86b9e0d77d 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -18,7 +18,7 @@ rootTask: IdleCompound - type: Input context: "human" - - type: AiFactionTag + - type: Faction factions: - SimpleNeutral - type: MovementSpeedModifier diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml index f115fb6e53..8b64810700 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml @@ -6,7 +6,7 @@ components: - type: InputMover - type: MobMover - - type: AiFactionTag + - type: Faction factions: - SimpleHostile - type: Sprite diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index db501b4df4..bb30faab23 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -24,7 +24,7 @@ groups: Flammable: [Touch] Extinguish: [Touch] - - type: AiFactionTag + - type: Faction factions: - Xeno - type: Hands @@ -357,7 +357,7 @@ - type: MobMover - type: HTN rootTask: SimpleHostileCompound - - type: AiFactionTag + - type: Faction factions: - Xeno - type: MeleeWeapon diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index 519f1f480e..58cb92de1e 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -13,7 +13,7 @@ description: Call in 3 carp rifts and take over this quadrant! You have only 5 minutes in between each rift before you will disappear. - type: HTN rootTask: XenoCompound - - type: AiFactionTag + - type: Faction factions: - Dragon - type: Speech diff --git a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml index d0e71852b2..94adf12216 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dwarf.yml @@ -24,6 +24,6 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen diff --git a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml index 3c96d20542..eec08c43ca 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/familiars.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/familiars.yml @@ -50,7 +50,7 @@ Slash: 7 - type: InputMover - type: MobMover - - type: AiFactionTag + - type: Faction factions: - SimpleNeutral - type: InteractionPopup diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 414cfbf992..cc2f914a71 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -30,7 +30,7 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen diff --git a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml index dc4c827a84..9c5708be34 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/reptilian.yml @@ -25,7 +25,7 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen - type: Respirator diff --git a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml index 750e9b8a1e..f7633bef29 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/skeleton.yml @@ -23,6 +23,6 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen diff --git a/Resources/Prototypes/Entities/Mobs/Player/slime.yml b/Resources/Prototypes/Entities/Mobs/Player/slime.yml index 41bebf50d3..175bfe94fe 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/slime.yml @@ -22,6 +22,6 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen diff --git a/Resources/Prototypes/Entities/Mobs/Player/vox.yml b/Resources/Prototypes/Entities/Mobs/Player/vox.yml index ddf5bfbc68..75cc57cdca 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/vox.yml @@ -25,7 +25,7 @@ - type: CameraRecoil - type: Examiner - type: CanHostGuardian - - type: AiFactionTag + - type: Faction factions: - NanoTrasen - type: Respirator diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml index 2e1a6bbb65..3e70643aef 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml @@ -72,6 +72,6 @@ blackboard: SoundTargetInLOS: !type:SoundPathSpecifier path: /Audio/Effects/double_beep.ogg - - type: AiFactionTag + - type: Faction factions: - Syndicate diff --git a/Resources/Prototypes/ai_factions.yml b/Resources/Prototypes/ai_factions.yml index 9599aa1955..84c15c2e16 100644 --- a/Resources/Prototypes/ai_factions.yml +++ b/Resources/Prototypes/ai_factions.yml @@ -1,34 +1,34 @@ -- type: aiFaction +- type: faction id: Dragon hostile: - NanoTrasen - Syndicate - Xeno -- type: aiFaction +- type: faction id: NanoTrasen hostile: - SimpleHostile - Syndicate - Xeno -- type: aiFaction +- type: faction id: SimpleHostile hostile: - NanoTrasen - Syndicate -- type: aiFaction +- type: faction id: SimpleNeutral -- type: aiFaction +- type: faction id: Syndicate hostile: - NanoTrasen - SimpleHostile - Xeno -- type: aiFaction +- type: faction id: Xeno hostile: - NanoTrasen