]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
fix fish petting (#16094)
authordeltanedas <39013340+deltanedas@users.noreply.github.com>
Fri, 5 May 2023 13:03:46 +0000 (13:03 +0000)
committerGitHub <noreply@github.com>
Fri, 5 May 2023 13:03:46 +0000 (23:03 +1000)
Co-authored-by: deltanedas <@deltanedas:kde.org>
Content.Server/NPC/Systems/FactionSystem.cs

index a176ed149da4dc11af025a43c7ad38c5784a13a2..9445c7d6adc26a7b2dbf33aa63f3e2e10b2aa6b8 100644 (file)
-using System.Linq;
 using Content.Server.NPC.Components;
 using Robust.Shared.Prototypes;
+using System.Linq;
+
+namespace Content.Server.NPC.Systems;
 
-namespace Content.Server.NPC.Systems
+/// <summary>
+///     Outlines faction relationships with each other.
+/// </summary>
+public sealed class FactionSystem : EntitySystem
 {
+    [Dependency] private readonly FactionExceptionSystem _factionException = default!;
+    [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly IPrototypeManager _protoManager = default!;
+
+    private ISawmill _sawmill = default!;
+
     /// <summary>
-    ///     Outlines faction relationships with each other.
+    /// To avoid prototype mutability we store an intermediary data class that gets used instead.
     /// </summary>
-    public sealed class FactionSystem : EntitySystem
+    private Dictionary<string, FactionData> _factions = new();
+
+    public override void Initialize()
     {
-        [Dependency] private readonly IPrototypeManager _protoManager = default!;
-        [Dependency] private readonly EntityLookupSystem _lookup = default!;
+        base.Initialize();
+        _sawmill = Logger.GetSawmill("faction");
+        SubscribeLocalEvent<FactionComponent, ComponentStartup>(OnFactionStartup);
+        _protoManager.PrototypesReloaded += OnProtoReload;
+        RefreshFactions();
+    }
 
-        private ISawmill _sawmill = default!;
+    public override void Shutdown()
+    {
+        base.Shutdown();
+        _protoManager.PrototypesReloaded -= OnProtoReload;
+    }
 
-        /// <summary>
-        /// To avoid prototype mutability we store an intermediary data class that gets used instead.
-        /// </summary>
-        private Dictionary<string, FactionData> _factions = new();
+    private void OnProtoReload(PrototypesReloadedEventArgs obj)
+    {
+        if (!obj.ByType.ContainsKey(typeof(FactionPrototype)))
+            return;
 
-        public override void Initialize()
-        {
-            base.Initialize();
-            _sawmill = Logger.GetSawmill("faction");
-            SubscribeLocalEvent<FactionComponent, ComponentStartup>(OnFactionStartup);
-            _protoManager.PrototypesReloaded += OnProtoReload;
-            RefreshFactions();
-        }
+        RefreshFactions();
+    }
 
-        public override void Shutdown()
-        {
-            base.Shutdown();
-            _protoManager.PrototypesReloaded -= OnProtoReload;
-        }
+    private void OnFactionStartup(EntityUid uid, FactionComponent component, ComponentStartup args)
+    {
+        RefreshFactions(component);
+    }
 
-        private void OnProtoReload(PrototypesReloadedEventArgs obj)
+    /// <summary>
+    /// Refreshes the cached factions for this component.
+    /// </summary>
+    private void RefreshFactions(FactionComponent component)
+    {
+        component.FriendlyFactions.Clear();
+        component.HostileFactions.Clear();
+
+        foreach (var faction in component.Factions)
         {
-            if (!obj.ByType.ContainsKey(typeof(FactionPrototype)))
-                return;
+            // YAML Linter already yells about this
+            if (!_factions.TryGetValue(faction, out var factionData))
+                continue;
 
-            RefreshFactions();
+            component.FriendlyFactions.UnionWith(factionData.Friendly);
+            component.HostileFactions.UnionWith(factionData.Hostile);
         }
+    }
 
-        private void OnFactionStartup(EntityUid uid, FactionComponent component, ComponentStartup args)
+    /// <summary>
+    /// Adds this entity to the particular faction.
+    /// </summary>
+    public void AddFaction(EntityUid uid, string faction, bool dirty = true)
+    {
+        if (!_protoManager.HasIndex<FactionPrototype>(faction))
         {
-            RefreshFactions(component);
+            _sawmill.Error($"Unable to find faction {faction}");
+            return;
         }
 
-        /// <summary>
-        /// Refreshes the cached factions for this component.
-        /// </summary>
-        private void RefreshFactions(FactionComponent component)
-        {
-            component.FriendlyFactions.Clear();
-            component.HostileFactions.Clear();
+        var comp = EnsureComp<FactionComponent>(uid);
+        if (!comp.Factions.Add(faction))
+            return;
 
-            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);
-            }
+        if (dirty)
+        {
+            RefreshFactions(comp);
         }
+    }
 
-        /// <summary>
-        /// Adds this entity to the particular faction.
-        /// </summary>
-        public void AddFaction(EntityUid uid, string faction, bool dirty = true)
+    /// <summary>
+    /// Removes this entity from the particular faction.
+    /// </summary>
+    public void RemoveFaction(EntityUid uid, string faction, bool dirty = true)
+    {
+        if (!_protoManager.HasIndex<FactionPrototype>(faction))
         {
-            if (!_protoManager.HasIndex<FactionPrototype>(faction))
-            {
-                _sawmill.Error($"Unable to find faction {faction}");
-                return;
-            }
+            _sawmill.Error($"Unable to find faction {faction}");
+            return;
+        }
 
-            var comp = EnsureComp<FactionComponent>(uid);
-            if (!comp.Factions.Add(faction))
-                return;
+        if (!TryComp<FactionComponent>(uid, out var component))
+            return;
 
-            if (dirty)
-            {
-                RefreshFactions(comp);
-            }
-        }
+        if (!component.Factions.Remove(faction))
+            return;
 
-        /// <summary>
-        /// Removes this entity from the particular faction.
-        /// </summary>
-        public void RemoveFaction(EntityUid uid, string faction, bool dirty = true)
+        if (dirty)
         {
-            if (!_protoManager.HasIndex<FactionPrototype>(faction))
-            {
-                _sawmill.Error($"Unable to find faction {faction}");
-                return;
-            }
-
-            if (!TryComp<FactionComponent>(uid, out var component))
-                return;
+            RefreshFactions(component);
+        }
+    }
 
-            if (!component.Factions.Remove(faction))
-                return;
+    public IEnumerable<EntityUid> GetNearbyHostiles(EntityUid entity, float range, FactionComponent? component = null)
+    {
+        if (!Resolve(entity, ref component, false))
+            return Array.Empty<EntityUid>();
 
-            if (dirty)
-            {
-                RefreshFactions(component);
-            }
+        var hostiles = GetNearbyFactions(entity, range, component.HostileFactions);
+        if (TryComp<FactionExceptionComponent>(entity, out var factionException))
+        {
+            // ignore anything from enemy faction that we are explicitly friendly towards
+            return hostiles.Where(target => !_factionException.IsIgnored(factionException, target));
         }
 
-        public IEnumerable<EntityUid> GetNearbyHostiles(EntityUid entity, float range, FactionComponent? component = null)
-        {
-            if (!Resolve(entity, ref component, false))
-                return Array.Empty<EntityUid>();
+        return hostiles;
+    }
 
-            return GetNearbyFactions(entity, range, component.HostileFactions);
-        }
+    public IEnumerable<EntityUid> GetNearbyFriendlies(EntityUid entity, float range, FactionComponent? component = null)
+    {
+        if (!Resolve(entity, ref component, false))
+            return Array.Empty<EntityUid>();
 
-        public IEnumerable<EntityUid> GetNearbyFriendlies(EntityUid entity, float range, FactionComponent? component = null)
-        {
-            if (!Resolve(entity, ref component, false))
-                return Array.Empty<EntityUid>();
+        return GetNearbyFactions(entity, range, component.FriendlyFactions);
+    }
 
-            return GetNearbyFactions(entity, range, component.FriendlyFactions);
-        }
+    private IEnumerable<EntityUid> GetNearbyFactions(EntityUid entity, float range, HashSet<string> factions)
+    {
+        var xformQuery = GetEntityQuery<TransformComponent>();
 
-        private IEnumerable<EntityUid> GetNearbyFactions(EntityUid entity, float range, HashSet<string> factions)
+        if (!xformQuery.TryGetComponent(entity, out var entityXform))
+            yield break;
+
+        foreach (var comp in _lookup.GetComponentsInRange<FactionComponent>(entityXform.MapPosition, range))
         {
-            var xformQuery = GetEntityQuery<TransformComponent>();
+            if (comp.Owner == entity)
+                continue;
 
-            if (!xformQuery.TryGetComponent(entity, out var entityXform))
-                yield break;
+            if (!factions.Overlaps(comp.Factions))
+                continue;
 
-            foreach (var comp in _lookup.GetComponentsInRange<FactionComponent>(entityXform.MapPosition, range))
-            {
-                if (comp.Owner == entity)
-                    continue;
+            yield return comp.Owner;
+        }
+    }
 
-                if (!factions.Overlaps(comp.Factions))
-                    continue;
+    public bool IsFriendly(EntityUid uidA, EntityUid uidB, FactionComponent? factionA = null, FactionComponent? factionB = null)
+    {
+        if (!Resolve(uidA, ref factionA, false) || !Resolve(uidB, ref factionB, false))
+            return false;
 
-                yield return comp.Owner;
-            }
-        }
+        return factionA.Factions.Overlaps(factionB.Factions) || factionA.FriendlyFactions.Overlaps(factionB.Factions);
+    }
 
