Use ECS prototype-reload events (#22613)
* Use ECS prototype-reload events * better constructors * Maybe this fixes tests?
This commit is contained in:
@@ -67,7 +67,7 @@ public sealed partial class ContentAudioSystem
|
|||||||
_nextAudio = TimeSpan.MaxValue;
|
_nextAudio = TimeSpan.MaxValue;
|
||||||
|
|
||||||
SetupAmbientSounds();
|
SetupAmbientSounds();
|
||||||
_proto.PrototypesReloaded += OnProtoReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||||
_state.OnStateChanged += OnStateChange;
|
_state.OnStateChanged += OnStateChange;
|
||||||
// On round end summary OR lobby cut audio.
|
// On round end summary OR lobby cut audio.
|
||||||
SubscribeNetworkEvent<RoundEndMessageEvent>(OnRoundEndMessage);
|
SubscribeNetworkEvent<RoundEndMessageEvent>(OnRoundEndMessage);
|
||||||
@@ -86,21 +86,14 @@ public sealed partial class ContentAudioSystem
|
|||||||
private void ShutdownAmbientMusic()
|
private void ShutdownAmbientMusic()
|
||||||
{
|
{
|
||||||
_configManager.UnsubValueChanged(CCVars.AmbientMusicVolume, AmbienceCVarChanged);
|
_configManager.UnsubValueChanged(CCVars.AmbientMusicVolume, AmbienceCVarChanged);
|
||||||
_proto.PrototypesReloaded -= OnProtoReload;
|
|
||||||
_state.OnStateChanged -= OnStateChange;
|
_state.OnStateChanged -= OnStateChange;
|
||||||
_ambientMusicStream = _audio.Stop(_ambientMusicStream);
|
_ambientMusicStream = _audio.Stop(_ambientMusicStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!obj.ByType.ContainsKey(typeof(AmbientMusicPrototype)) &&
|
if (obj.WasModified<AmbientMusicPrototype>() || obj.WasModified<RulesPrototype>())
|
||||||
!obj.ByType.ContainsKey(typeof(RulesPrototype)))
|
SetupAmbientSounds();
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ambientSounds.Clear();
|
|
||||||
SetupAmbientSounds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStateChange(StateChangedEventArgs obj)
|
private void OnStateChange(StateChangedEventArgs obj)
|
||||||
@@ -114,6 +107,7 @@ public sealed partial class ContentAudioSystem
|
|||||||
|
|
||||||
private void SetupAmbientSounds()
|
private void SetupAmbientSounds()
|
||||||
{
|
{
|
||||||
|
_ambientSounds.Clear();
|
||||||
foreach (var ambience in _proto.EnumeratePrototypes<AmbientMusicPrototype>())
|
foreach (var ambience in _proto.EnumeratePrototypes<AmbientMusicPrototype>())
|
||||||
{
|
{
|
||||||
var tracks = _ambientSounds.GetOrNew(ambience.ID);
|
var tracks = _ambientSounds.GetOrNew(ambience.ID);
|
||||||
|
|||||||
@@ -29,18 +29,13 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
|||||||
SubscribeLocalEvent<ChameleonClothingComponent, AfterAutoHandleStateEvent>(HandleState);
|
SubscribeLocalEvent<ChameleonClothingComponent, AfterAutoHandleStateEvent>(HandleState);
|
||||||
|
|
||||||
PrepareAllVariants();
|
PrepareAllVariants();
|
||||||
_proto.PrototypesReloaded += OnProtoReloaded;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReloaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
private void OnProtoReloaded(PrototypesReloadedEventArgs args)
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
if (args.WasModified<EntityPrototype>())
|
||||||
_proto.PrototypesReloaded -= OnProtoReloaded;
|
PrepareAllVariants();
|
||||||
}
|
|
||||||
|
|
||||||
private void OnProtoReloaded(PrototypesReloadedEventArgs _)
|
|
||||||
{
|
|
||||||
PrepareAllVariants();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleState(EntityUid uid, ChameleonClothingComponent component, ref AfterAutoHandleStateEvent args)
|
private void HandleState(EntityUid uid, ChameleonClothingComponent component, ref AfterAutoHandleStateEvent args)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Content.Client.GameTicking.Managers;
|
|
||||||
using Content.Shared.CrewManifest;
|
using Content.Shared.CrewManifest;
|
||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -19,12 +18,7 @@ public sealed class CrewManifestSystem : EntitySystem
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
BuildDepartmentLookup();
|
BuildDepartmentLookup();
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypesReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReload);
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypesReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -36,16 +30,16 @@ public sealed class CrewManifestSystem : EntitySystem
|
|||||||
RaiseNetworkEvent(new RequestCrewManifestMessage(netEntity));
|
RaiseNetworkEvent(new RequestCrewManifestMessage(netEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPrototypesReload(PrototypesReloadedEventArgs _)
|
private void OnPrototypesReload(PrototypesReloadedEventArgs args)
|
||||||
{
|
{
|
||||||
_jobDepartmentLookup.Clear();
|
if (args.WasModified<DepartmentPrototype>())
|
||||||
_departments.Clear();
|
BuildDepartmentLookup();
|
||||||
|
|
||||||
BuildDepartmentLookup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildDepartmentLookup()
|
private void BuildDepartmentLookup()
|
||||||
{
|
{
|
||||||
|
_jobDepartmentLookup.Clear();
|
||||||
|
_departments.Clear();
|
||||||
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||||
{
|
{
|
||||||
_departments.Add(department.ID);
|
_departments.Add(department.ID);
|
||||||
|
|||||||
@@ -24,14 +24,13 @@ public sealed class ParallaxSystem : SharedParallaxSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_overlay.AddOverlay(new ParallaxOverlay());
|
_overlay.AddOverlay(new ParallaxOverlay());
|
||||||
_protoManager.PrototypesReloaded += OnReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnReload);
|
||||||
|
|
||||||
SubscribeLocalEvent<ParallaxComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
|
SubscribeLocalEvent<ParallaxComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnReload(PrototypesReloadedEventArgs obj)
|
private void OnReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!obj.ByType.ContainsKey(typeof(ParallaxPrototype)))
|
if (!obj.WasModified<ParallaxPrototype>())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_parallax.UnloadParallax(Fallback);
|
_parallax.UnloadParallax(Fallback);
|
||||||
@@ -48,7 +47,6 @@ public sealed class ParallaxSystem : SharedParallaxSystem
|
|||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
_overlay.RemoveOverlay<ParallaxOverlay>();
|
_overlay.RemoveOverlay<ParallaxOverlay>();
|
||||||
_protoManager.PrototypesReloaded -= OnReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAfterAutoHandleState(EntityUid uid, ParallaxComponent component, ref AfterAutoHandleStateEvent args)
|
private void OnAfterAutoHandleState(EntityUid uid, ParallaxComponent component, ref AfterAutoHandleStateEvent args)
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ public sealed class DecalPlacerUIController : UIController, IOnStateExited<Gamep
|
|||||||
|
|
||||||
private void OnPrototypesReloaded(PrototypesReloadedEventArgs obj)
|
private void OnPrototypesReloaded(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
ReloadPrototypes();
|
if (obj.WasModified<DecalPrototype>())
|
||||||
|
ReloadPrototypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReloadPrototypes()
|
private void ReloadPrototypes()
|
||||||
|
|||||||
@@ -23,15 +23,7 @@ public sealed class AlertLevelSystem : EntitySystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<StationInitializedEvent>(OnStationInitialize);
|
SubscribeLocalEvent<StationInitializedEvent>(OnStationInitialize);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypeReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypeReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float time)
|
public override void Update(float time)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Content.Shared.Audio;
|
|||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Robust.Server.Audio;
|
using Robust.Server.Audio;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Components;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Audio;
|
namespace Content.Server.Audio;
|
||||||
@@ -11,14 +10,13 @@ namespace Content.Server.Audio;
|
|||||||
public sealed class ContentAudioSystem : SharedContentAudioSystem
|
public sealed class ContentAudioSystem : SharedContentAudioSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly AudioSystem _serverAudio = default!;
|
[Dependency] private readonly AudioSystem _serverAudio = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||||
_protoManager.PrototypesReloaded += OnProtoReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRoundCleanup(RoundRestartCleanupEvent ev)
|
private void OnRoundCleanup(RoundRestartCleanupEvent ev)
|
||||||
@@ -28,16 +26,8 @@ public sealed class ContentAudioSystem : SharedContentAudioSystem
|
|||||||
|
|
||||||
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!obj.ByType.ContainsKey(typeof(AudioPresetPrototype)))
|
if (obj.WasModified<AudioPresetPrototype>())
|
||||||
return;
|
_serverAudio.ReloadPresets();
|
||||||
|
|
||||||
_serverAudio.ReloadPresets();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_protoManager.PrototypesReloaded -= OnProtoReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRoundStart(RoundStartingEvent ev)
|
private void OnRoundStart(RoundStartingEvent ev)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using Content.Shared.Chat.Prototypes;
|
using Content.Shared.Chat.Prototypes;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -7,44 +8,36 @@ namespace Content.Server.Chat.Systems;
|
|||||||
// emotes using emote prototype
|
// emotes using emote prototype
|
||||||
public partial class ChatSystem
|
public partial class ChatSystem
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, EmotePrototype> _wordEmoteDict = new();
|
private FrozenDictionary<string, EmotePrototype> _wordEmoteDict = FrozenDictionary<string, EmotePrototype>.Empty;
|
||||||
|
|
||||||
private void InitializeEmotes()
|
protected override void OnPrototypeReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypeReloadEmotes;
|
base.OnPrototypeReload(obj);
|
||||||
CacheEmotes();
|
if (obj.WasModified<EmotePrototype>())
|
||||||
}
|
CacheEmotes();
|
||||||
|
|
||||||
private void ShutdownEmotes()
|
|
||||||
{
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypeReloadEmotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPrototypeReloadEmotes(PrototypesReloadedEventArgs obj)
|
|
||||||
{
|
|
||||||
CacheEmotes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheEmotes()
|
private void CacheEmotes()
|
||||||
{
|
{
|
||||||
_wordEmoteDict.Clear();
|
var dict = new Dictionary<string, EmotePrototype>();
|
||||||
var emotes = _prototypeManager.EnumeratePrototypes<EmotePrototype>();
|
var emotes = _prototypeManager.EnumeratePrototypes<EmotePrototype>();
|
||||||
foreach (var emote in emotes)
|
foreach (var emote in emotes)
|
||||||
{
|
{
|
||||||
foreach (var word in emote.ChatTriggers)
|
foreach (var word in emote.ChatTriggers)
|
||||||
{
|
{
|
||||||
var lowerWord = word.ToLower();
|
var lowerWord = word.ToLower();
|
||||||
if (_wordEmoteDict.ContainsKey(lowerWord))
|
if (dict.TryGetValue(lowerWord, out var value))
|
||||||
{
|
{
|
||||||
var existingId = _wordEmoteDict[lowerWord].ID;
|
var errMsg = $"Duplicate of emote word {lowerWord} in emotes {emote.ID} and {value.ID}";
|
||||||
var errMsg = $"Duplicate of emote word {lowerWord} in emotes {emote.ID} and {existingId}";
|
Log.Error(errMsg);
|
||||||
Logger.Error(errMsg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_wordEmoteDict.Add(lowerWord, emote);
|
dict.Add(lowerWord, emote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_wordEmoteDict = dict.ToFrozenDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
InitializeEmotes();
|
CacheEmotes();
|
||||||
_configurationManager.OnValueChanged(CCVars.LoocEnabled, OnLoocEnabledChanged, true);
|
_configurationManager.OnValueChanged(CCVars.LoocEnabled, OnLoocEnabledChanged, true);
|
||||||
_configurationManager.OnValueChanged(CCVars.DeadLoocEnabled, OnDeadLoocEnabledChanged, true);
|
_configurationManager.OnValueChanged(CCVars.DeadLoocEnabled, OnDeadLoocEnabledChanged, true);
|
||||||
_configurationManager.OnValueChanged(CCVars.CritLoocEnabled, OnCritLoocEnabledChanged, true);
|
_configurationManager.OnValueChanged(CCVars.CritLoocEnabled, OnCritLoocEnabledChanged, true);
|
||||||
@@ -80,7 +80,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
ShutdownEmotes();
|
|
||||||
_configurationManager.UnsubValueChanged(CCVars.LoocEnabled, OnLoocEnabledChanged);
|
_configurationManager.UnsubValueChanged(CCVars.LoocEnabled, OnLoocEnabledChanged);
|
||||||
_configurationManager.UnsubValueChanged(CCVars.DeadLoocEnabled, OnDeadLoocEnabledChanged);
|
_configurationManager.UnsubValueChanged(CCVars.DeadLoocEnabled, OnDeadLoocEnabledChanged);
|
||||||
_configurationManager.UnsubValueChanged(CCVars.CritLoocEnabled, OnCritLoocEnabledChanged);
|
_configurationManager.UnsubValueChanged(CCVars.CritLoocEnabled, OnCritLoocEnabledChanged);
|
||||||
@@ -736,7 +735,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
|
|
||||||
return ev.Message;
|
return ev.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckIgnoreSpeechBlocker(EntityUid sender, bool ignoreBlocker)
|
public bool CheckIgnoreSpeechBlocker(EntityUid sender, bool ignoreBlocker)
|
||||||
{
|
{
|
||||||
if (ignoreBlocker)
|
if (ignoreBlocker)
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ public sealed class ChemistryGuideDataSystem : SharedChemistryGuideDataSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
PrototypeManager.PrototypesReloaded += PrototypeManagerReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(PrototypeManagerReload);
|
||||||
|
|
||||||
_player.PlayerStatusChanged += OnPlayerStatusChanged;
|
_player.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||||
|
|
||||||
InitializeServerRegistry();
|
InitializeServerRegistry();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public sealed class RandomGiftSystem : EntitySystem
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_prototype.PrototypesReloaded += OnPrototypesReloaded;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
||||||
SubscribeLocalEvent<RandomGiftComponent, MapInitEvent>(OnGiftMapInit);
|
SubscribeLocalEvent<RandomGiftComponent, MapInitEvent>(OnGiftMapInit);
|
||||||
SubscribeLocalEvent<RandomGiftComponent, UseInHandEvent>(OnUseInHand);
|
SubscribeLocalEvent<RandomGiftComponent, UseInHandEvent>(OnUseInHand);
|
||||||
SubscribeLocalEvent<RandomGiftComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<RandomGiftComponent, ExaminedEvent>(OnExamined);
|
||||||
@@ -80,7 +80,8 @@ public sealed class RandomGiftSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnPrototypesReloaded(PrototypesReloadedEventArgs obj)
|
private void OnPrototypesReloaded(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
BuildIndex();
|
if (obj.WasModified<EntityPrototype>())
|
||||||
|
BuildIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildIndex()
|
private void BuildIndex()
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using Content.Shared.Administration;
|
|||||||
using Content.Shared.Mobs;
|
using Content.Shared.Mobs;
|
||||||
using Content.Shared.NPC;
|
using Content.Shared.NPC;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -38,8 +37,7 @@ public sealed class HTNSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<HTNComponent, PlayerDetachedEvent>(_npc.OnPlayerNPCDetach);
|
SubscribeLocalEvent<HTNComponent, PlayerDetachedEvent>(_npc.OnPlayerNPCDetach);
|
||||||
SubscribeLocalEvent<HTNComponent, ComponentShutdown>(OnHTNShutdown);
|
SubscribeLocalEvent<HTNComponent, ComponentShutdown>(OnHTNShutdown);
|
||||||
SubscribeNetworkEvent<RequestHTNMessage>(OnHTNMessage);
|
SubscribeNetworkEvent<RequestHTNMessage>(OnHTNMessage);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeLoad);
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypeLoad;
|
|
||||||
OnLoad();
|
OnLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,12 +55,6 @@ public sealed class HTNSystem : EntitySystem
|
|||||||
_subscribers.Remove(args.SenderSession);
|
_subscribers.Remove(args.SenderSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypeLoad;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLoad()
|
private void OnLoad()
|
||||||
{
|
{
|
||||||
// Clear all NPCs in case they're hanging onto stale tasks
|
// Clear all NPCs in case they're hanging onto stale tasks
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.NPC.Components;
|
using Content.Server.NPC.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -18,31 +19,23 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// To avoid prototype mutability we store an intermediary data class that gets used instead.
|
/// To avoid prototype mutability we store an intermediary data class that gets used instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<string, FactionData> _factions = new();
|
private FrozenDictionary<string, FactionData> _factions = FrozenDictionary<string, FactionData>.Empty;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_sawmill = Logger.GetSawmill("faction");
|
_sawmill = Logger.GetSawmill("faction");
|
||||||
SubscribeLocalEvent<NpcFactionMemberComponent, ComponentStartup>(OnFactionStartup);
|
SubscribeLocalEvent<NpcFactionMemberComponent, ComponentStartup>(OnFactionStartup);
|
||||||
_protoManager.PrototypesReloaded += OnProtoReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||||
|
|
||||||
InitializeException();
|
InitializeException();
|
||||||
RefreshFactions();
|
RefreshFactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_protoManager.PrototypesReloaded -= OnProtoReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!obj.ByType.ContainsKey(typeof(NpcFactionPrototype)))
|
if (obj.WasModified<NpcFactionPrototype>())
|
||||||
return;
|
RefreshFactions();
|
||||||
|
|
||||||
RefreshFactions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFactionStartup(EntityUid uid, NpcFactionMemberComponent memberComponent, ComponentStartup args)
|
private void OnFactionStartup(EntityUid uid, NpcFactionMemberComponent memberComponent, ComponentStartup args)
|
||||||
@@ -237,16 +230,15 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||||||
|
|
||||||
private void RefreshFactions()
|
private void RefreshFactions()
|
||||||
{
|
{
|
||||||
_factions.Clear();
|
|
||||||
|
|
||||||
foreach (var faction in _protoManager.EnumeratePrototypes<NpcFactionPrototype>())
|
_factions = _protoManager.EnumeratePrototypes<NpcFactionPrototype>().ToFrozenDictionary(
|
||||||
{
|
faction => faction.ID,
|
||||||
_factions[faction.ID] = new FactionData()
|
faction => new FactionData
|
||||||
{
|
{
|
||||||
Friendly = faction.Friendly.ToHashSet(),
|
Friendly = faction.Friendly.ToHashSet(),
|
||||||
Hostile = faction.Hostile.ToHashSet(),
|
Hostile = faction.Hostile.ToHashSet()
|
||||||
};
|
|
||||||
}
|
});
|
||||||
|
|
||||||
foreach (var comp in EntityQuery<NpcFactionMemberComponent>(true))
|
foreach (var comp in EntityQuery<NpcFactionMemberComponent>(true))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ public sealed class NameIdentifierSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<NameIdentifierComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<NameIdentifierComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<NameIdentifierComponent, ComponentShutdown>(OnComponentShutdown);
|
SubscribeLocalEvent<NameIdentifierComponent, ComponentShutdown>(OnComponentShutdown);
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(CleanupIds);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(CleanupIds);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnReloadPrototypes);
|
||||||
|
|
||||||
InitialSetupPrototypes();
|
InitialSetupPrototypes();
|
||||||
_prototypeManager.PrototypesReloaded += OnReloadPrototypes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnComponentShutdown(EntityUid uid, NameIdentifierComponent component, ComponentShutdown args)
|
private void OnComponentShutdown(EntityUid uid, NameIdentifierComponent component, ComponentShutdown args)
|
||||||
@@ -46,13 +46,6 @@ public sealed class NameIdentifierSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnReloadPrototypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a new unique name/suffix for a given entity and adds it to <see cref="CurrentIds"/>
|
/// Generates a new unique name/suffix for a given entity and adds it to <see cref="CurrentIds"/>
|
||||||
/// but does not set the entity's name.
|
/// but does not set the entity's name.
|
||||||
|
|||||||
@@ -85,14 +85,13 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
||||||
_configManager.OnValueChanged(CVars.NetMaxUpdateRange, SetLoadRange, true);
|
_configManager.OnValueChanged(CVars.NetMaxUpdateRange, SetLoadRange, true);
|
||||||
InitializeCommands();
|
InitializeCommands();
|
||||||
ProtoManager.PrototypesReloaded += ProtoReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(ProtoReload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
_configManager.UnsubValueChanged(CVars.NetMaxUpdateRange, SetLoadRange);
|
_configManager.UnsubValueChanged(CVars.NetMaxUpdateRange, SetLoadRange);
|
||||||
ProtoManager.PrototypesReloaded -= ProtoReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProtoReload(PrototypesReloadedEventArgs obj)
|
private void ProtoReload(PrototypesReloadedEventArgs obj)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
|||||||
_console.RegisterCommand("dungen", Loc.GetString("cmd-dungen-desc"), Loc.GetString("cmd-dungen-help"), GenerateDungeon, CompletionCallback);
|
_console.RegisterCommand("dungen", Loc.GetString("cmd-dungen-desc"), Loc.GetString("cmd-dungen-help"), GenerateDungeon, CompletionCallback);
|
||||||
_console.RegisterCommand("dungen_preset_vis", Loc.GetString("cmd-dungen_preset_vis-desc"), Loc.GetString("cmd-dungen_preset_vis-help"), DungeonPresetVis, PresetCallback);
|
_console.RegisterCommand("dungen_preset_vis", Loc.GetString("cmd-dungen_preset_vis-desc"), Loc.GetString("cmd-dungen_preset_vis-help"), DungeonPresetVis, PresetCallback);
|
||||||
_console.RegisterCommand("dungen_pack_vis", Loc.GetString("cmd-dungen_pack_vis-desc"), Loc.GetString("cmd-dungen_pack_vis-help"), DungeonPackVis, PackCallback);
|
_console.RegisterCommand("dungen_pack_vis", Loc.GetString("cmd-dungen_pack_vis-desc"), Loc.GetString("cmd-dungen_pack_vis-help"), DungeonPackVis, PackCallback);
|
||||||
_prototype.PrototypesReloaded += PrototypeReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(PrototypeReload);
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundCleanup);
|
||||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||||
}
|
}
|
||||||
@@ -91,8 +91,6 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
|||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
_prototype.PrototypesReloaded -= PrototypeReload;
|
|
||||||
|
|
||||||
foreach (var token in _dungeonJobs.Values)
|
foreach (var token in _dungeonJobs.Values)
|
||||||
{
|
{
|
||||||
token.Cancel();
|
token.Cancel();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public sealed class SpreaderSystem : EntitySystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remaining number of updates per grid & prototype.
|
/// Remaining number of updates per grid & prototype.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
// TODO PERFORMANCE Assign each prototype to an index and convert dictionary to array
|
||||||
private Dictionary<EntityUid, Dictionary<string, int>> _gridUpdates = new();
|
private Dictionary<EntityUid, Dictionary<string, int>> _gridUpdates = new();
|
||||||
|
|
||||||
public const float SpreadCooldownSeconds = 1;
|
public const float SpreadCooldownSeconds = 1;
|
||||||
@@ -42,24 +43,16 @@ public sealed class SpreaderSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
SubscribeLocalEvent<AirtightChanged>(OnAirtightChanged);
|
SubscribeLocalEvent<AirtightChanged>(OnAirtightChanged);
|
||||||
SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
|
SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
|
||||||
|
|
||||||
SubscribeLocalEvent<EdgeSpreaderComponent, EntityTerminatingEvent>(OnTerminating);
|
SubscribeLocalEvent<EdgeSpreaderComponent, EntityTerminatingEvent>(OnTerminating);
|
||||||
SetupPrototypes();
|
SetupPrototypes();
|
||||||
_prototype.PrototypesReloaded += OnPrototypeReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_prototype.PrototypesReloaded -= OnPrototypeReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPrototypeReload(PrototypesReloadedEventArgs obj)
|
private void OnPrototypeReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (!obj.ByType.ContainsKey(typeof(EdgeSpreaderPrototype)))
|
if (obj.WasModified<EdgeSpreaderPrototype>())
|
||||||
return;
|
SetupPrototypes();
|
||||||
|
|
||||||
SetupPrototypes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupPrototypes()
|
private void SetupPrototypes()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -7,7 +8,8 @@ namespace Content.Shared.Alert;
|
|||||||
public abstract class AlertsSystem : EntitySystem
|
public abstract class AlertsSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
private readonly Dictionary<AlertType, AlertPrototype> _typeToAlert = new();
|
|
||||||
|
private FrozenDictionary<AlertType, AlertPrototype> _typeToAlert = default!;
|
||||||
|
|
||||||
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(EntityUid euid)
|
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(EntityUid euid)
|
||||||
{
|
{
|
||||||
@@ -170,9 +172,8 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
||||||
|
|
||||||
SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert);
|
SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(HandlePrototypesReloaded);
|
||||||
LoadPrototypes();
|
LoadPrototypes();
|
||||||
_prototypeManager.PrototypesReloaded += HandlePrototypesReloaded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args)
|
protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args)
|
||||||
@@ -185,29 +186,25 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
RaiseLocalEvent(uid, new AlertSyncEvent(uid), true);
|
RaiseLocalEvent(uid, new AlertSyncEvent(uid), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
_prototypeManager.PrototypesReloaded -= HandlePrototypesReloaded;
|
|
||||||
|
|
||||||
base.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandlePrototypesReloaded(PrototypesReloadedEventArgs obj)
|
private void HandlePrototypesReloaded(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
LoadPrototypes();
|
if (obj.WasModified<AlertPrototype>())
|
||||||
|
LoadPrototypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void LoadPrototypes()
|
protected virtual void LoadPrototypes()
|
||||||
{
|
{
|
||||||
_typeToAlert.Clear();
|
var dict = new Dictionary<AlertType, AlertPrototype>();
|
||||||
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
||||||
{
|
{
|
||||||
if (!_typeToAlert.TryAdd(alert.AlertType, alert))
|
if (!dict.TryAdd(alert.AlertType, alert))
|
||||||
{
|
{
|
||||||
Log.Error("Found alert with duplicate alertType {0} - all alerts must have" +
|
Log.Error("Found alert with duplicate alertType {0} - all alerts must have" +
|
||||||
" a unique alerttype, this one will be skipped", alert.AlertType);
|
" a unique alerttype, this one will be skipped", alert.AlertType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_typeToAlert = dict.ToFrozenDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Radio;
|
using Content.Shared.Radio;
|
||||||
using Content.Shared.Speech;
|
using Content.Shared.Speech;
|
||||||
@@ -36,35 +37,26 @@ public abstract class SharedChatSystem : EntitySystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cache of the keycodes for faster lookup.
|
/// Cache of the keycodes for faster lookup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<char, RadioChannelPrototype> _keyCodes = new();
|
private FrozenDictionary<char, RadioChannelPrototype> _keyCodes = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
DebugTools.Assert(_prototypeManager.HasIndex<RadioChannelPrototype>(CommonChannel));
|
DebugTools.Assert(_prototypeManager.HasIndex<RadioChannelPrototype>(CommonChannel));
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypeReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
|
||||||
CacheRadios();
|
CacheRadios();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPrototypeReload(PrototypesReloadedEventArgs obj)
|
protected virtual void OnPrototypeReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
if (obj.ByType.ContainsKey(typeof(RadioChannelPrototype)))
|
if (obj.WasModified<RadioChannelPrototype>())
|
||||||
CacheRadios();
|
CacheRadios();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheRadios()
|
private void CacheRadios()
|
||||||
{
|
{
|
||||||
_keyCodes.Clear();
|
_keyCodes = _prototypeManager.EnumeratePrototypes<RadioChannelPrototype>()
|
||||||
|
.ToFrozenDictionary(x => x.KeyCode);
|
||||||
foreach (var proto in _prototypeManager.EnumeratePrototypes<RadioChannelPrototype>())
|
|
||||||
{
|
|
||||||
_keyCodes.Add(proto.KeyCode, proto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypeReload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.Administration.Logs;
|
using Content.Shared.Administration.Logs;
|
||||||
using Content.Shared.Chemistry.Components;
|
using Content.Shared.Chemistry.Components;
|
||||||
@@ -7,6 +8,7 @@ using Content.Shared.FixedPoint;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Chemistry.Reaction
|
namespace Content.Shared.Chemistry.Reaction
|
||||||
{
|
{
|
||||||
@@ -22,23 +24,22 @@ namespace Content.Shared.Chemistry.Reaction
|
|||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A cache of all existant chemical reactions indexed by one of their
|
/// A cache of all reactions indexed by at most ONE of their required reactants.
|
||||||
/// required reactants.
|
/// I.e., even if a reaction has more than one reagent, it will only ever appear once in this dictionary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IDictionary<string, List<ReactionPrototype>> _reactions = default!;
|
private FrozenDictionary<string, List<ReactionPrototype>> _reactionsSingle = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A cache of all reactions indexed by one of their required reactants.
|
||||||
|
/// </summary>
|
||||||
|
private FrozenDictionary<string, List<ReactionPrototype>> _reactions = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
InitializeReactionCache();
|
InitializeReactionCache();
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypesReloaded;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_prototypeManager.PrototypesReloaded -= OnPrototypesReloaded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -46,34 +47,27 @@ namespace Content.Shared.Chemistry.Reaction
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InitializeReactionCache()
|
private void InitializeReactionCache()
|
||||||
{
|
{
|
||||||
_reactions = new Dictionary<string, List<ReactionPrototype>>();
|
// Construct single-reaction dictionary.
|
||||||
|
var dict = new Dictionary<string, List<ReactionPrototype>>();
|
||||||
var reactions = _prototypeManager.EnumeratePrototypes<ReactionPrototype>();
|
foreach(var reaction in _prototypeManager.EnumeratePrototypes<ReactionPrototype>())
|
||||||
foreach(var reaction in reactions)
|
|
||||||
{
|
{
|
||||||
CacheReaction(reaction);
|
// For this dictionary we only need to cache based on the first reagent.
|
||||||
|
var reagent = reaction.Reactants.Keys.First();
|
||||||
|
var list = dict.GetOrNew(reagent);
|
||||||
|
list.Add(reaction);
|
||||||
}
|
}
|
||||||
}
|
_reactionsSingle = dict.ToFrozenDictionary();
|
||||||
|
|
||||||
/// <summary>
|
dict.Clear();
|
||||||
/// Caches a reaction by its first required reagent.
|
foreach(var reaction in _prototypeManager.EnumeratePrototypes<ReactionPrototype>())
|
||||||
/// Used to build the reaction cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reaction">A reaction prototype to cache.</param>
|
|
||||||
private void CacheReaction(ReactionPrototype reaction)
|
|
||||||
{
|
|
||||||
var reagents = reaction.Reactants.Keys;
|
|
||||||
foreach(var reagent in reagents)
|
|
||||||
{
|
{
|
||||||
if(!_reactions.TryGetValue(reagent, out var cache))
|
foreach (var reagent in reaction.Reactants.Keys)
|
||||||
{
|
{
|
||||||
cache = new List<ReactionPrototype>();
|
var list = dict.GetOrNew(reagent);
|
||||||
_reactions.Add(reagent, cache);
|
list.Add(reaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.Add(reaction);
|
|
||||||
return; // Only need to cache based on the first reagent.
|
|
||||||
}
|
}
|
||||||
|
_reactions = dict.ToFrozenDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -82,20 +76,8 @@ namespace Content.Shared.Chemistry.Reaction
|
|||||||
/// <param name="eventArgs">The set of modified prototypes.</param>
|
/// <param name="eventArgs">The set of modified prototypes.</param>
|
||||||
private void OnPrototypesReloaded(PrototypesReloadedEventArgs eventArgs)
|
private void OnPrototypesReloaded(PrototypesReloadedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (!eventArgs.ByType.TryGetValue(typeof(ReactionPrototype), out var set))
|
if (eventArgs.WasModified<ReactionPrototype>())
|
||||||
return;
|
InitializeReactionCache();
|
||||||
|
|
||||||
foreach (var (reactant, cache) in _reactions)
|
|
||||||
{
|
|
||||||
cache.RemoveAll((reaction) => set.Modified.ContainsKey(reaction.ID));
|
|
||||||
if (cache.Count == 0)
|
|
||||||
_reactions.Remove(reactant);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var prototype in set.Modified.Values)
|
|
||||||
{
|
|
||||||
CacheReaction((ReactionPrototype) prototype);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -285,7 +267,7 @@ namespace Content.Shared.Chemistry.Reaction
|
|||||||
SortedSet<ReactionPrototype> reactions = new();
|
SortedSet<ReactionPrototype> reactions = new();
|
||||||
foreach (var reactant in solution.Contents)
|
foreach (var reactant in solution.Contents)
|
||||||
{
|
{
|
||||||
if (_reactions.TryGetValue(reactant.Reagent.Prototype, out var reactantReactions))
|
if (_reactionsSingle.TryGetValue(reactant.Reagent.Prototype, out var reactantReactions))
|
||||||
reactions.UnionWith(reactantReactions);
|
reactions.UnionWith(reactantReactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +279,7 @@ namespace Content.Shared.Chemistry.Reaction
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Error($"{nameof(Solution)} {owner} could not finish reacting in under {MaxReactionIterations} loops.");
|
Log.Error($"{nameof(Solution)} {owner} could not finish reacting in under {MaxReactionIterations} loops.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ namespace Content.Shared.Entry
|
|||||||
|
|
||||||
private void PrototypeReload(PrototypesReloadedEventArgs obj)
|
private void PrototypeReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
|
if (!obj.WasModified<ContentTileDefinition>())
|
||||||
|
return;
|
||||||
|
|
||||||
// Need to re-allocate tiledefs due to how prototype reloads work
|
// Need to re-allocate tiledefs due to how prototype reloads work
|
||||||
foreach (var def in _prototypeManager.EnumeratePrototypes<ContentTileDefinition>())
|
foreach (var def in _prototypeManager.EnumeratePrototypes<ContentTileDefinition>())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
using System.Collections.Frozen;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
using Content.Shared.Humanoid.Prototypes;
|
using Content.Shared.Humanoid.Prototypes;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
@@ -9,33 +11,41 @@ namespace Content.Shared.Humanoid.Markings
|
|||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
private readonly List<MarkingPrototype> _index = new();
|
private readonly List<MarkingPrototype> _index = new();
|
||||||
private readonly Dictionary<MarkingCategories, Dictionary<string, MarkingPrototype>> _markingDict = new();
|
public FrozenDictionary<MarkingCategories, FrozenDictionary<string, MarkingPrototype>> CategorizedMarkings = default!;
|
||||||
private readonly Dictionary<string, MarkingPrototype> _markings = new();
|
public FrozenDictionary<string, MarkingPrototype> Markings = default!;
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_prototypeManager.PrototypesReloaded += OnPrototypeReload;
|
_prototypeManager.PrototypesReloaded += OnPrototypeReload;
|
||||||
|
CachePrototypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CachePrototypes()
|
||||||
|
{
|
||||||
|
_index.Clear();
|
||||||
|
var markingDict = new Dictionary<MarkingCategories, Dictionary<string, MarkingPrototype>>();
|
||||||
|
|
||||||
foreach (var category in Enum.GetValues<MarkingCategories>())
|
foreach (var category in Enum.GetValues<MarkingCategories>())
|
||||||
{
|
{
|
||||||
_markingDict.Add(category, new Dictionary<string, MarkingPrototype>());
|
markingDict.Add(category, new());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var prototype in _prototypeManager.EnumeratePrototypes<MarkingPrototype>())
|
foreach (var prototype in _prototypeManager.EnumeratePrototypes<MarkingPrototype>())
|
||||||
{
|
{
|
||||||
_index.Add(prototype);
|
_index.Add(prototype);
|
||||||
_markingDict[prototype.MarkingCategory].Add(prototype.ID, prototype);
|
markingDict[prototype.MarkingCategory].Add(prototype.ID, prototype);
|
||||||
_markings.Add(prototype.ID, prototype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Markings = _prototypeManager.EnumeratePrototypes<MarkingPrototype>().ToFrozenDictionary(x => x.ID);
|
||||||
|
CategorizedMarkings = markingDict.ToFrozenDictionary(
|
||||||
|
x => x.Key,
|
||||||
|
x => x.Value.ToFrozenDictionary());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, MarkingPrototype> Markings => _markings;
|
public FrozenDictionary<string, MarkingPrototype> MarkingsByCategory(MarkingCategories category)
|
||||||
public IReadOnlyDictionary<MarkingCategories, Dictionary<string, MarkingPrototype>> CategorizedMarkings => _markingDict;
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, MarkingPrototype> MarkingsByCategory(MarkingCategories category)
|
|
||||||
{
|
{
|
||||||
// all marking categories are guaranteed to have a dict entry
|
// all marking categories are guaranteed to have a dict entry
|
||||||
return _markingDict[category];
|
return CategorizedMarkings[category];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -143,7 +153,7 @@ namespace Content.Shared.Humanoid.Markings
|
|||||||
|
|
||||||
public bool TryGetMarking(Marking marking, [NotNullWhen(true)] out MarkingPrototype? markingResult)
|
public bool TryGetMarking(Marking marking, [NotNullWhen(true)] out MarkingPrototype? markingResult)
|
||||||
{
|
{
|
||||||
return _markings.TryGetValue(marking.MarkingId, out markingResult);
|
return Markings.TryGetValue(marking.MarkingId, out markingResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -178,17 +188,8 @@ namespace Content.Shared.Humanoid.Markings
|
|||||||
|
|
||||||
private void OnPrototypeReload(PrototypesReloadedEventArgs args)
|
private void OnPrototypeReload(PrototypesReloadedEventArgs args)
|
||||||
{
|
{
|
||||||
if(!args.ByType.TryGetValue(typeof(MarkingPrototype), out var set))
|
if (args.WasModified<MarkingPrototype>())
|
||||||
return;
|
CachePrototypes();
|
||||||
|
|
||||||
|
|
||||||
_index.RemoveAll(i => set.Modified.ContainsKey(i.ID));
|
|
||||||
|
|
||||||
foreach (var prototype in set.Modified.Values)
|
|
||||||
{
|
|
||||||
var markingPrototype = (MarkingPrototype) prototype;
|
|
||||||
_index.Add(markingPrototype);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanBeApplied(string species, Sex sex, Marking marking, IPrototypeManager? prototypeManager = null)
|
public bool CanBeApplied(string species, Sex sex, Marking marking, IPrototypeManager? prototypeManager = null)
|
||||||
|
|||||||
@@ -22,19 +22,14 @@ public abstract class SharedJobSystem : EntitySystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_protoManager.PrototypesReloaded += OnProtoReload;
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||||
SetupTrackerLookup();
|
SetupTrackerLookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
_protoManager.PrototypesReloaded -= OnProtoReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
private void OnProtoReload(PrototypesReloadedEventArgs obj)
|
||||||
{
|
{
|
||||||
SetupTrackerLookup();
|
if (obj.WasModified<JobPrototype>())
|
||||||
|
SetupTrackerLookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupTrackerLookup()
|
private void SetupTrackerLookup()
|
||||||
|
|||||||
Reference in New Issue
Block a user