From 177d69cb983a4257532e6c1e6a8bfe4647953e78 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 17 Apr 2024 19:10:53 +1000 Subject: [PATCH 001/170] Update submodule to 218.2.0 (#27041) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index a6e7224672..1901059755 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit a6e7224672402c36f0b61d7c082427b4ff31250e +Subproject commit 19010597553d15f5ca239497ac66eab876ecc720 From 2db374988c91c6ce5f932b9cee1ba251cbfb22e5 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 17 Apr 2024 19:27:00 +1000 Subject: [PATCH 002/170] Added Jukebox (#26736) * Added Jukebox, along with music for jukebox * Fixed Jukebox meta.json copyright * Removed songs I couldn't find a license for. * Renamed files to solve check failures from spaces * Added missing attributions.yml * Fixed lack of description in Jukebox * Jukebox is now constructable. * Change Jukebox menu to FancyWindow * Moved Jukebox messages out of jukebox component * Removed Jukebox OnValueChanged. * JukeboxComp now uses AutoGenerateComponentState * Removed state code, since it's auto generated * Fixed various Jukebox code to match conventions. * Updated Standard.yml to match changed song list. * fixes * Jukebox workin * Fix * Polishing * Finalising * Revert * bad * jukey * Reviews * name * Update submodule to 218.2.0 --------- Co-authored-by: iNVERTED --- .../Jukebox/JukeboxBoundUserInterface.cs | 119 +++++++++++++ Content.Client/Audio/Jukebox/JukeboxMenu.xaml | 18 ++ .../Audio/Jukebox/JukeboxMenu.xaml.cs | 166 ++++++++++++++++++ Content.Client/Audio/Jukebox/JukeboxSystem.cs | 153 ++++++++++++++++ Content.Server/Audio/Jukebox/JukeboxSystem.cs | 152 ++++++++++++++++ .../Audio/Jukebox/JukeboxComponent.cs | 80 +++++++++ .../Audio/Jukebox/JukeboxPrototype.cs | 23 +++ Content.Shared/Audio/Jukebox/JukeboxUi.cs | 11 ++ .../Audio/Jukebox/SharedJukeboxSystem.cs | 8 + Resources/Audio/Jukebox/attributions.yml | 22 +++ Resources/Audio/Jukebox/constellations.ogg | Bin 0 -> 848147 bytes Resources/Audio/Jukebox/drifting.ogg | Bin 0 -> 915591 bytes Resources/Audio/Jukebox/flip-flap.ogg | Bin 0 -> 1522765 bytes Resources/Audio/Jukebox/sector11.ogg | Bin 0 -> 2118480 bytes Resources/Audio/Jukebox/starlight.ogg | Bin 0 -> 1575072 bytes Resources/Audio/Jukebox/title3.ogg | Bin 0 -> 2240764 bytes .../Locale/en-US/jukebox/jukebox-menu.ftl | 5 + .../Prototypes/Catalog/Jukebox/Standard.yml | 35 ++++ .../Circuitboards/Machine/production.yml | 16 +- .../Entities/Structures/Machines/jukebox.yml | 59 +++++++ .../Entities/Structures/Machines/lathe.yml | 1 + .../Prototypes/Recipes/Lathes/electronics.yml | 8 + .../Prototypes/Research/civilianservices.yml | 1 + .../Structures/Machines/jukebox.rsi/meta.json | 31 ++++ .../Structures/Machines/jukebox.rsi/off.png | Bin 0 -> 770 bytes .../Structures/Machines/jukebox.rsi/on.png | Bin 0 -> 673 bytes .../Machines/jukebox.rsi/select.png | Bin 0 -> 1339 bytes 27 files changed, 907 insertions(+), 1 deletion(-) create mode 100644 Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs create mode 100644 Content.Client/Audio/Jukebox/JukeboxMenu.xaml create mode 100644 Content.Client/Audio/Jukebox/JukeboxMenu.xaml.cs create mode 100644 Content.Client/Audio/Jukebox/JukeboxSystem.cs create mode 100644 Content.Server/Audio/Jukebox/JukeboxSystem.cs create mode 100644 Content.Shared/Audio/Jukebox/JukeboxComponent.cs create mode 100644 Content.Shared/Audio/Jukebox/JukeboxPrototype.cs create mode 100644 Content.Shared/Audio/Jukebox/JukeboxUi.cs create mode 100644 Content.Shared/Audio/Jukebox/SharedJukeboxSystem.cs create mode 100644 Resources/Audio/Jukebox/attributions.yml create mode 100644 Resources/Audio/Jukebox/constellations.ogg create mode 100644 Resources/Audio/Jukebox/drifting.ogg create mode 100644 Resources/Audio/Jukebox/flip-flap.ogg create mode 100644 Resources/Audio/Jukebox/sector11.ogg create mode 100644 Resources/Audio/Jukebox/starlight.ogg create mode 100644 Resources/Audio/Jukebox/title3.ogg create mode 100644 Resources/Locale/en-US/jukebox/jukebox-menu.ftl create mode 100644 Resources/Prototypes/Catalog/Jukebox/Standard.yml create mode 100644 Resources/Prototypes/Entities/Structures/Machines/jukebox.yml create mode 100644 Resources/Textures/Structures/Machines/jukebox.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/jukebox.rsi/off.png create mode 100644 Resources/Textures/Structures/Machines/jukebox.rsi/on.png create mode 100644 Resources/Textures/Structures/Machines/jukebox.rsi/select.png diff --git a/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs new file mode 100644 index 0000000000..072730d65d --- /dev/null +++ b/Content.Client/Audio/Jukebox/JukeboxBoundUserInterface.cs @@ -0,0 +1,119 @@ +using Content.Shared.Audio.Jukebox; +using Robust.Client.Audio; +using Robust.Client.Player; +using Robust.Shared.Audio.Components; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; + +namespace Content.Client.Audio.Jukebox; + +public sealed class JukeboxBoundUserInterface : BoundUserInterface +{ + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + + [ViewVariables] + private JukeboxMenu? _menu; + + public JukeboxBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + IoCManager.InjectDependencies(this); + } + + protected override void Open() + { + base.Open(); + + _menu = new JukeboxMenu(); + _menu.OnClose += Close; + _menu.OpenCentered(); + + _menu.OnPlayPressed += args => + { + if (args) + { + SendMessage(new JukeboxPlayingMessage()); + } + else + { + SendMessage(new JukeboxPauseMessage()); + } + }; + + _menu.OnStopPressed += () => + { + SendMessage(new JukeboxStopMessage()); + }; + + _menu.OnSongSelected += SelectSong; + + _menu.SetTime += SetTime; + PopulateMusic(); + Reload(); + } + + /// + /// Reloads the attached menu if it exists. + /// + public void Reload() + { + if (_menu == null || !EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox)) + return; + + _menu.SetAudioStream(jukebox.AudioStream); + + if (_protoManager.TryIndex(jukebox.SelectedSongId, out var songProto)) + { + var length = EntMan.System().GetAudioLength(songProto.Path.Path.ToString()); + _menu.SetSelectedSong(songProto.Name, (float) length.TotalSeconds); + } + else + { + _menu.SetSelectedSong(string.Empty, 0f); + } + } + + public void PopulateMusic() + { + _menu?.Populate(_protoManager.EnumeratePrototypes()); + } + + public void SelectSong(ProtoId songid) + { + SendMessage(new JukeboxSelectedMessage(songid)); + } + + public void SetTime(float time) + { + var sentTime = time; + + // You may be wondering, what the fuck is this + // Well we want to be able to predict the playback slider change, of which there are many ways to do it + // We can't just use SendPredictedMessage because it will reset every tick and audio updates every frame + // so it will go BRRRRT + // Using ping gets us close enough that it SHOULD, MOST OF THE TIME, fall within the 0.1 second tolerance + // that's still on engine so our playback position never gets corrected. + if (EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox) && + EntMan.TryGetComponent(jukebox.AudioStream, out AudioComponent? audioComp)) + { + audioComp.PlaybackPosition = time; + } + + SendMessage(new JukeboxSetTimeMessage(sentTime)); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + if (_menu == null) + return; + + _menu.OnClose -= Close; + _menu.Dispose(); + _menu = null; + } +} + diff --git a/Content.Client/Audio/Jukebox/JukeboxMenu.xaml b/Content.Client/Audio/Jukebox/JukeboxMenu.xaml new file mode 100644 index 0000000000..e8d39a9b11 --- /dev/null +++ b/Content.Client/Audio/Jukebox/JukeboxMenu.xaml @@ -0,0 +1,18 @@ + + + + + + + + Text="{Loc 'analysis-console-server-list-button'}"> + + + + + @@ -36,13 +52,13 @@ - + - + diff --git a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs index 90732f814f..2acf35da25 100644 --- a/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs +++ b/Content.Client/Xenoarchaeology/Ui/AnalysisConsoleMenu.xaml.cs @@ -3,6 +3,7 @@ using Content.Client.UserInterface.Controls; using Content.Shared.Xenoarchaeology.Equipment; using Robust.Client.AutoGenerated; using Robust.Client.GameObjects; +using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -19,6 +20,8 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow public event Action? OnScanButtonPressed; public event Action? OnPrintButtonPressed; public event Action? OnExtractButtonPressed; + public event Action? OnUpBiasButtonPressed; + public event Action? OnDownBiasButtonPressed; // For rendering the progress bar, updated from BUI state private TimeSpan? _startTime; @@ -36,6 +39,12 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow ScanButton.OnPressed += _ => OnScanButtonPressed?.Invoke(); PrintButton.OnPressed += _ => OnPrintButtonPressed?.Invoke(); ExtractButton.OnPressed += _ => OnExtractButtonPressed?.Invoke(); + UpBiasButton.OnPressed += _ => OnUpBiasButtonPressed?.Invoke(); + DownBiasButton.OnPressed += _ => OnDownBiasButtonPressed?.Invoke(); + + var buttonGroup = new ButtonGroup(false); + UpBiasButton.Group = buttonGroup; + DownBiasButton.Group = buttonGroup; } protected override void FrameUpdate(FrameEventArgs args) @@ -60,7 +69,7 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow ProgressBar.Value = Math.Clamp(1.0f - (float) remaining.Divide(total), 0.0f, 1.0f); } - public void SetButtonsDisabled(AnalysisConsoleScanUpdateState state) + public void SetButtonsDisabled(AnalysisConsoleUpdateState state) { ScanButton.Disabled = !state.CanScan; PrintButton.Disabled = !state.CanPrint; @@ -78,7 +87,6 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow ExtractButton.AddStyleClass("ButtonColorGreen"); } } - private void UpdateArtifactIcon(EntityUid? uid) { if (uid == null) @@ -91,7 +99,7 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow ArtifactDisplay.SetEntity(uid); } - public void UpdateInformationDisplay(AnalysisConsoleScanUpdateState state) + public void UpdateInformationDisplay(AnalysisConsoleUpdateState state) { var message = new FormattedMessage(); @@ -129,7 +137,7 @@ public sealed partial class AnalysisConsoleMenu : FancyWindow Information.SetMessage(message); } - public void UpdateProgressBar(AnalysisConsoleScanUpdateState state) + public void UpdateProgressBar(AnalysisConsoleUpdateState state) { ProgressBar.Visible = state.Scanning; ProgressLabel.Visible = state.Scanning; diff --git a/Content.Server/Xenoarchaeology/Equipment/Components/TraversalDistorterComponent.cs b/Content.Server/Xenoarchaeology/Equipment/Components/TraversalDistorterComponent.cs index ec16083c53..fe95114f73 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Components/TraversalDistorterComponent.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Components/TraversalDistorterComponent.cs @@ -8,7 +8,7 @@ public sealed partial class TraversalDistorterComponent : Component { [ViewVariables(VVAccess.ReadWrite)] - public BiasDirection BiasDirection = BiasDirection.In; + public BiasDirection BiasDirection = BiasDirection.Up; public TimeSpan NextActivation = default!; public TimeSpan ActivationDelay = TimeSpan.FromSeconds(1); @@ -16,6 +16,6 @@ public sealed partial class TraversalDistorterComponent : Component public enum BiasDirection : byte { - In, //down the tree, towards depth 0 - Out //up the tree, away from depth 0 + Up, //Towards depth 0 + Down, //Away from depth 0 } diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs index 51906313a3..2e546dd200 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactAnalyzerSystem.cs @@ -40,6 +40,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem [Dependency] private readonly PaperSystem _paper = default!; [Dependency] private readonly ResearchSystem _research = default!; [Dependency] private readonly MetaDataSystem _metaSystem = default!; + [Dependency] private readonly TraversalDistorterSystem _traversalDistorter = default!; /// public override void Initialize() @@ -61,6 +62,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem SubscribeLocalEvent(OnScanButton); SubscribeLocalEvent(OnPrintButton); SubscribeLocalEvent(OnExtractButton); + SubscribeLocalEvent(OnBiasButton); SubscribeLocalEvent((e, c, _) => UpdateUserInterface(e, c), after: new[] { typeof(ResearchSystem) }); @@ -192,6 +194,7 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem var canScan = false; var canPrint = false; var points = 0; + if (TryComp(component.AnalyzerEntity, out var analyzer)) { artifact = analyzer.LastAnalyzedArtifact; @@ -205,15 +208,20 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem if (GetArtifactForAnalysis(component.AnalyzerEntity, placer) is { } current) points = _artifact.GetResearchPointValue(current); } + var analyzerConnected = component.AnalyzerEntity != null; var serverConnected = TryComp(uid, out var client) && client.ConnectedToServer; var scanning = TryComp(component.AnalyzerEntity, out var active); var paused = active != null ? active.AnalysisPaused : false; + var biasDirection = BiasDirection.Up; - var state = new AnalysisConsoleScanUpdateState(GetNetEntity(artifact), analyzerConnected, serverConnected, - canScan, canPrint, msg, scanning, paused, active?.StartTime, active?.AccumulatedRunTime, totalTime, points); + if (TryComp(component.AnalyzerEntity, out var trav)) + biasDirection = trav.BiasDirection; + + var state = new AnalysisConsoleUpdateState(GetNetEntity(artifact), analyzerConnected, serverConnected, + canScan, canPrint, msg, scanning, paused, active?.StartTime, active?.AccumulatedRunTime, totalTime, points, biasDirection == BiasDirection.Down); var bui = _ui.GetUi(uid, ArtifactAnalzyerUiKey.Key); _ui.SetUiState(bui, state); @@ -372,6 +380,20 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem UpdateUserInterface(uid, component); } + private void OnBiasButton(EntityUid uid, AnalysisConsoleComponent component, AnalysisConsoleBiasButtonPressedMessage args) + { + if (component.AnalyzerEntity == null) + return; + + if (!TryComp(component.AnalyzerEntity, out var trav)) + return; + + if (!_traversalDistorter.SetState(component.AnalyzerEntity.Value, trav, args.IsDown)) + return; + + UpdateUserInterface(uid, component); + } + /// /// Cancels scans if the artifact changes nodes (is activated) during the scan. /// diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/TraversalDistorterSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/TraversalDistorterSystem.cs index 230e639af4..2092f79f05 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/TraversalDistorterSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/TraversalDistorterSystem.cs @@ -17,8 +17,6 @@ public sealed class TraversalDistorterSystem : EntitySystem public override void Initialize() { SubscribeLocalEvent(OnInit); - - SubscribeLocalEvent(OnInteract); SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnItemPlaced); @@ -30,30 +28,25 @@ public sealed class TraversalDistorterSystem : EntitySystem component.NextActivation = _timing.CurTime; } - private void OnInteract(EntityUid uid, TraversalDistorterComponent component, ActivateInWorldEvent args) + /// + /// Switches the state of the traversal distorter between up and down. + /// + /// The distorter's entity + /// The component on the entity + /// If the distorter changed state + public bool SetState(EntityUid uid, TraversalDistorterComponent component, bool isDown) { - if (args.Handled || !this.IsPowered(uid, EntityManager)) - return; + if (!this.IsPowered(uid, EntityManager)) + return false; + if (_timing.CurTime < component.NextActivation) - return; - args.Handled = true; + return false; + component.NextActivation = _timing.CurTime + component.ActivationDelay; - component.BiasDirection = component.BiasDirection == BiasDirection.In - ? BiasDirection.Out - : BiasDirection.In; + component.BiasDirection = isDown ? BiasDirection.Down : BiasDirection.Up; - var toPopup = string.Empty; - switch (component.BiasDirection) - { - case BiasDirection.In: - toPopup = Loc.GetString("traversal-distorter-set-in"); - break; - case BiasDirection.Out: - toPopup = Loc.GetString("traversal-distorter-set-out"); - break; - } - _popup.PopupEntity(toPopup, uid); + return true; } private void OnExamine(EntityUid uid, TraversalDistorterComponent component, ExaminedEvent args) @@ -61,11 +54,11 @@ public sealed class TraversalDistorterSystem : EntitySystem string examine = string.Empty; switch (component.BiasDirection) { - case BiasDirection.In: - examine = Loc.GetString("traversal-distorter-desc-in"); + case BiasDirection.Up: + examine = Loc.GetString("traversal-distorter-desc-up"); break; - case BiasDirection.Out: - examine = Loc.GetString("traversal-distorter-desc-out"); + case BiasDirection.Down: + examine = Loc.GetString("traversal-distorter-desc-down"); break; } diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Nodes.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Nodes.cs index 647f31a895..895bb0217b 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Nodes.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Nodes.cs @@ -19,26 +19,46 @@ public sealed partial class ArtifactSystem /// /// /// - /// The amount of nodes it has. - private void GenerateArtifactNodeTree(EntityUid artifact, ref List allNodes, int nodeAmount) + /// The amount of nodes it has. + private void GenerateArtifactNodeTree(EntityUid artifact, List allNodes, int nodesToCreate) { - if (nodeAmount < 1) + if (nodesToCreate < 1) { - Log.Error($"nodeAmount {nodeAmount} is less than 1. Aborting artifact tree generation."); + Log.Error($"nodesToCreate {nodesToCreate} is less than 1. Aborting artifact tree generation."); return; } _usedNodeIds.Clear(); + var uninitializedNodes = new List { new(){ Id = GetValidNodeId() } }; + var createdNodes = 1; - var rootNode = new ArtifactNode + while (uninitializedNodes.Count > 0) { - Id = GetValidNodeId() - }; - var uninitializedNodes = new List { rootNode }; - while (uninitializedNodes.Any()) - { - GenerateNode(artifact, ref uninitializedNodes, ref allNodes, nodeAmount); + var node = uninitializedNodes[0]; + uninitializedNodes.Remove(node); + + node.Trigger = GetRandomTrigger(artifact, ref node); + node.Effect = GetRandomEffect(artifact, ref node); + + var maxChildren = _random.Next(1, MaxEdgesPerNode - 1); + + for (var i = 0; i < maxChildren; i++) + { + if (nodesToCreate <= createdNodes) + { + break; + } + + var child = new ArtifactNode {Id = GetValidNodeId(), Depth = node.Depth + 1}; + node.Edges.Add(child.Id); + child.Edges.Add(node.Id); + + uninitializedNodes.Add(child); + createdNodes++; + } + + allNodes.Add(node); } } @@ -51,46 +71,10 @@ public sealed partial class ArtifactSystem } _usedNodeIds.Add(id); + return id; } - /// - /// Generate an individual node on the tree. - /// - private void GenerateNode(EntityUid artifact, ref List uninitializedNodes, ref List allNodes, int targetNodeAmount) - { - if (!uninitializedNodes.Any()) - return; - - var node = uninitializedNodes.First(); - uninitializedNodes.Remove(node); - - //Generate the connected nodes - var maxEdges = Math.Max(1, targetNodeAmount - allNodes.Count - uninitializedNodes.Count - 1); - maxEdges = Math.Min(maxEdges, MaxEdgesPerNode); - var minEdges = Math.Clamp(targetNodeAmount - allNodes.Count - uninitializedNodes.Count - 1, 0, 1); - - var edgeAmount = _random.Next(minEdges, maxEdges); - - for (var i = 0; i < edgeAmount; i++) - { - var neighbor = new ArtifactNode - { - Depth = node.Depth + 1, - Id = GetValidNodeId() - }; - node.Edges.Add(neighbor.Id); - neighbor.Edges.Add(node.Id); - - uninitializedNodes.Add(neighbor); - } - - node.Trigger = GetRandomTrigger(artifact, ref node); - node.Effect = GetRandomEffect(artifact, ref node); - - allNodes.Add(node); - } - //yeah these two functions are near duplicates but i don't //want to implement an interface or abstract parent @@ -159,6 +143,7 @@ public sealed partial class ArtifactSystem return key; } } + return _random.Pick(weights.Keys); //shouldn't happen } diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs index 955fe827d7..a5469e93dc 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs @@ -129,7 +129,7 @@ public sealed partial class ArtifactSystem : EntitySystem { var nodeAmount = _random.Next(component.NodesMin, component.NodesMax); - GenerateArtifactNodeTree(uid, ref component.NodeTree, nodeAmount); + GenerateArtifactNodeTree(uid, component.NodeTree, nodeAmount); var firstNode = GetRootNode(component.NodeTree); EnterNode(uid, ref firstNode, component); } @@ -184,13 +184,14 @@ public sealed partial class ArtifactSystem : EntitySystem var currentNode = GetNodeFromId(component.CurrentNodeId.Value, component); currentNode.Triggered = true; - if (currentNode.Edges.Any()) - { - var newNode = GetNewNode(uid, component); - if (newNode == null) - return; - EnterNode(uid, ref newNode, component); - } + if (currentNode.Edges.Count == 0) + return; + + var newNode = GetNewNode(uid, component); + if (newNode == null) + return; + + EnterNode(uid, ref newNode, component); } private ArtifactNode? GetNewNode(EntityUid uid, ArtifactComponent component) @@ -210,15 +211,15 @@ public sealed partial class ArtifactSystem : EntitySystem { switch (trav.BiasDirection) { - case BiasDirection.In: - var foo = allNodes.Where(x => GetNodeFromId(x, component).Depth < currentNode.Depth).ToHashSet(); - if (foo.Any()) - allNodes = foo; + case BiasDirection.Up: + var upNodes = allNodes.Where(x => GetNodeFromId(x, component).Depth < currentNode.Depth).ToHashSet(); + if (upNodes.Count != 0) + allNodes = upNodes; break; - case BiasDirection.Out: - var bar = allNodes.Where(x => GetNodeFromId(x, component).Depth > currentNode.Depth).ToHashSet(); - if (bar.Any()) - allNodes = bar; + case BiasDirection.Down: + var downNodes = allNodes.Where(x => GetNodeFromId(x, component).Depth > currentNode.Depth).ToHashSet(); + if (downNodes.Count != 0) + allNodes = downNodes; break; } } @@ -226,12 +227,14 @@ public sealed partial class ArtifactSystem : EntitySystem var undiscoveredNodes = allNodes.Where(x => !GetNodeFromId(x, component).Discovered).ToList(); Log.Debug($"Undiscovered nodes: {string.Join(", ", undiscoveredNodes)}"); var newNode = _random.Pick(allNodes); - if (undiscoveredNodes.Any() && _random.Prob(0.75f)) + + if (undiscoveredNodes.Count != 0 && _random.Prob(0.75f)) { newNode = _random.Pick(undiscoveredNodes); } Log.Debug($"Going to node {newNode}"); + return GetNodeFromId(newNode, component); } diff --git a/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs b/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs index cecacceda9..07f2a60c84 100644 --- a/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs +++ b/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactAnalyzer.cs @@ -30,50 +30,40 @@ public sealed class AnalysisConsoleExtractButtonPressedMessage : BoundUserInterf } [Serializable, NetSerializable] -public sealed class AnalysisConsoleScanUpdateState : BoundUserInterfaceState +public sealed class AnalysisConsoleBiasButtonPressedMessage(bool isDown) : BoundUserInterfaceMessage { - public NetEntity? Artifact; - - public bool AnalyzerConnected; - - public bool ServerConnected; - - public bool CanScan; - - public bool CanPrint; - - public FormattedMessage? ScanReport; - - public bool Scanning; - - public bool Paused; - - public TimeSpan? StartTime; - - public TimeSpan? AccumulatedRunTime; - - public TimeSpan? TotalTime; - - public int PointAmount; - - public AnalysisConsoleScanUpdateState(NetEntity? artifact, bool analyzerConnected, bool serverConnected, bool canScan, bool canPrint, - FormattedMessage? scanReport, bool scanning, bool paused, TimeSpan? startTime, TimeSpan? accumulatedRunTime, TimeSpan? totalTime, int pointAmount) - { - Artifact = artifact; - AnalyzerConnected = analyzerConnected; - ServerConnected = serverConnected; - CanScan = canScan; - CanPrint = canPrint; - - ScanReport = scanReport; - - Scanning = scanning; - Paused = paused; - - StartTime = startTime; - AccumulatedRunTime = accumulatedRunTime; - TotalTime = totalTime; - - PointAmount = pointAmount; - } + public bool IsDown = isDown; +} + +[Serializable, NetSerializable] +public sealed class AnalysisConsoleUpdateState( + NetEntity? artifact, + bool analyzerConnected, + bool serverConnected, + bool canScan, + bool canPrint, + FormattedMessage? scanReport, + bool scanning, + bool paused, + TimeSpan? startTime, + TimeSpan? accumulatedRunTime, + TimeSpan? totalTime, + int pointAmount, + bool isTraversalDown +) + : BoundUserInterfaceState +{ + public NetEntity? Artifact = artifact; + public bool AnalyzerConnected = analyzerConnected; + public bool ServerConnected = serverConnected; + public bool CanScan = canScan; + public bool CanPrint = canPrint; + public FormattedMessage? ScanReport = scanReport; + public bool Scanning = scanning; + public bool Paused = paused; + public TimeSpan? StartTime = startTime; + public TimeSpan? AccumulatedRunTime = accumulatedRunTime; + public TimeSpan? TotalTime = totalTime; + public int PointAmount = pointAmount; + public bool IsTraversalDown = isTraversalDown; } diff --git a/Resources/Locale/en-US/research/technologies.ftl b/Resources/Locale/en-US/research/technologies.ftl index a68f9e80b4..70ca8d018a 100644 --- a/Resources/Locale/en-US/research/technologies.ftl +++ b/Resources/Locale/en-US/research/technologies.ftl @@ -44,7 +44,7 @@ research-technology-magnets-tech = Localized Magnetism research-technology-advanced-parts = Advanced Parts research-technology-anomaly-harnessing = Anomaly Core Harnessing research-technology-grappling = Grappling -research-technology-abnormal-artifact-manipulation = Abnormal Artifact Manipulation +research-technology-abnormal-artifact-manipulation = Artifact Recycling research-technology-gravity-manipulation = Gravity Manipulation research-technology-quantum-leaping = Quantum Leaping research-technology-advanced-anomaly-research = Advanced Anomaly Research diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl index 599f36ec91..672d80ed31 100644 --- a/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/artifact-analyzer.ftl @@ -6,6 +6,10 @@ analysis-console-print-button = Print analysis-console-print-tooltip-info = Print out the current information about the artifact. analysis-console-extract-button = Extract analysis-console-extract-button-info = Extract points from an artifact based on the newly explored nodes. +analysis-console-bias-up = Up +analysis-console-bias-down = Down +analysis-console-bias-button-info-up = Toggles the bias an artifact has in moving between its nodes. Up heads toward zero depth. +analysis-console-bias-button-info-down = Toggles the bias an artifact has in moving between its nodes. Down heads toward ever-higher depths. analysis-console-info-no-scanner = No analyzer connected! Please connect one using a multitool. analysis-console-info-no-artifact = No artifact present! Place one on the pad then scan for information. diff --git a/Resources/Locale/en-US/xenoarchaeology/traversal-distorter.ftl b/Resources/Locale/en-US/xenoarchaeology/traversal-distorter.ftl index 5c9eac57a5..ef2931768b 100644 --- a/Resources/Locale/en-US/xenoarchaeology/traversal-distorter.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/traversal-distorter.ftl @@ -1,5 +1,5 @@ -traversal-distorter-set-in = Traversal bias set to "in" -traversal-distorter-set-out = Traversal bias set to "out" +traversal-distorter-set-up = Traversal bias set to up, toward safer nodes +traversal-distorter-set-down = Traversal bias set to down, toward more dangerous nodes -traversal-distorter-desc-in = The affected artifact's traversal now favors moving inwards to the beginning. -traversal-distorter-desc-out = The affected artifact's traversal now favors moving outwards towards more dangerous nodes. +traversal-distorter-desc-up = The affected artifact's traversal now favors moving up the node tree toward safer nodes. +traversal-distorter-desc-down = The affected artifact's traversal now favors moving down the node tree towards more dangerous nodes. diff --git a/Resources/Maps/Dungeon/experiment.yml b/Resources/Maps/Dungeon/experiment.yml index 8449abf932..590692a6bb 100644 --- a/Resources/Maps/Dungeon/experiment.yml +++ b/Resources/Maps/Dungeon/experiment.yml @@ -7444,13 +7444,6 @@ entities: - type: Transform pos: 32.5,14.5 parent: 1653 -- proto: MachineTraversalDistorter - entities: - - uid: 1058 - components: - - type: Transform - pos: 34.5,22.5 - parent: 1653 - proto: MaintenanceFluffSpawner entities: - uid: 867 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index ebc8237cb2..63c7908432 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -253,23 +253,6 @@ materialRequirements: Glass: 5 -- type: entity - id: TraversalDistorterMachineCircuitboard - parent: BaseMachineCircuitboard - name: traversal distorter machine board - description: A machine printed circuit board for a traversal distorter. - components: - - type: Sprite - state: science - - type: MachineBoard - prototype: MachineTraversalDistorter - requirements: - Manipulator: 1 - Capacitor: 2 - materialRequirements: - Steel: 5 - Cable: 1 - - type: entity id: ArtifactCrusherMachineCircuitboard parent: BaseMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index b00d6d8986..8b0c578763 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -43,6 +43,7 @@ powerLoad: 12000 needsPower: false #only turns on when scanning - type: ArtifactAnalyzer + - type: TraversalDistorter - type: ItemPlacer whitelist: components: @@ -72,62 +73,6 @@ True: { visible: true } False: { visible: false } -- type: entity - id: MachineTraversalDistorter - parent: [ BaseMachinePowered, ConstructibleMachine ] - name: traversal distorter - description: A machine capable of distorting the traversal of artifact nodes. - components: - - type: Sprite - noRot: true - sprite: Structures/Machines/traversal_distorter.rsi - drawdepth: FloorObjects - layers: - - state: icon - - state: unshaded - shader: unshaded - map: ["enum.PowerDeviceVisualLayers.Powered"] - - type: Physics - bodyType: Static - canCollide: true - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.35,-0.35,0.35,0.35" - density: 190 - mask: - - MachineMask - layer: - - Impassable - - MidImpassable - - LowImpassable - hard: False - - type: Transform - noRot: false - - type: TraversalDistorter - - type: ItemPlacer - # don't limit the number of artifacts that can be biased - maxEntities: 0 - whitelist: - components: - - Artifact - - type: PlaceableSurface - placeCentered: true - - type: Machine - board: TraversalDistorterMachineCircuitboard - - type: Appearance - - type: GuideHelp - guides: - - TraversalDistorter - - type: GenericVisualizer - visuals: - enum.PowerDeviceVisuals.Powered: - enum.PowerDeviceVisualLayers.Powered: - True: { visible: true } - False: { visible: false } - - type: entity id: MachineArtifactCrusher parent: [ ConstructibleMachine, BaseMachinePowered ] diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index b1d2469af2..25c6545286 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -443,7 +443,6 @@ - AnomalySynchronizerCircuitboard - APECircuitboard - ArtifactAnalyzerMachineCircuitboard - - TraversalDistorterMachineCircuitboard - ArtifactCrusherMachineCircuitboard - TelecomServerCircuitboard - MassMediaCircuitboard diff --git a/Resources/Prototypes/Guidebook/science.yml b/Resources/Prototypes/Guidebook/science.yml index 4382696df8..2c3018dcee 100644 --- a/Resources/Prototypes/Guidebook/science.yml +++ b/Resources/Prototypes/Guidebook/science.yml @@ -38,7 +38,6 @@ text: "/ServerInfo/Guidebook/Science/Xenoarchaeology.xml" children: - ArtifactReports - - TraversalDistorter - type: guideEntry id: Robotics @@ -52,11 +51,6 @@ name: guide-entry-artifact-reports text: "/ServerInfo/Guidebook/Science/ArtifactReports.xml" -- type: guideEntry - id: TraversalDistorter - name: guide-entry-traversal-distorter - text: "/ServerInfo/Guidebook/Science/TraversalDistorter.xml" - - type: guideEntry id: Cyborgs name: guide-entry-cyborgs diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index 60c0fc1524..a6f3e6cece 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -328,16 +328,6 @@ Glass: 900 Gold: 100 -- type: latheRecipe - id: TraversalDistorterMachineCircuitboard - result: TraversalDistorterMachineCircuitboard - category: Circuitry - completetime: 4 - materials: - Steel: 100 - Glass: 900 - Gold: 100 - - type: latheRecipe id: ArtifactCrusherMachineCircuitboard result: ArtifactCrusherMachineCircuitboard @@ -921,7 +911,7 @@ materials: Steel: 100 Glass: 900 - + - type: latheRecipe id: ShuttleGunPerforatorCircuitboard result: ShuttleGunPerforatorCircuitboard @@ -930,7 +920,7 @@ Steel: 100 Glass: 900 Gold: 100 - + - type: latheRecipe id: ShuttleGunKineticCircuitboard result: ShuttleGunKineticCircuitboard @@ -938,7 +928,7 @@ materials: Steel: 100 Glass: 900 - + - type: latheRecipe id: ShuttleGunFriendshipCircuitboard result: ShuttleGunFriendshipCircuitboard @@ -947,7 +937,7 @@ Steel: 100 Glass: 900 Gold: 50 - + - type: latheRecipe id: ShuttleGunDusterCircuitboard result: ShuttleGunDusterCircuitboard diff --git a/Resources/Prototypes/Research/experimental.yml b/Resources/Prototypes/Research/experimental.yml index 1b1a738322..77adfcf5d5 100644 --- a/Resources/Prototypes/Research/experimental.yml +++ b/Resources/Prototypes/Research/experimental.yml @@ -87,13 +87,12 @@ id: AbnormalArtifactManipulation name: research-technology-abnormal-artifact-manipulation icon: - sprite: Structures/Machines/traversal_distorter.rsi - state: display + sprite: Structures/Machines/artifact_crusher.rsi + state: icon discipline: Experimental tier: 2 cost: 5000 recipeUnlocks: - - TraversalDistorterMachineCircuitboard - ArtifactCrusherMachineCircuitboard - type: technology diff --git a/Resources/ServerInfo/Guidebook/Science/ArtifactReports.xml b/Resources/ServerInfo/Guidebook/Science/ArtifactReports.xml index b7ba3d4c8b..b010e20abc 100644 --- a/Resources/ServerInfo/Guidebook/Science/ArtifactReports.xml +++ b/Resources/ServerInfo/Guidebook/Science/ArtifactReports.xml @@ -1,25 +1,24 @@ -# Artifact Reports -A large portion of Xenoarchaeology gameplay revolves around the interpretation of artifact reports, which are created at the [color=#a4885c]analysis console[/color] after an artifact is scanned. Reports contain the following information: + # Artifact Reports + A large portion of Xenoarchaeology gameplay revolves around the interpretation of artifact reports, which are created at the [color=#a4885c]analysis console[/color] after an artifact is scanned. Reports contain the following information: -- [color=#a4885c]Node ID:[/color] a unique numeric ID corresponding to this artifact's node. Useful in conjunction with a [color=#a4885c]node scanner[/color] for quickly identifying recurring nodes. + - [color=#a4885c]Node ID:[/color] a unique numeric ID corresponding to this artifact's node. Useful in conjunction with a [color=#a4885c]node scanner[/color] for quickly identifying recurring nodes. -- [color=#a4885c]Depth:[/color] a distance from the starting node (depth 0). This is a good shorthand for the value and danger of a node. + - [color=#a4885c]Depth:[/color] a distance from the starting node (depth 0). This is a good shorthand for the value and danger of a node. -- [color=#a4885c]Activation status:[/color] whether or not a node has been activated in the past. + - [color=#a4885c]Activation status:[/color] whether or not a node has been activated in the past. -- [color=#a4885c]Stimulus:[/color] the stimulus for that particular node. + - [color=#a4885c]Stimulus:[/color] the stimulus for that particular node. -- [color=#a4885c]Reaction:[/color] the reaction the stimulus induces. This is often vague, so caution is advised. + - [color=#a4885c]Reaction:[/color] the reaction the stimulus induces. This is often vague, so caution is advised. -- [color=#a4885c]Edges:[/color] the amount of nodes that are connected to the current node. Using this, you can calculate the total number of nodes as well as organize a map of their connections. + - [color=#a4885c]Edges:[/color] the amount of nodes that are connected to the current node. Using this, you can calculate the total number of nodes as well as organize a map of their connections. -- [color=#a4885c]Unextracted value:[/color] the amount of research points an artifact will give when extracted. Extracting sets this to zero and traversing new nodes increases it. - -Reports are a helpful tool in manipulating an artifact, especially in the later stages where you are traversing nodes that have already been activated. - - - -To help with this process, consider printing out reports, writing down details uncovered during activation, or storing them in a folder nearby. + - [color=#a4885c]Unextracted value:[/color] the amount of research points an artifact will give when extracted. Extracting sets this to zero and traversing new nodes increases it. + Reports are a helpful tool in manipulating an artifact, especially in the later stages where you are traversing nodes that have already been activated. + + + + To help with this process, consider printing out reports, writing down details uncovered during activation, or storing them in a folder nearby. diff --git a/Resources/ServerInfo/Guidebook/Science/TraversalDistorter.xml b/Resources/ServerInfo/Guidebook/Science/TraversalDistorter.xml deleted file mode 100644 index f46065c744..0000000000 --- a/Resources/ServerInfo/Guidebook/Science/TraversalDistorter.xml +++ /dev/null @@ -1,18 +0,0 @@ - -# Traversal Distorter - -The traversal distorter is a late-game artifact machine that can aid in moving through the nodes of an artifact. - - - -Artifacts placed on top of a powered traversal distorter are subjected to a bias which affects which node they will move to after being activated. The bias can be set by clicking on the distorter. - -There are two types of biases: -- [color=#a4885c]In:[/color] favors nodes closer to the origin. Results in a decrease of depth. -- [color=#a4885c]Out:[/color] favors nodes farther away from the origin. Results in an increase of depth. - -Setting it to bias inwards allows you to return to the beginning of an artifact graph, if you've reached a dead end. - -Likewise, if you find yourself stuck at low depths, setting it to bias outward will help you find new nodes. In certain circumstances, toggling between the two allows you to repeatedly activate the same node. - - diff --git a/Resources/ServerInfo/Guidebook/Science/Xenoarchaeology.xml b/Resources/ServerInfo/Guidebook/Science/Xenoarchaeology.xml index 3fedb678df..87177acbaf 100644 --- a/Resources/ServerInfo/Guidebook/Science/Xenoarchaeology.xml +++ b/Resources/ServerInfo/Guidebook/Science/Xenoarchaeology.xml @@ -2,18 +2,28 @@ # Xenoarchaeology Xenoarchaeology is a science subdepartment focused on researching and experimenting on alien artifacts. -## Artifacts +At the start of each shift, the Science department will usually have access to at least two artifacts to experiment on. You can buy more by talking to the Cargo department. + +By researching the unique things each artifact can do, you gain Research Points, increase the artifact's sale value, and potentially discover a useful ability or two that can help your department or the whole station! + +## Artifact Nodes -Artifacts consist of a randomly-generated graph structure. They consist of nodes connected to each other by edges, the traversal of which is the main goal of the scientists working on them. +Artifacts consist of a randomly-generated tree of nodes. These nodes have a "[color=#a4885c]depth[/color]", representing how dangerous the node is, and the number of other nodes connected to it, called "[color=#a4885c]edges[/color]", -Each node has two main components: a [color=#a4885c]stimulus[/color] and a [color=#a4885c]reaction[/color]. A stimulus is the external behavior that triggers the reaction. Some reactions are instantaneous effects while others are permanent changes. Triggering the reaction causes the artifact to move to one of the node's edges. +Artifacts always start at depth zero, the root of the tree. Travelling the tree to find as many nodes as possible is the main goal of the scientists working on them. Knowledge is extracted from nodes to gain Research Points and increase the artifact's sale value. -With these basic principles, you can begin to grasp how the different nodes of an artifact are interconnected, and how one can move between them by repeatedly activating nodes. +Each node has two components: its [color=#a4885c]stimulus[/color] and a [color=#a4885c]reaction[/color]. -While it might seem random to an untrained eye, a skilled scientist can learn to understand the internal structure of any artifact. +A stimulus is the external behavior that triggers the reaction. There's a variety of these, and higher depth nodes have more difficult to accomplish stimuli. Some stimuli will need improvisation to trigger, and you may need to talk to other departments to get everything you need. + +Some reactions are instantaneous effects while others are permanent changes. Once an artifact is triggered, the reaction causes the artifact to randomly move to another node it is linked to. + +With some experimental science, you can begin to grasp how the different nodes of an artifact are connected, and how to move between them by repeatedly activating nodes. + +All non-zero-depth nodes will have exactly one edge that leads up to its parent node. All other edges a node has lead down to the next depth. ## Artifact Analyzer and Analysis Console @@ -22,13 +32,26 @@ While it might seem random to an untrained eye, a skilled scientist can learn to The main equipment that you'll be using for Xenoarchaeology is the [color=#a4885c]artifact analyzer[/color] and the [color=#a4885c]analysis console[/color]. You can use these to create reports that contain valuable information about an artifact. -To set them up, simply link them with a network configurator, set an artifact on top of the analyzer, and press the [color=#a4885c]Scan[/color] button. +To set them up, simply link them with a network configurator and set an artifact on top of the analyzer. Every station has at least one of these machines already set up. -Using the console, you can extract points from the artifact using the [color=#a4885c]Extract[/color] button. The amount of points you extract is based on how many new nodes have been activated, since last extracting. You can extract multiple times, there is no reason not to!!! +Use the console's [color=#a4885c]scan[/color] button to discover what stimulus the artifact needs and what its reaction will do. Scanning takes thirty seconds. + +Use the [color=#a4885c]print[/color] button to save the scan result, so you can refer to it later. + +Once you've discovered a new node, you can extract points from the artifact using the [color=#a4885c]Extract[/color] button. ## Assembling Artifacts -It is possible to gather multiple artifact fragments and assemble them into a working artifact. You can ask for these from Salvage, they usually find these while mining asteroids or on Expeditions. +It is possible to gather multiple artifact fragments and assemble them into a working artifact. You can ask for these from Salvage, who usually find these while mining asteroids or on Expeditions. +## Traversal Bias + + + +Artifacts placed on top of a powered artifact analyzer are subjected to a bias which affects which node they will move to after being activated. The bias can be set in the artifact console. + +There are two types of biases: +- [color=#a4885c]Up:[/color] favors nodes closer to the origin. Results in a decrease of depth. +- [color=#a4885c]Down:[/color] favors nodes farther away from the origin. Results in an increase of depth. diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/icon.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af5f78e3683cf95c6a7348cbcc839f3162d165e8 GIT binary patch literal 1570 zcmV+-2Hp9IP)em2#F?GO|jY#1BOMCwd^*P)B;Wson={8 zDAI??z1*3(Gdr_b?L)tW+`n_abMCok&R%A+mY0|DD&cyi*8g|lzu-XDY6(6#dctuQ zcV0Y4?Pg^{z#>>1gd`Q)mcQ0_T{F%hB$+^xiXqF>>R{>`b= z@Njq~2PCOD?M{e{lO3D!5ah56;n4`zO0RJZ$nrG8qY(sas`;$hMF4=hH}`T|Gvw$e zB&itT(TG7XSW}Hj`7bUBJq8_5IvK75vOLY*C6C~T@4LCA(bxcv9Xp|!yKvzgDl4`l z8XLgLlV9*12-Z|XmZwd<)jJlA4RGZE;Aa2NT*vg_9)TT5Qn6+yEY6(ylxvJ9Z*bs6 zz|1ioa)6ax%knfgbav3RYbUJ>EFarvZIRY80+SOXrfX~0ZQ;(FZH73ghl>d76K`^2 z1nbvtKq8qmw3{|nbDbkRW=YJh6Pc`fXv;?{5fDW`72NX95d(34 zz6;4@5_9wOc<N7gP?%oW6K){i)nVA{QxNLhn#5G=w{P-={r;d9BdStS5RYx#gClPl6_96fP9>JW@ zi41Eq?X|oVg|t7PN~I-cWmsJ^xB&A6EJY!NJbOFhLC6zKop5{v{y7mIL4bcwq+_$OM`TiT(%#L4Y6#aJ${yKS2--Ign0X(A|_) zorHjS4me4|jNg>9na@VUDJ-vK>9Cp{$mmwg!m19~fn^ff#S5(itP?M@4%q(Jj0g6& zz$q-Bf|pST2y8uu|3)2f%BvdCu(K7Z=N^Q% zwIH6#MtM~O6h(oeDD(*cfUiC)qx0oe4Tz_*5!%**)N>CScD7PITMo4BJA#&d>bspA z{e9TItC_ZBJu)^1pWlz;XUAz985^T|tj>-8J_B#s2mrv9-cA&WB?u3PX?vx&ldd;4 zHln?)4ef1hXliWK=nZyI4w>7qbbuHqeHOe35KP6M;P}~bbam8XD)xjcLrQ Date: Sun, 21 Apr 2024 16:10:32 +0000 Subject: [PATCH 170/170] Automatic changelog update --- Resources/Changelog/Changelog.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5630fd6f59..d623b48d44 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Ubaser - changes: - - message: Grinding ectoplasm now gives Necrosol. - type: Tweak - id: 5915 - time: '2024-02-11T06:24:35.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25053 - author: Ubaser changes: - message: Food Service research is now roundstart. @@ -3839,3 +3832,17 @@ id: 6414 time: '2024-04-21T13:16:23.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/22986 +- author: FairlySadPanda + changes: + - message: Xenoarchaeology Traversal Distorters have been rolled into the Artifact + Analyzers to make artifact gameplay a bit more controlled. + type: Tweak + - message: The T2 Abnormal Artifact Manipulation tech has been made cheaper to compensate + for losing an unlock. + type: Tweak + - message: The Xenoarchaeology guidebook entry has been rewritten to be more useful + and comprehensive for newbies. + type: Tweak + id: 6415 + time: '2024-04-21T16:09:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26545