-        public bool IsFriendly(EntityUid uidA, EntityUid uidB, FactionComponent? factionA = null, FactionComponent? factionB = null)
+    /// <summary>
+    /// Makes the source faction friendly to the target faction, 1-way.
+    /// </summary>
+    public void MakeFriendly(string source, string target)
+    {
+        if (!_factions.TryGetValue(source, out var sourceFaction))
         {
-            if (!Resolve(uidA, ref factionA, false) || !Resolve(uidB, ref factionB, false))
-                return false;
-
-            return factionA.Factions.Overlaps(factionB.Factions) || factionA.FriendlyFactions.Overlaps(factionB.Factions);
+            _sawmill.Error($"Unable to find faction {source}");
+            return;
         }
 
-        /// <summary>
-        /// Makes the source faction friendly to the target faction, 1-way.
-        /// </summary>
-        public void MakeFriendly(string source, string target)
+        if (!_factions.ContainsKey(target))
         {
-            if (!_factions.TryGetValue(source, out var sourceFaction))
-            {
-                _sawmill.Error($"Unable to find faction {source}");
-                return;
-            }
+            _sawmill.Error($"Unable to find faction {target}");
+            return;
+        }
 
-            if (!_factions.ContainsKey(target))
-            {
-                _sawmill.Error($"Unable to find faction {target}");
-                return;
-            }
+        sourceFaction.Friendly.Add(target);
+        sourceFaction.Hostile.Remove(target);
+        RefreshFactions();
+    }
 
