From 1ca9328c15bab6d457ea00e398c4d81dad1e2b06 Mon Sep 17 00:00:00 2001
From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Fri, 5 May 2023 13:03:46 +0000
Subject: [PATCH] fix fish petting (#16094)
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
Content.Server/NPC/Systems/FactionSystem.cs | 334 ++++++++++----------
1 file changed, 171 insertions(+), 163 deletions(-)
diff --git a/Content.Server/NPC/Systems/FactionSystem.cs b/Content.Server/NPC/Systems/FactionSystem.cs
index a176ed149d..9445c7d6ad 100644
--- a/Content.Server/NPC/Systems/FactionSystem.cs
+++ b/Content.Server/NPC/Systems/FactionSystem.cs
@@ -1,221 +1,229 @@
-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
+///
+/// Outlines faction relationships with each other.
+///
+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!;
+
///
- /// Outlines faction relationships with each other.
+ /// To avoid prototype mutability we store an intermediary data class that gets used instead.
///
- public sealed class FactionSystem : EntitySystem
+ private Dictionary _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(OnFactionStartup);
+ _protoManager.PrototypesReloaded += OnProtoReload;
+ RefreshFactions();
+ }
- private ISawmill _sawmill = default!;
+ public override void Shutdown()
+ {
+ base.Shutdown();
+ _protoManager.PrototypesReloaded -= OnProtoReload;
+ }
- ///
- /// To avoid prototype mutability we store an intermediary data class that gets used instead.
- ///
- private Dictionary _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(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)
+ ///
+ /// Refreshes the cached factions for this component.
+ ///
+ 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)
+ ///
+ /// Adds this entity to the particular faction.
+ ///
+ public void AddFaction(EntityUid uid, string faction, bool dirty = true)
+ {
+ if (!_protoManager.HasIndex(faction))
{
- RefreshFactions(component);
+ _sawmill.Error($"Unable to find faction {faction}");
+ return;
}
- ///
- /// Refreshes the cached factions for this component.
- ///
- private void RefreshFactions(FactionComponent component)
- {
- component.FriendlyFactions.Clear();
- component.HostileFactions.Clear();
+ var comp = EnsureComp(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);
}
+ }
- ///
- /// Adds this entity to the particular faction.
- ///
- public void AddFaction(EntityUid uid, string faction, bool dirty = true)
+ ///
+ /// Removes this entity from the particular faction.
+ ///
+ public void RemoveFaction(EntityUid uid, string faction, bool dirty = true)
+ {
+ if (!_protoManager.HasIndex(faction))
{
- if (!_protoManager.HasIndex(faction))
- {
- _sawmill.Error($"Unable to find faction {faction}");
- return;
- }
+ _sawmill.Error($"Unable to find faction {faction}");
+ return;
+ }
- var comp = EnsureComp(uid);
- if (!comp.Factions.Add(faction))
- return;
+ if (!TryComp(uid, out var component))
+ return;
- if (dirty)
- {
- RefreshFactions(comp);
- }
- }
+ if (!component.Factions.Remove(faction))
+ return;
- ///
- /// Removes this entity from the particular faction.
- ///
- public void RemoveFaction(EntityUid uid, string faction, bool dirty = true)
+ if (dirty)
{
- if (!_protoManager.HasIndex(faction))
- {
- _sawmill.Error($"Unable to find faction {faction}");
- return;
- }
-
- if (!TryComp(uid, out var component))
- return;
+ RefreshFactions(component);
+ }
+ }
- if (!component.Factions.Remove(faction))
- return;
+ public IEnumerable GetNearbyHostiles(EntityUid entity, float range, FactionComponent? component = null)
+ {
+ if (!Resolve(entity, ref component, false))
+ return Array.Empty();
- if (dirty)
- {
- RefreshFactions(component);
- }
+ var hostiles = GetNearbyFactions(entity, range, component.HostileFactions);
+ if (TryComp(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 GetNearbyHostiles(EntityUid entity, float range, FactionComponent? component = null)
- {
- if (!Resolve(entity, ref component, false))
- return Array.Empty();
+ return hostiles;
+ }
- 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();
- 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);
+ }
- return GetNearbyFactions(entity, range, component.FriendlyFactions);
- }
+ private IEnumerable GetNearbyFactions(EntityUid entity, float range, HashSet factions)
+ {
+ var xformQuery = GetEntityQuery();
- private IEnumerable GetNearbyFactions(EntityUid entity, float range, HashSet factions)
+ if (!xformQuery.TryGetComponent(entity, out var entityXform))
+ yield break;
+
+ foreach (var comp in _lookup.GetComponentsInRange(entityXform.MapPosition, range))
{
- var xformQuery = GetEntityQuery();
+ 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(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)
+ ///
+ /// 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))
{
- 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;
}
- ///
- /// Makes the source faction friendly to the target faction, 1-way.
- ///
- 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())
{
- _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))
+ _factions[faction.ID] = new FactionData()
{
- comp.FriendlyFactions.Clear();
- comp.HostileFactions.Clear();
- RefreshFactions(comp);
- }
+ Friendly = faction.Friendly.ToHashSet(),
+ Hostile = faction.Hostile.ToHashSet(),
+ };
}
- ///
- /// Makes the source faction hostile to the target faction, 1-way.
- ///
- public void MakeHostile(string source, string target)
+ foreach (var comp in EntityQuery(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;
- }
+ ///
+ /// 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;
+ }
- 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();
}
}
+
--
2.51.2