-            sourceFaction.Friendly.Add(target);
-            sourceFaction.Hostile.Remove(target);
-            RefreshFactions();
-        }
+    private void RefreshFactions()
+    {
+        _factions.Clear();
 
-        private void RefreshFactions()
+        foreach (var faction in _protoManager.EnumeratePrototypes<FactionPrototype>())
         {
-            _factions.Clear();
-
-            foreach (var faction in _protoManager.EnumeratePrototypes<FactionPrototype>())
-            {
-                _factions[faction.ID] = new FactionData()
-                {
-                    Friendly = faction.Friendly.ToHashSet(),
-                    Hostile = faction.Hostile.ToHashSet(),
-                };
-            }
-
-            foreach (var comp in EntityQuery<FactionComponent>(true))
+            _factions[faction.ID] = new FactionData()
             {
-                comp.FriendlyFactions.Clear();
-                comp.HostileFactions.Clear();
-                RefreshFactions(comp);
-            }
+                Friendly = faction.Friendly.ToHashSet(),
+                Hostile = faction.Hostile.ToHashSet(),
+            };
         }
 
-        /// <summary>
-        /// Makes the source faction hostile to the target faction, 1-way.
-        /// </summary>
-        public void MakeHostile(string source, string target)
+        foreach (var comp in EntityQuery<FactionComponent>(true))
         {
-            if (!_factions.TryGetValue(source, out var sourceFaction))
-            {
-                _sawmill.Error($"Unable to find faction {source}");
-                return;
-            }
+            comp.FriendlyFactions.Clear();
+            comp.HostileFactions.Clear();
+            RefreshFactions(comp);
+        }
+    }
 
-            if (!_factions.ContainsKey(target))
-            {
-                _sawmill.Error($"Unable to find faction {target}");
-                return;
-            }
+    /// <summary>
+    /// Makes the source faction hostile to the target faction, 1-way.
+    /// </summary>
+    public void MakeHostile(string source, string target)
+    {
+        if (!_factions.TryGetValue(source, out var sourceFaction))
+        {
+            _sawmill.Error($"Unable to find faction {source}");
+            return;
+        }
 
-            sourceFaction.Friendly.Remove(target);
-            sourceFaction.Hostile.Add(target);
-            RefreshFactions();
+        if (!_factions.ContainsKey(target))
+        {
+            _sawmill.Error($"Unable to find faction {target}");
+            return;
         }
+
+        sourceFaction.Friendly.Remove(target);
+        sourceFaction.Hostile.Add(target);
+        RefreshFactions();
     }
 }
+