Merge branch 'master' into 2020-08-31-click-attack
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects.Components.UserInterface;
|
||||
|
||||
namespace Content.Client.GameObjects.Components
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class AcceptCloningBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
|
||||
public AcceptCloningBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private AcceptCloningWindow _window;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new AcceptCloningWindow();
|
||||
_window.OnClose += Close;
|
||||
_window.DenyButton.OnPressed += _ => _window.Close();
|
||||
_window.ConfirmButton.OnPressed += _ =>
|
||||
{
|
||||
SendMessage(
|
||||
new SharedAcceptCloningComponent.UiButtonPressedMessage(
|
||||
SharedAcceptCloningComponent.UiButton.Accept));
|
||||
_window.Close();
|
||||
};
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
50
Content.Client/GameObjects/Components/AcceptCloningWindow.cs
Normal file
50
Content.Client/GameObjects/Components/AcceptCloningWindow.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
#nullable enable
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
|
||||
namespace Content.Client.GameObjects.Components
|
||||
{
|
||||
public sealed class AcceptCloningWindow : SS14Window
|
||||
{
|
||||
public readonly Button DenyButton;
|
||||
public readonly Button ConfirmButton;
|
||||
|
||||
public AcceptCloningWindow()
|
||||
{
|
||||
|
||||
Title = Loc.GetString("Cloning Machine");
|
||||
|
||||
Contents.AddChild(new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(new Label
|
||||
{
|
||||
Text = Loc.GetString("You are being cloned! Transfer your soul to the clone body?")
|
||||
}),
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(ConfirmButton = new Button
|
||||
{
|
||||
Text = Loc.GetString("Yes"),
|
||||
}),
|
||||
(DenyButton = new Button
|
||||
{
|
||||
Text = Loc.GetString("No"),
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using Content.Client.GameObjects.Components.Mobs;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Input;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.Input;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#nullable enable
|
||||
using Content.Client.GameObjects.Components.Disposal;
|
||||
using Content.Client.GameObjects.Components.MedicalScanner;
|
||||
using Content.Client.Interfaces.GameObjects.Components.Interaction;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -21,7 +23,13 @@ namespace Content.Client.GameObjects.Components.Body
|
||||
|
||||
public bool ClientCanDropOn(CanDropEventArgs eventArgs)
|
||||
{
|
||||
return eventArgs.Target.HasComponent<DisposalUnitComponent>();
|
||||
if (
|
||||
eventArgs.Target.HasComponent<DisposalUnitComponent>()||
|
||||
eventArgs.Target.HasComponent<MedicalScannerComponent>())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ClientCanDrag(CanDragEventArgs eventArgs)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.Medical.SharedCloningPodComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.CloningPod
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class CloningPodBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
public CloningPodBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private CloningPodWindow _window;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
|
||||
_window = new CloningPodWindow(new Dictionary<int, string>());
|
||||
_window.OnClose += Close;
|
||||
_window.CloneButton.OnPressed += _ =>
|
||||
{
|
||||
if (_window.SelectedScan != null)
|
||||
{
|
||||
SendMessage(new CloningPodUiButtonPressedMessage(UiButton.Clone, (int) _window.SelectedScan));
|
||||
}
|
||||
};
|
||||
_window.EjectButton.OnPressed += _ =>
|
||||
{
|
||||
SendMessage(new CloningPodUiButtonPressedMessage(UiButton.Eject, null));
|
||||
};
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
_window.Populate((CloningPodBoundUserInterfaceState) state);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using static Content.Shared.GameObjects.Components.Medical.SharedCloningPodComponent;
|
||||
using static Content.Shared.GameObjects.Components.Medical.SharedCloningPodComponent.CloningPodStatus;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.CloningPod
|
||||
{
|
||||
public class CloningPodVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (!component.TryGetData(CloningPodVisuals.Status, out CloningPodStatus status)) return;
|
||||
sprite.LayerSetState(CloningPodVisualLayers.Machine, StatusToMachineStateId(status));
|
||||
}
|
||||
|
||||
private string StatusToMachineStateId(CloningPodStatus status)
|
||||
{
|
||||
//TODO: implement NoMind for if the mind is not yet in the body
|
||||
//TODO: Find a use for GORE POD
|
||||
switch (status)
|
||||
{
|
||||
case Cloning: return "pod_1";
|
||||
case NoMind: return "pod_e";
|
||||
case Gore: return "pod_g";
|
||||
case Idle: return "pod_0";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(status), status, "unknown CloningPodStatus");
|
||||
}
|
||||
}
|
||||
|
||||
public enum CloningPodVisualLayers
|
||||
{
|
||||
Machine,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Localization;
|
||||
using static Content.Shared.GameObjects.Components.Medical.SharedCloningPodComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.CloningPod
|
||||
{
|
||||
public sealed class CloningPodWindow : SS14Window
|
||||
{
|
||||
private Dictionary<int, string> _scanManager;
|
||||
|
||||
private readonly VBoxContainer _mainVBox;
|
||||
private readonly ScanListContainer _scanList;
|
||||
private readonly LineEdit _searchBar;
|
||||
private readonly Button _clearButton;
|
||||
public readonly Button CloneButton;
|
||||
public readonly Button EjectButton;
|
||||
private readonly CloningScanButton _measureButton;
|
||||
private CloningScanButton? _selectedButton;
|
||||
private Label _progressLabel;
|
||||
private readonly ProgressBar _cloningProgressBar;
|
||||
private Label _mindState;
|
||||
|
||||
protected override Vector2 ContentsMinimumSize => _mainVBox?.CombinedMinimumSize ?? Vector2.Zero;
|
||||
private CloningPodBoundUserInterfaceState _lastUpdate = null!;
|
||||
|
||||
// List of scans that are visible based on current filter criteria.
|
||||
private readonly Dictionary<int, string> _filteredScans = new Dictionary<int, string>();
|
||||
|
||||
// The indices of the visible scans last time UpdateVisibleScans was ran.
|
||||
// This is inclusive, so end is the index of the last scan, not right after it.
|
||||
private (int start, int end) _lastScanIndices;
|
||||
|
||||
public int? SelectedScan;
|
||||
|
||||
protected override Vector2? CustomSize => (250, 300);
|
||||
|
||||
public CloningPodWindow(
|
||||
Dictionary<int, string> scanManager)
|
||||
{
|
||||
_scanManager = scanManager;
|
||||
|
||||
|
||||
Title = Loc.GetString("Cloning Machine");
|
||||
|
||||
Contents.AddChild(_mainVBox = new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(_searchBar = new LineEdit
|
||||
{
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
PlaceHolder = Loc.GetString("Search")
|
||||
}),
|
||||
|
||||
(_clearButton = new Button
|
||||
{
|
||||
Disabled = true,
|
||||
Text = Loc.GetString("Clear"),
|
||||
})
|
||||
}
|
||||
},
|
||||
new ScrollContainer
|
||||
{
|
||||
CustomMinimumSize = new Vector2(200.0f, 0.0f),
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
Children =
|
||||
{
|
||||
(_scanList = new ScanListContainer())
|
||||
}
|
||||
},
|
||||
new VBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(CloneButton = new Button
|
||||
{
|
||||
Text = Loc.GetString("Clone")
|
||||
})
|
||||
}
|
||||
},
|
||||
(_measureButton = new CloningScanButton {Visible = false}),
|
||||
(_cloningProgressBar = new ProgressBar
|
||||
{
|
||||
CustomMinimumSize = (200, 20),
|
||||
SizeFlagsHorizontal = SizeFlags.Fill,
|
||||
MinValue = 0,
|
||||
MaxValue = 10,
|
||||
Page = 0,
|
||||
Value = 0.5f,
|
||||
Children =
|
||||
{
|
||||
(_progressLabel = new Label())
|
||||
}
|
||||
}),
|
||||
(EjectButton = new Button
|
||||
{
|
||||
Text = Loc.GetString("Eject Body")
|
||||
}),
|
||||
new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
new Label()
|
||||
{
|
||||
Text = Loc.GetString("Neural Interface: ")
|
||||
},
|
||||
(_mindState = new Label()
|
||||
{
|
||||
Text = Loc.GetString("No Activity"),
|
||||
FontColorOverride = Color.Red
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
_searchBar.OnTextChanged += OnSearchBarTextChanged;
|
||||
_clearButton.OnPressed += OnClearButtonPressed;
|
||||
|
||||
BuildEntityList();
|
||||
|
||||
_searchBar.GrabKeyboardFocus();
|
||||
}
|
||||
|
||||
public void Populate(CloningPodBoundUserInterfaceState state)
|
||||
{
|
||||
//Ignore useless updates or we can't interact with the UI
|
||||
//TODO: come up with a better comparision, probably write a comparator because '.Equals' doesn't work
|
||||
if (_lastUpdate == null || _lastUpdate.MindIdName.Count != state.MindIdName.Count)
|
||||
{
|
||||
_scanManager = state.MindIdName;
|
||||
BuildEntityList();
|
||||
_lastUpdate = state;
|
||||
}
|
||||
|
||||
var percentage = state.Progress / _cloningProgressBar.MaxValue * 100;
|
||||
_progressLabel.Text = $"{percentage:0}%";
|
||||
|
||||
_cloningProgressBar.Value = state.Progress;
|
||||
_mindState.Text = Loc.GetString(state.MindPresent ? "Consciousness Detected" : "No Activity");
|
||||
_mindState.FontColorOverride = state.MindPresent ? Color.Green : Color.Red;
|
||||
}
|
||||
|
||||
private void OnSearchBarTextChanged(LineEdit.LineEditEventArgs args)
|
||||
{
|
||||
BuildEntityList(args.Text);
|
||||
_clearButton.Disabled = string.IsNullOrEmpty(args.Text);
|
||||
}
|
||||
|
||||
private void OnClearButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
_searchBar.Clear();
|
||||
BuildEntityList("");
|
||||
}
|
||||
|
||||
|
||||
private void BuildEntityList(string? searchStr = null)
|
||||
{
|
||||
_filteredScans.Clear();
|
||||
_scanList.RemoveAllChildren();
|
||||
// Reset last scan indices so it automatically updates the entire list.
|
||||
_lastScanIndices = (0, -1);
|
||||
_scanList.RemoveAllChildren();
|
||||
_selectedButton = null;
|
||||
searchStr = searchStr?.ToLowerInvariant();
|
||||
|
||||
foreach (var scan in _scanManager)
|
||||
{
|
||||
if (searchStr != null && !_doesScanMatchSearch(scan.Value, searchStr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_filteredScans.Add(scan.Key, scan.Value);
|
||||
}
|
||||
|
||||
//TODO: set up sort
|
||||
//_filteredScans.Sort((a, b) => string.Compare(a.ToString(), b.ToString(), StringComparison.Ordinal));
|
||||
|
||||
_scanList.TotalItemCount = _filteredScans.Count;
|
||||
}
|
||||
|
||||
private void UpdateVisibleScans()
|
||||
{
|
||||
// Update visible buttons in the scan list.
|
||||
|
||||
// Calculate index of first scan to render based on current scroll.
|
||||
var height = _measureButton.CombinedMinimumSize.Y + ScanListContainer.Separation;
|
||||
var offset = -_scanList.Position.Y;
|
||||
var startIndex = (int) Math.Floor(offset / height);
|
||||
_scanList.ItemOffset = startIndex;
|
||||
|
||||
var (prevStart, prevEnd) = _lastScanIndices;
|
||||
|
||||
// Calculate index of final one.
|
||||
var endIndex = startIndex - 1;
|
||||
var spaceUsed = -height; // -height instead of 0 because else it cuts off the last button.
|
||||
|
||||
while (spaceUsed < _scanList.Parent!.Height)
|
||||
{
|
||||
spaceUsed += height;
|
||||
endIndex += 1;
|
||||
}
|
||||
|
||||
endIndex = Math.Min(endIndex, _filteredScans.Count - 1);
|
||||
|
||||
if (endIndex == prevEnd && startIndex == prevStart)
|
||||
{
|
||||
// Nothing changed so bye.
|
||||
return;
|
||||
}
|
||||
|
||||
_lastScanIndices = (startIndex, endIndex);
|
||||
|
||||
// Delete buttons at the start of the list that are no longer visible (scrolling down).
|
||||
for (var i = prevStart; i < startIndex && i <= prevEnd; i++)
|
||||
{
|
||||
var control = (CloningScanButton) _scanList.GetChild(0);
|
||||
DebugTools.Assert(control.Index == i);
|
||||
_scanList.RemoveChild(control);
|
||||
}
|
||||
|
||||
// Delete buttons at the end of the list that are no longer visible (scrolling up).
|
||||
for (var i = prevEnd; i > endIndex && i >= prevStart; i--)
|
||||
{
|
||||
var control = (CloningScanButton) _scanList.GetChild(_scanList.ChildCount - 1);
|
||||
DebugTools.Assert(control.Index == i);
|
||||
_scanList.RemoveChild(control);
|
||||
}
|
||||
|
||||
var array = _filteredScans.ToArray();
|
||||
|
||||
// Create buttons at the start of the list that are now visible (scrolling up).
|
||||
for (var i = Math.Min(prevStart - 1, endIndex); i >= startIndex; i--)
|
||||
{
|
||||
InsertEntityButton(array[i], true, i);
|
||||
}
|
||||
|
||||
// Create buttons at the end of the list that are now visible (scrolling down).
|
||||
for (var i = Math.Max(prevEnd + 1, startIndex); i <= endIndex; i++)
|
||||
{
|
||||
InsertEntityButton(array[i], false, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a spawn button and insert it into the start or end of the list.
|
||||
private void InsertEntityButton(KeyValuePair<int, string> scan, bool insertFirst, int index)
|
||||
{
|
||||
var button = new CloningScanButton
|
||||
{
|
||||
Scan = scan.Value,
|
||||
Id = scan.Key,
|
||||
Index = index // We track this index purely for debugging.
|
||||
};
|
||||
button.ActualButton.OnToggled += OnItemButtonToggled;
|
||||
var entityLabelText = scan.Value;
|
||||
|
||||
button.EntityLabel.Text = entityLabelText;
|
||||
|
||||
if (scan.Key == SelectedScan)
|
||||
{
|
||||
_selectedButton = button;
|
||||
_selectedButton.ActualButton.Pressed = true;
|
||||
}
|
||||
|
||||
//TODO: replace with body's face
|
||||
/*var tex = IconComponent.GetScanIcon(scan, resourceCache);
|
||||
var rect = button.EntityTextureRect;
|
||||
if (tex != null)
|
||||
{
|
||||
rect.Texture = tex.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Dispose();
|
||||
}
|
||||
|
||||
rect.Dispose();
|
||||
*/
|
||||
|
||||
_scanList.AddChild(button);
|
||||
if (insertFirst)
|
||||
{
|
||||
button.SetPositionInParent(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _doesScanMatchSearch(string scan, string searchStr)
|
||||
{
|
||||
return scan.ToLowerInvariant().Contains(searchStr);
|
||||
}
|
||||
|
||||
private void OnItemButtonToggled(BaseButton.ButtonToggledEventArgs args)
|
||||
{
|
||||
var item = (CloningScanButton) args.Button.Parent!;
|
||||
if (_selectedButton == item)
|
||||
{
|
||||
_selectedButton = null;
|
||||
SelectedScan = null;
|
||||
return;
|
||||
}
|
||||
else if (_selectedButton != null)
|
||||
{
|
||||
_selectedButton.ActualButton.Pressed = false;
|
||||
}
|
||||
|
||||
_selectedButton = null;
|
||||
SelectedScan = null;
|
||||
|
||||
_selectedButton = item;
|
||||
SelectedScan = item.Id;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
UpdateVisibleScans();
|
||||
}
|
||||
|
||||
private class ScanListContainer : Container
|
||||
{
|
||||
// Quick and dirty container to do virtualization of the list.
|
||||
// Basically, get total item count and offset to put the current buttons at.
|
||||
// Get a constant minimum height and move the buttons in the list up to match the scrollbar.
|
||||
private int _totalItemCount;
|
||||
private int _itemOffset;
|
||||
|
||||
public int TotalItemCount
|
||||
{
|
||||
get => _totalItemCount;
|
||||
set
|
||||
{
|
||||
_totalItemCount = value;
|
||||
MinimumSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public int ItemOffset
|
||||
{
|
||||
get => _itemOffset;
|
||||
set
|
||||
{
|
||||
_itemOffset = value;
|
||||
UpdateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public const float Separation = 2;
|
||||
|
||||
protected override Vector2 CalculateMinimumSize()
|
||||
{
|
||||
if (ChildCount == 0)
|
||||
{
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
var first = GetChild(0);
|
||||
|
||||
var (minX, minY) = first.CombinedMinimumSize;
|
||||
|
||||
return (minX, minY * TotalItemCount + (TotalItemCount - 1) * Separation);
|
||||
}
|
||||
|
||||
protected override void LayoutUpdateOverride()
|
||||
{
|
||||
if (ChildCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var first = GetChild(0);
|
||||
|
||||
var height = first.CombinedMinimumSize.Y;
|
||||
var offset = ItemOffset * height + (ItemOffset - 1) * Separation;
|
||||
|
||||
foreach (var child in Children)
|
||||
{
|
||||
FitChildInBox(child, UIBox2.FromDimensions(0, offset, Width, height));
|
||||
offset += Separation + height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerDisplay("cloningbutton {" + nameof(Index) + "}")]
|
||||
private class CloningScanButton : Control
|
||||
{
|
||||
public string Scan { get; set; } = default!;
|
||||
public int Id { get; set; }
|
||||
public Button ActualButton { get; private set; }
|
||||
public Label EntityLabel { get; private set; }
|
||||
public TextureRect EntityTextureRect { get; private set; }
|
||||
public int Index { get; set; }
|
||||
|
||||
public CloningScanButton()
|
||||
{
|
||||
AddChild(ActualButton = new Button
|
||||
{
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
SizeFlagsVertical = SizeFlags.FillExpand,
|
||||
ToggleMode = true,
|
||||
});
|
||||
|
||||
AddChild(new HBoxContainer
|
||||
{
|
||||
Children =
|
||||
{
|
||||
(EntityTextureRect = new TextureRect
|
||||
{
|
||||
CustomMinimumSize = (32, 32),
|
||||
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||
Stretch = TextureRect.StretchMode.KeepAspectCentered,
|
||||
CanShrink = true
|
||||
}),
|
||||
(EntityLabel = new Label
|
||||
{
|
||||
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||
Text = "",
|
||||
ClipText = true
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
|
||||
namespace Content.Client.GameObjects.Components
|
||||
{
|
||||
public class ExtinguisherCabinetVisualizer : AppearanceVisualizer
|
||||
{
|
||||
private string _prefix;
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
|
||||
if (component.TryGetData(ExtinguisherCabinetVisuals.IsOpen, out bool isOpen))
|
||||
{
|
||||
if (isOpen)
|
||||
{
|
||||
if (component.TryGetData(ExtinguisherCabinetVisuals.ContainsExtinguisher, out bool contains))
|
||||
{
|
||||
if (contains)
|
||||
{
|
||||
sprite.LayerSetState(0, "extinguisher_full");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(0, "extinguisher_empty");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(0, "extinguisher_closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.MedicalScanner
|
||||
{
|
||||
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedMedicalScannerComponent))]
|
||||
public class MedicalScannerComponent : SharedMedicalScannerComponent
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,11 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
if (component.Owner.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (!component.TryGetData(MedicalScannerVisuals.Status, out MedicalScannerStatus status)) return;
|
||||
sprite.LayerSetState(MedicalScannerVisualLayers.Machine, StatusToMachineStateId(status));
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Content.Client.GameObjects.Components.MedicalScanner
|
||||
{
|
||||
(ScanButton = new Button
|
||||
{
|
||||
Text = "Scan and Save DNA"
|
||||
Text = Loc.GetString("Scan and Save DNA")
|
||||
}),
|
||||
(_diagnostics = new Label
|
||||
{
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace Content.Client.GameObjects.Components.Observer
|
||||
|
||||
private GhostGui _gui;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public bool CanReturnToBody { get; private set; } = true;
|
||||
[ViewVariables(VVAccess.ReadOnly)] public bool CanReturnToBody { get; private set; } = true;
|
||||
|
||||
private bool _isAttached;
|
||||
|
||||
@@ -51,7 +50,8 @@ namespace Content.Client.GameObjects.Components.Observer
|
||||
base.Initialize();
|
||||
|
||||
if (Owner.TryGetComponent(out SpriteComponent component))
|
||||
component.Visible = _playerManager.LocalPlayer.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
|
||||
component.Visible =
|
||||
_playerManager.LocalPlayer.ControlledEntity?.HasComponent<GhostComponent>() ?? false;
|
||||
}
|
||||
|
||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
||||
@@ -98,7 +98,6 @@ namespace Content.Client.GameObjects.Components.Observer
|
||||
{
|
||||
_gui?.Update();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"Breakable",
|
||||
"Pickaxe",
|
||||
"Interactable",
|
||||
"CloningPod",
|
||||
"Destructible",
|
||||
"Temperature",
|
||||
"Explosive",
|
||||
@@ -58,7 +59,6 @@
|
||||
"AccessReader",
|
||||
"IdCardConsole",
|
||||
"Airlock",
|
||||
"MedicalScanner",
|
||||
"WirePlacer",
|
||||
"Drink",
|
||||
"Food",
|
||||
@@ -172,6 +172,9 @@
|
||||
"SignalTransmitter",
|
||||
"SignalButton",
|
||||
"SignalLinker",
|
||||
"ExtinguisherCabinet",
|
||||
"ExtinguisherCabinetFilled",
|
||||
"FireExtinguisher",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Content.Client
|
||||
}
|
||||
|
||||
await using var file =
|
||||
_resourceManager.UserData.Open(BaseScreenshotPath / $"{filename}.png", FileMode.CreateNew, FileAccess.Read, FileShare.None);
|
||||
_resourceManager.UserData.Open(BaseScreenshotPath / $"{filename}.png", FileMode.CreateNew, FileAccess.Write, FileShare.None);
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
|
||||
@@ -2,12 +2,14 @@ using Content.Client.GameObjects.Components.Observer;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
|
||||
namespace Content.Client.UserInterface
|
||||
{
|
||||
public class GhostGui : Control
|
||||
{
|
||||
public Button ReturnToBody = new Button(){Text = "Return to body"};
|
||||
|
||||
public readonly Button ReturnToBody = new Button() {Text = Loc.GetString("Return to body")};
|
||||
private GhostComponent _owner;
|
||||
|
||||
public GhostGui(GhostComponent owner)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Content.Client.UserInterface.Suspicion
|
||||
_ => throw new ArgumentException($"Invalid number of allies: {role.Allies.Count}")
|
||||
};
|
||||
|
||||
role.Owner.PopupMessage(role.Owner, message);
|
||||
role.Owner.PopupMessage(message);
|
||||
}
|
||||
|
||||
private bool TryGetComponent(out SuspicionRoleComponent suspicion)
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.Interfaces.Maps;
|
||||
using Robust.Server.Interfaces.Timing;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -25,11 +24,13 @@ namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
var server = StartServerDummyTicker();
|
||||
await server.WaitIdleAsync();
|
||||
var mapMan = server.ResolveDependency<IMapManager>();
|
||||
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var entityMan = server.ResolveDependency<IEntityManager>();
|
||||
var prototypeMan = server.ResolveDependency<IPrototypeManager>();
|
||||
var mapLoader = server.ResolveDependency<IMapLoader>();
|
||||
var pauseMan = server.ResolveDependency<IPauseManager>();
|
||||
var pauseManager = server.ResolveDependency<IPauseManager>();
|
||||
var tileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
|
||||
|
||||
var prototypes = new List<EntityPrototype>();
|
||||
IMapGrid grid = default;
|
||||
IEntity testEntity;
|
||||
@@ -37,9 +38,25 @@ namespace Content.IntegrationTests.Tests
|
||||
//Build up test environment
|
||||
server.Post(() =>
|
||||
{
|
||||
var mapId = mapMan.CreateMap();
|
||||
pauseMan.AddUninitializedMap(mapId);
|
||||
grid = mapLoader.LoadBlueprint(mapId, "Maps/stationstation.yml");
|
||||
// Create a one tile grid to stave off the grid 0 monsters
|
||||
var mapId = mapManager.CreateMap();
|
||||
|
||||
pauseManager.AddUninitializedMap(mapId);
|
||||
|
||||
var gridId = new GridId(1);
|
||||
|
||||
if (!mapManager.TryGetGrid(gridId, out grid))
|
||||
{
|
||||
grid = mapManager.CreateGrid(mapId, gridId);
|
||||
}
|
||||
|
||||
var tileDefinition = tileDefinitionManager["underplating"];
|
||||
var tile = new Tile(tileDefinition.TileId);
|
||||
var coordinates = new GridCoordinates(0, 0, gridId);
|
||||
|
||||
grid.SetTile(coordinates, tile);
|
||||
|
||||
pauseManager.DoMapInitialize(mapId);
|
||||
});
|
||||
|
||||
server.Assert(() =>
|
||||
|
||||
102
Content.IntegrationTests/Tests/Fluids/PuddleTest.cs
Normal file
102
Content.IntegrationTests/Tests/Fluids/PuddleTest.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.Fluids;
|
||||
using Content.Shared.Chemistry;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.Interfaces.Timing;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Fluids
|
||||
{
|
||||
[TestFixture]
|
||||
[TestOf(typeof(PuddleComponent))]
|
||||
public class PuddleTest : ContentIntegrationTest
|
||||
{
|
||||
[Test]
|
||||
public async Task TilePuddleTest()
|
||||
{
|
||||
var server = StartServerDummyTicker();
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var pauseManager = server.ResolveDependency<IPauseManager>();
|
||||
var tileDefinitionManager = server.ResolveDependency<ITileDefinitionManager>();
|
||||
|
||||
GridCoordinates coordinates = default;
|
||||
|
||||
// Build up test environment
|
||||
server.Post(() =>
|
||||
{
|
||||
// Create a one tile grid to spill onto
|
||||
var mapId = mapManager.CreateMap();
|
||||
|
||||
pauseManager.AddUninitializedMap(mapId);
|
||||
|
||||
var gridId = new GridId(1);
|
||||
|
||||
if (!mapManager.TryGetGrid(gridId, out var grid))
|
||||
{
|
||||
grid = mapManager.CreateGrid(mapId, gridId);
|
||||
}
|
||||
|
||||
var tileDefinition = tileDefinitionManager["underplating"];
|
||||
var tile = new Tile(tileDefinition.TileId);
|
||||
coordinates = new GridCoordinates(0, 0, gridId);
|
||||
|
||||
grid.SetTile(coordinates, tile);
|
||||
|
||||
pauseManager.DoMapInitialize(mapId);
|
||||
});
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
server.Assert(() =>
|
||||
{
|
||||
var solution = new Solution("water", ReagentUnit.New(20));
|
||||
var puddle = solution.SpillAt(coordinates, "PuddleSmear");
|
||||
Assert.NotNull(puddle);
|
||||
});
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SpaceNoPuddleTest()
|
||||
{
|
||||
var server = StartServerDummyTicker();
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var pauseManager = server.ResolveDependency<IPauseManager>();
|
||||
|
||||
// Build up test environment
|
||||
server.Post(() =>
|
||||
{
|
||||
var mapId = mapManager.CreateMap();
|
||||
|
||||
pauseManager.AddUninitializedMap(mapId);
|
||||
|
||||
var gridId = new GridId(1);
|
||||
|
||||
if (!mapManager.GridExists(gridId))
|
||||
{
|
||||
mapManager.CreateGrid(mapId, gridId);
|
||||
}
|
||||
});
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
server.Assert(() =>
|
||||
{
|
||||
var gridId = new GridId(1);
|
||||
var coordinates = new GridCoordinates(0, 0, gridId);
|
||||
var solution = new Solution("water", ReagentUnit.New(20));
|
||||
var puddle = solution.SpillAt(coordinates, "PuddleSmear");
|
||||
Assert.Null(puddle);
|
||||
});
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Content.IntegrationTests/Tests/PostMapInitTest.cs
Normal file
60
Content.IntegrationTests/Tests/PostMapInitTest.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.Interfaces.Resources;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.IntegrationTests.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class PostMapInitTest : ContentIntegrationTest
|
||||
{
|
||||
public readonly string[] SkippedMaps =
|
||||
{
|
||||
"/Maps/Pathfinding/simple.yml"
|
||||
};
|
||||
|
||||
[Test]
|
||||
public async Task NoSavedPostMapInitTest()
|
||||
{
|
||||
var server = StartServerDummyTicker();
|
||||
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var resourceManager = server.ResolveDependency<IResourceManager>();
|
||||
var mapFolder = new ResourcePath("/Maps");
|
||||
var maps = resourceManager
|
||||
.ContentFindFiles(mapFolder)
|
||||
.Where(filePath => filePath.Extension == "yml" && !filePath.Filename.StartsWith("."))
|
||||
.ToArray();
|
||||
|
||||
foreach (var map in maps)
|
||||
{
|
||||
var rootedPath = map.ToRootedPath();
|
||||
|
||||
if (SkippedMaps.Contains(rootedPath.ToString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!resourceManager.TryContentFileRead(rootedPath, out var fileStream))
|
||||
{
|
||||
Assert.Fail($"Map not found: {rootedPath}");
|
||||
}
|
||||
|
||||
using var reader = new StreamReader(fileStream);
|
||||
var yamlStream = new YamlStream();
|
||||
|
||||
yamlStream.Load(reader);
|
||||
|
||||
var root = yamlStream.Documents[0].RootNode;
|
||||
var meta = root["meta"];
|
||||
var postMapInit = meta["postmapinit"].AsBool();
|
||||
|
||||
Assert.False(postMapInit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Content.Server/Administration/DeleteEntitiesWithId.cs
Normal file
39
Content.Server/Administration/DeleteEntitiesWithId.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#nullable enable
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.Administration
|
||||
{
|
||||
public class DeleteEntitiesWithId : IClientCommand
|
||||
{
|
||||
public string Command => "deleteewi";
|
||||
public string Description => "Deletes entities with the specified prototype ID.";
|
||||
public string Help => $"Usage: {Command} <prototypeID>";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
|
||||
{
|
||||
if (args.Length != 1)
|
||||
{
|
||||
shell.SendText(player, Help);
|
||||
return;
|
||||
}
|
||||
|
||||
var id = args[0].ToLower();
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var query = new PredicateEntityQuery(e => e.Prototype?.ID.ToLower() == id);
|
||||
var entities = entityManager.GetEntities(query);
|
||||
var i = 0;
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
entity.Delete();
|
||||
i++;
|
||||
}
|
||||
|
||||
shell.SendText(player, $"Deleted all entities with id {id}. Occurrences: {i}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
@@ -13,13 +13,11 @@ using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class GasSprayerComponent : Component, IAfterInteract
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||
|
||||
//TODO: create a function that can create a gas based on a solution mix
|
||||
@@ -48,7 +46,7 @@ namespace Content.Server.Atmos
|
||||
|
||||
if (tank.Solution.GetReagentQuantity(_fuelType) == 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, eventArgs.User,
|
||||
Owner.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("{0:theName} is out of {1}!", Owner, _fuelName));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Content.Server.Body
|
||||
{
|
||||
private IBodyManagerComponent? _body;
|
||||
|
||||
private readonly HashSet<Mechanism> _mechanisms = new HashSet<Mechanism>();
|
||||
private readonly HashSet<IMechanism> _mechanisms = new HashSet<IMechanism>();
|
||||
|
||||
public BodyPart(BodyPartPrototype data)
|
||||
{
|
||||
@@ -146,11 +146,11 @@ namespace Content.Server.Body
|
||||
public BodyPartCompatibility Compatibility { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set of all <see cref="Mechanism"/> currently inside this
|
||||
/// Set of all <see cref="IMechanism"/> currently inside this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public IReadOnlyCollection<Mechanism> Mechanisms => _mechanisms;
|
||||
public IReadOnlyCollection<IMechanism> Mechanisms => _mechanisms;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by
|
||||
@@ -258,7 +258,7 @@ namespace Content.Server.Body
|
||||
return SurgeryData.CanAttachBodyPart(part);
|
||||
}
|
||||
|
||||
public bool CanInstallMechanism(Mechanism mechanism)
|
||||
public bool CanInstallMechanism(IMechanism mechanism)
|
||||
{
|
||||
return SizeUsed + mechanism.Size <= Size &&
|
||||
SurgeryData.CanInstallMechanism(mechanism);
|
||||
@@ -275,7 +275,7 @@ namespace Content.Server.Body
|
||||
/// True if successful, false if there was an error
|
||||
/// (e.g. not enough room in <see cref="IBodyPart"/>).
|
||||
/// </returns>
|
||||
private bool TryInstallMechanism(Mechanism mechanism)
|
||||
private bool TryInstallMechanism(IMechanism mechanism)
|
||||
{
|
||||
if (!CanInstallMechanism(mechanism))
|
||||
{
|
||||
@@ -308,7 +308,7 @@ namespace Content.Server.Body
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryDropMechanism(IEntity dropLocation, Mechanism mechanismTarget,
|
||||
public bool TryDropMechanism(IEntity dropLocation, IMechanism mechanismTarget,
|
||||
[NotNullWhen(true)] out DroppedMechanismComponent dropped)
|
||||
{
|
||||
dropped = null!;
|
||||
@@ -331,16 +331,16 @@ namespace Content.Server.Body
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to destroy the given <see cref="Mechanism"/> in this
|
||||
/// Tries to destroy the given <see cref="IMechanism"/> in this
|
||||
/// <see cref="IBodyPart"/>. Does NOT spawn a dropped entity.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Tries to destroy the given <see cref="Mechanism"/> in this
|
||||
/// Tries to destroy the given <see cref="IMechanism"/> in this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <param name="mechanismTarget">The mechanism to destroy.</param>
|
||||
/// <returns>True if successful, false otherwise.</returns>
|
||||
public bool DestroyMechanism(Mechanism mechanismTarget)
|
||||
public bool DestroyMechanism(IMechanism mechanismTarget)
|
||||
{
|
||||
if (!RemoveMechanism(mechanismTarget))
|
||||
{
|
||||
@@ -365,7 +365,7 @@ namespace Content.Server.Body
|
||||
return SurgeryData.PerformSurgery(toolType, target, surgeon, performer);
|
||||
}
|
||||
|
||||
private void AddMechanism(Mechanism mechanism)
|
||||
private void AddMechanism(IMechanism mechanism)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
@@ -402,7 +402,7 @@ namespace Content.Server.Body
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to remove.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
private bool RemoveMechanism(Mechanism mechanism)
|
||||
private bool RemoveMechanism(IMechanism mechanism)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
|
||||
@@ -54,12 +54,12 @@ namespace Content.Server.Body
|
||||
int CurrentDurability { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Collection of all <see cref="Mechanism"/>s currently inside this
|
||||
/// Collection of all <see cref="IMechanism"/>s currently inside this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// To add and remove from this list see <see cref="AddMechanism"/> and
|
||||
/// <see cref="RemoveMechanism"/>
|
||||
/// </summary>
|
||||
IReadOnlyCollection<Mechanism> Mechanisms { get; }
|
||||
IReadOnlyCollection<IMechanism> Mechanisms { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to the RSI that represents this <see cref="IBodyPart"/>.
|
||||
@@ -109,23 +109,23 @@ namespace Content.Server.Body
|
||||
bool CanAttachPart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a <see cref="Mechanism"/> can be installed on this
|
||||
/// Checks if a <see cref="IMechanism"/> can be installed on this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <returns>True if it can be installed, false otherwise.</returns>
|
||||
bool CanInstallMechanism(Mechanism mechanism);
|
||||
bool CanInstallMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove the given <see cref="Mechanism"/> reference from
|
||||
/// Tries to remove the given <see cref="IMechanism"/> reference from
|
||||
/// this <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The newly spawned <see cref="DroppedMechanismComponent"/>, or null
|
||||
/// if there was an error in spawning the entity or removing the mechanism.
|
||||
/// </returns>
|
||||
bool TryDropMechanism(IEntity dropLocation, Mechanism mechanismTarget,
|
||||
bool TryDropMechanism(IEntity dropLocation, IMechanism mechanismTarget,
|
||||
[NotNullWhen(true)] out DroppedMechanismComponent dropped);
|
||||
|
||||
bool DestroyMechanism(Mechanism mechanism);
|
||||
bool DestroyMechanism(IMechanism mechanism);
|
||||
}
|
||||
}
|
||||
|
||||
103
Content.Server/Body/Mechanisms/IMechanism.cs
Normal file
103
Content.Server/Body/Mechanisms/IMechanism.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Body.Mechanisms.Behaviors;
|
||||
using Content.Server.GameObjects.Components.Body;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
|
||||
namespace Content.Server.Body.Mechanisms
|
||||
{
|
||||
public interface IMechanism
|
||||
{
|
||||
string Id { get; }
|
||||
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Professional description of the <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The message to display upon examining a mob with this Mechanism installed.
|
||||
/// If the string is empty (""), no message will be displayed.
|
||||
/// </summary>
|
||||
string ExamineMessage { get; set; }
|
||||
|
||||
// TODO: Make RSI properties sane
|
||||
/// <summary>
|
||||
/// Path to the RSI that represents this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
string RSIPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// RSI state that represents this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
string RSIState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Max HP of this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
int MaxDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current HP of this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
int CurrentDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// At what HP this <see cref="IMechanism"/> is completely destroyed.
|
||||
/// </summary>
|
||||
int DestroyThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Armor of this <see cref="IMechanism"/> against attacks.
|
||||
/// </summary>
|
||||
int Resistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines a handful of things - mostly whether this
|
||||
/// <see cref="IMechanism"/> can fit into a <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
// TODO: OnSizeChanged
|
||||
int Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What kind of <see cref="IBodyPart"/> this <see cref="IMechanism"/> can be
|
||||
/// easily installed into.
|
||||
/// </summary>
|
||||
BodyPartCompatibility Compatibility { get; set; }
|
||||
|
||||
IReadOnlyList<MechanismBehavior> Behaviors { get; }
|
||||
|
||||
IBodyManagerComponent? Body { get; }
|
||||
|
||||
IBodyPart? Part { get; set; }
|
||||
|
||||
void EnsureInitialize();
|
||||
|
||||
void InstalledIntoBody();
|
||||
|
||||
void RemovedFromBody(IBodyManagerComponent old);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by <see cref="IBodyPart.PreMetabolism"/> before
|
||||
/// <see cref="MetabolismComponent.Update"/> is called.
|
||||
/// </summary>
|
||||
void PreMetabolism(float frameTime);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by <see cref="IBodyPart.PostMetabolism"/> after
|
||||
/// <see cref="MetabolismComponent.Update"/> is called.
|
||||
/// </summary>
|
||||
void PostMetabolism(float frameTime);
|
||||
|
||||
void AddBehavior(MechanismBehavior behavior);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a behavior from this mechanism.
|
||||
/// </summary>
|
||||
/// <param name="behavior">The behavior to remove.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
bool RemoveBehavior(MechanismBehavior behavior);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace Content.Server.Body.Mechanisms
|
||||
/// This includes livers, eyes, cameras, brains, explosive implants,
|
||||
/// binary communicators, and other things.
|
||||
/// </summary>
|
||||
public class Mechanism
|
||||
public class Mechanism : IMechanism
|
||||
{
|
||||
private IBodyPart? _part;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Content.Server.Body.Mechanisms
|
||||
ExamineMessage = null!;
|
||||
RSIPath = null!;
|
||||
RSIState = null!;
|
||||
Behaviors = new List<MechanismBehavior>();
|
||||
_behaviors = new List<MechanismBehavior>();
|
||||
}
|
||||
|
||||
[ViewVariables] private bool Initialized { get; set; }
|
||||
@@ -40,74 +40,29 @@ namespace Content.Server.Body.Mechanisms
|
||||
|
||||
[ViewVariables] public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Professional description of the <see cref="Mechanism"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string Description { get; set; }
|
||||
[ViewVariables] public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The message to display upon examining a mob with this Mechanism installed.
|
||||
/// If the string is empty (""), no message will be displayed.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string ExamineMessage { get; set; }
|
||||
[ViewVariables] public string ExamineMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Path to the RSI that represents this <see cref="Mechanism"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string RSIPath { get; set; }
|
||||
[ViewVariables] public string RSIPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// RSI state that represents this <see cref="Mechanism"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string RSIState { get; set; }
|
||||
[ViewVariables] public string RSIState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Max HP of this <see cref="Mechanism"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int MaxDurability { get; set; }
|
||||
[ViewVariables] public int MaxDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current HP of this <see cref="Mechanism"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int CurrentDurability { get; set; }
|
||||
[ViewVariables] public int CurrentDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// At what HP this <see cref="Mechanism"/> is completely destroyed.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int DestroyThreshold { get; set; }
|
||||
[ViewVariables] public int DestroyThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Armor of this <see cref="Mechanism"/> against attacks.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int Resistance { get; set; }
|
||||
[ViewVariables] public int Resistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines a handful of things - mostly whether this
|
||||
/// <see cref="Mechanism"/> can fit into a <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int Size { get; set; }
|
||||
[ViewVariables] public int Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What kind of <see cref="IBodyPart"/> this <see cref="Mechanism"/> can be
|
||||
/// easily installed into.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public BodyPartCompatibility Compatibility { get; set; }
|
||||
[ViewVariables] public BodyPartCompatibility Compatibility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The behaviors that this <see cref="Mechanism"/> performs.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private List<MechanismBehavior> Behaviors { get; }
|
||||
private readonly List<MechanismBehavior> _behaviors;
|
||||
|
||||
[ViewVariables] public IReadOnlyList<MechanismBehavior> Behaviors => _behaviors;
|
||||
|
||||
public IBodyManagerComponent? Body => Part?.Body;
|
||||
|
||||
@@ -167,7 +122,7 @@ namespace Content.Server.Body.Mechanisms
|
||||
Size = data.Size;
|
||||
Compatibility = data.Compatibility;
|
||||
|
||||
foreach (var behavior in Behaviors.ToArray())
|
||||
foreach (var behavior in _behaviors.ToArray())
|
||||
{
|
||||
RemoveBehavior(behavior);
|
||||
}
|
||||
@@ -210,10 +165,6 @@ namespace Content.Server.Body.Mechanisms
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by <see cref="IBodyPart.PreMetabolism"/> before
|
||||
/// <see cref="MetabolismComponent.Update"/> is called.
|
||||
/// </summary>
|
||||
public void PreMetabolism(float frameTime)
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
@@ -222,10 +173,6 @@ namespace Content.Server.Body.Mechanisms
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by <see cref="IBodyPart.PostMetabolism"/> after
|
||||
/// <see cref="MetabolismComponent.Update"/> is called.
|
||||
/// </summary>
|
||||
public void PostMetabolism(float frameTime)
|
||||
{
|
||||
foreach (var behavior in Behaviors)
|
||||
@@ -234,16 +181,21 @@ namespace Content.Server.Body.Mechanisms
|
||||
}
|
||||
}
|
||||
|
||||
private void AddBehavior(MechanismBehavior behavior)
|
||||
public void AddBehavior(MechanismBehavior behavior)
|
||||
{
|
||||
Behaviors.Add(behavior);
|
||||
_behaviors.Add(behavior);
|
||||
behavior.Initialize(this);
|
||||
}
|
||||
|
||||
private bool RemoveBehavior(MechanismBehavior behavior)
|
||||
public bool RemoveBehavior(MechanismBehavior behavior)
|
||||
{
|
||||
behavior.Remove();
|
||||
return Behaviors.Remove(behavior);
|
||||
if (_behaviors.Remove(behavior))
|
||||
{
|
||||
behavior.Remove();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Content.Server.Body.Surgery
|
||||
[UsedImplicitly]
|
||||
public class BiologicalSurgeryData : SurgeryData
|
||||
{
|
||||
private readonly List<Mechanism> _disconnectedOrgans = new List<Mechanism>();
|
||||
private readonly List<IMechanism> _disconnectedOrgans = new List<IMechanism>();
|
||||
|
||||
private bool _skinOpened;
|
||||
private bool _skinRetracted;
|
||||
@@ -118,7 +118,7 @@ namespace Content.Server.Body.Surgery
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public override bool CanInstallMechanism(Mechanism mechanism)
|
||||
public override bool CanInstallMechanism(IMechanism mechanism)
|
||||
{
|
||||
return _skinOpened && _vesselsClamped && _skinRetracted;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ namespace Content.Server.Body.Surgery
|
||||
|
||||
private void OpenSkinSurgery(IBodyPartContainer container, ISurgeon surgeon, IEntity performer)
|
||||
{
|
||||
performer.PopupMessage(performer, Loc.GetString("Cut open the skin..."));
|
||||
performer.PopupMessage(Loc.GetString("Cut open the skin..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
_skinOpened = true;
|
||||
@@ -139,7 +139,7 @@ namespace Content.Server.Body.Surgery
|
||||
|
||||
private void ClampVesselsSurgery(IBodyPartContainer container, ISurgeon surgeon, IEntity performer)
|
||||
{
|
||||
performer.PopupMessage(performer, Loc.GetString("Clamp the vessels..."));
|
||||
performer.PopupMessage(Loc.GetString("Clamp the vessels..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
_vesselsClamped = true;
|
||||
@@ -147,7 +147,7 @@ namespace Content.Server.Body.Surgery
|
||||
|
||||
private void RetractSkinSurgery(IBodyPartContainer container, ISurgeon surgeon, IEntity performer)
|
||||
{
|
||||
performer.PopupMessage(performer, Loc.GetString("Retract the skin..."));
|
||||
performer.PopupMessage(Loc.GetString("Retract the skin..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
_skinRetracted = true;
|
||||
@@ -155,7 +155,7 @@ namespace Content.Server.Body.Surgery
|
||||
|
||||
private void CauterizeIncisionSurgery(IBodyPartContainer container, ISurgeon surgeon, IEntity performer)
|
||||
{
|
||||
performer.PopupMessage(performer, Loc.GetString("Cauterize the incision..."));
|
||||
performer.PopupMessage(Loc.GetString("Cauterize the incision..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
_skinOpened = false;
|
||||
@@ -170,7 +170,7 @@ namespace Content.Server.Body.Surgery
|
||||
return;
|
||||
}
|
||||
|
||||
var toSend = new List<Mechanism>();
|
||||
var toSend = new List<IMechanism>();
|
||||
foreach (var mechanism in Parent.Mechanisms)
|
||||
{
|
||||
if (!_disconnectedOrgans.Contains(mechanism))
|
||||
@@ -185,7 +185,7 @@ namespace Content.Server.Body.Surgery
|
||||
}
|
||||
}
|
||||
|
||||
private void LoosenOrganSurgeryCallback(Mechanism target, IBodyPartContainer container, ISurgeon surgeon,
|
||||
private void LoosenOrganSurgeryCallback(IMechanism target, IBodyPartContainer container, ISurgeon surgeon,
|
||||
IEntity performer)
|
||||
{
|
||||
if (target == null || !Parent.Mechanisms.Contains(target))
|
||||
@@ -193,7 +193,7 @@ namespace Content.Server.Body.Surgery
|
||||
return;
|
||||
}
|
||||
|
||||
performer.PopupMessage(performer, Loc.GetString("Loosen the organ..."));
|
||||
performer.PopupMessage(Loc.GetString("Loosen the organ..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
_disconnectedOrgans.Add(target);
|
||||
@@ -216,7 +216,7 @@ namespace Content.Server.Body.Surgery
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveOrganSurgeryCallback(Mechanism target, IBodyPartContainer container, ISurgeon surgeon,
|
||||
private void RemoveOrganSurgeryCallback(IMechanism target, IBodyPartContainer container, ISurgeon surgeon,
|
||||
IEntity performer)
|
||||
{
|
||||
if (target == null || !Parent.Mechanisms.Contains(target))
|
||||
@@ -224,7 +224,7 @@ namespace Content.Server.Body.Surgery
|
||||
return;
|
||||
}
|
||||
|
||||
performer.PopupMessage(performer, Loc.GetString("Remove the organ..."));
|
||||
performer.PopupMessage(Loc.GetString("Remove the organ..."));
|
||||
|
||||
// TODO do_after: Delay
|
||||
Parent.TryDropMechanism(performer, target, out _);
|
||||
@@ -240,7 +240,7 @@ namespace Content.Server.Body.Surgery
|
||||
}
|
||||
|
||||
var bmTarget = (BodyManagerComponent) container;
|
||||
performer.PopupMessage(performer, Loc.GetString("Saw off the limb!"));
|
||||
performer.PopupMessage(Loc.GetString("Saw off the limb!"));
|
||||
|
||||
// TODO do_after: Delay
|
||||
bmTarget.DisconnectBodyPart(Parent, true);
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Content.Server.Body.Surgery
|
||||
public interface ISurgeon
|
||||
{
|
||||
public delegate void MechanismRequestCallback(
|
||||
Mechanism target,
|
||||
IMechanism target,
|
||||
IBodyPartContainer container,
|
||||
ISurgeon surgeon,
|
||||
IEntity performer);
|
||||
@@ -29,6 +29,6 @@ namespace Content.Server.Body.Surgery
|
||||
/// This function is called in that scenario, and it is expected that you call the callback with one mechanism from the
|
||||
/// provided list.
|
||||
/// </summary>
|
||||
public void RequestMechanism(IEnumerable<Mechanism> options, MechanismRequestCallback callback);
|
||||
public void RequestMechanism(IEnumerable<IMechanism> options, MechanismRequestCallback callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace Content.Server.Body.Surgery
|
||||
public abstract string GetDescription(IEntity target);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a <see cref="Mechanism"/> can be installed into the
|
||||
/// Returns whether a <see cref="IMechanism"/> can be installed into the
|
||||
/// <see cref="IBodyPart"/> this <see cref="SurgeryData"/> represents.
|
||||
/// </summary>
|
||||
public abstract bool CanInstallMechanism(Mechanism mechanism);
|
||||
public abstract bool CanInstallMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="IBodyPart"/> can be connected to the
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Observer;
|
||||
using Content.Server.Players;
|
||||
using Content.Server.Utility;
|
||||
@@ -120,7 +119,6 @@ namespace Content.Server.Chat
|
||||
internal class SuicideCommand : IClientCommand
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public string Command => "suicide";
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.GameObjects.Components.Access;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
@@ -25,7 +25,6 @@ namespace Content.Server.GameObjects.Components.Access
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public class IdCardConsoleComponent : SharedIdCardConsoleComponent, IActivate
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private ContainerSlot _privilegedIdContainer = default!;
|
||||
@@ -132,7 +131,7 @@ namespace Content.Server.GameObjects.Components.Access
|
||||
{
|
||||
if (!user.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(user, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,7 +160,7 @@ namespace Content.Server.GameObjects.Components.Access
|
||||
|
||||
if (!hands.Drop(hands.ActiveHand, container))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, Loc.GetString("You can't let go of the ID card!"));
|
||||
Owner.PopupMessage(user, Loc.GetString("You can't let go of the ID card!"));
|
||||
return;
|
||||
}
|
||||
UpdateUserInterface();
|
||||
|
||||
@@ -4,7 +4,6 @@ using Content.Shared.Interfaces;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -22,7 +21,6 @@ using Robust.Shared.Maths;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Utility;
|
||||
using Serilog;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
@@ -30,9 +28,6 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
[RegisterComponent]
|
||||
public class CuffableComponent : SharedCuffableComponent
|
||||
{
|
||||
[Dependency]
|
||||
private readonly ISharedNotifyManager _notifyManager;
|
||||
|
||||
/// <summary>
|
||||
/// How many of this entity's hands are currently cuffed.
|
||||
/// </summary>
|
||||
@@ -231,13 +226,13 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
|
||||
if (!isOwner && !ActionBlockerSystem.CanInteract(user))
|
||||
{
|
||||
user.PopupMessage(user, Loc.GetString("You can't do that!"));
|
||||
user.PopupMessage(Loc.GetString("You can't do that!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isOwner && user.InRangeUnobstructed(Owner, _interactRange))
|
||||
{
|
||||
user.PopupMessage(user, Loc.GetString("You are too far away to remove the cuffs."));
|
||||
user.PopupMessage(Loc.GetString("You are too far away to remove the cuffs."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,7 +242,7 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
return;
|
||||
}
|
||||
|
||||
user.PopupMessage(user, Loc.GetString("You start removing the cuffs."));
|
||||
user.PopupMessage(Loc.GetString("You start removing the cuffs."));
|
||||
|
||||
var audio = EntitySystem.Get<AudioSystem>();
|
||||
audio.PlayFromEntity(isOwner ? cuff.StartBreakoutSound : cuff.StartUncuffSound, Owner);
|
||||
@@ -292,29 +287,29 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
|
||||
if (CuffedHandCount == 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user, Loc.GetString("You successfully remove the cuffs."));
|
||||
user.PopupMessage(Loc.GetString("You successfully remove the cuffs."));
|
||||
|
||||
if (!isOwner)
|
||||
{
|
||||
_notifyManager.PopupMessage(user, Owner, Loc.GetString("{0:theName} uncuffs your hands.", user));
|
||||
user.PopupMessage(Owner, Loc.GetString("{0:theName} uncuffs your hands.", user));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user, Loc.GetString("You successfully remove the cuffs. {0} of {1:theName}'s hands remain cuffed.", CuffedHandCount, user));
|
||||
_notifyManager.PopupMessage(user, Owner, Loc.GetString("{0:theName} removes your cuffs. {1} of your hands remain cuffed.", user, CuffedHandCount));
|
||||
user.PopupMessage(Loc.GetString("You successfully remove the cuffs. {0} of {1:theName}'s hands remain cuffed.", CuffedHandCount, user));
|
||||
user.PopupMessage(Owner, Loc.GetString("{0:theName} removes your cuffs. {1} of your hands remain cuffed.", user, CuffedHandCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user, Loc.GetString("You successfully remove the cuffs. {0} of your hands remain cuffed.", CuffedHandCount));
|
||||
user.PopupMessage(Loc.GetString("You successfully remove the cuffs. {0} of your hands remain cuffed.", CuffedHandCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user, Loc.GetString("You fail to remove the cuffs."));
|
||||
user.PopupMessage(Loc.GetString("You fail to remove the cuffs."));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -23,9 +23,6 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
[RegisterComponent]
|
||||
public class HandcuffComponent : SharedHandcuffComponent, IAfterInteract
|
||||
{
|
||||
[Dependency]
|
||||
private readonly ISharedNotifyManager _notifyManager;
|
||||
|
||||
/// <summary>
|
||||
/// The time it takes to apply a <see cref="CuffedComponent"/> to an entity.
|
||||
/// </summary>
|
||||
@@ -161,36 +158,36 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
|
||||
if (eventArgs.Target == eventArgs.User)
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You can't cuff yourself!"));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You can't cuff yourself!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Broken)
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("The cuffs are broken!"));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("The cuffs are broken!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!eventArgs.Target.TryGetComponent<HandsComponent>(out var hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("{0:theName} has no hands!", eventArgs.Target));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("{0:theName} has no hands!", eventArgs.Target));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cuffed.CuffedHandCount == hands.Count)
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("{0:theName} has no free hands to handcuff!", eventArgs.Target));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("{0:theName} has no free hands to handcuff!", eventArgs.Target));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!eventArgs.InRangeUnobstructed(_interactRange, ignoreInsideBlocker: true))
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You are too far away to use the cuffs!"));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You are too far away to use the cuffs!"));
|
||||
return;
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You start cuffing {0:theName}.", eventArgs.Target));
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.Target, Loc.GetString("{0:theName} starts cuffing you!", eventArgs.User));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You start cuffing {0:theName}.", eventArgs.Target));
|
||||
eventArgs.User.PopupMessage(eventArgs.Target, Loc.GetString("{0:theName} starts cuffing you!", eventArgs.User));
|
||||
_audioSystem.PlayFromEntity(StartCuffSound, Owner);
|
||||
|
||||
TryUpdateCuff(eventArgs.User, eventArgs.Target, cuffed);
|
||||
@@ -222,8 +219,8 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
if (result != DoAfterStatus.Cancelled)
|
||||
{
|
||||
_audioSystem.PlayFromEntity(EndCuffSound, Owner);
|
||||
_notifyManager.PopupMessage(user, user, Loc.GetString("You successfully cuff {0:theName}.", target));
|
||||
_notifyManager.PopupMessage(target, target, Loc.GetString("You have been cuffed by {0:theName}!", user));
|
||||
user.PopupMessage(Loc.GetString("You successfully cuff {0:theName}.", target));
|
||||
target.PopupMessage(Loc.GetString("You have been cuffed by {0:theName}!", user));
|
||||
|
||||
if (user.TryGetComponent<HandsComponent>(out var hands))
|
||||
{
|
||||
@@ -237,8 +234,8 @@ namespace Content.Server.GameObjects.Components.ActionBlocking
|
||||
}
|
||||
else
|
||||
{
|
||||
user.PopupMessage(user, Loc.GetString("You were interrupted while cuffing {0:theName}!", target));
|
||||
target.PopupMessage(target, Loc.GetString("You interrupt {0:theName} while they are cuffing you!", user));
|
||||
user.PopupMessage(Loc.GetString("You were interrupted while cuffing {0:theName}!", target));
|
||||
target.PopupMessage(Loc.GetString("You interrupt {0:theName} while they are cuffing you!", user));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
@@ -24,7 +24,6 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
[RegisterComponent]
|
||||
public class GasAnalyzerComponent : SharedGasAnalyzerComponent, IAfterInteract, IDropped, IUse
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
private GasAnalyzerDanger _pressureDanger;
|
||||
@@ -207,17 +206,14 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
|
||||
if (!player.TryGetComponent(out IHandsComponent? handsComponent))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(player, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
||||
if (activeHandEntity == null || !activeHandEntity.TryGetComponent(out GasAnalyzerComponent? gasAnalyzer))
|
||||
{
|
||||
_notifyManager.PopupMessage(serverMsg.Session.AttachedEntity,
|
||||
serverMsg.Session.AttachedEntity,
|
||||
Loc.GetString("You need a Gas Analyzer in your hand!"));
|
||||
serverMsg.Session.AttachedEntity.PopupMessage(Loc.GetString("You need a Gas Analyzer in your hand!"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,7 +227,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
{
|
||||
if (!eventArgs.CanReach)
|
||||
{
|
||||
_notifyManager.PopupMessage(eventArgs.User, eventArgs.User, Loc.GetString("You can't reach there!"));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You can't reach there!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
public class GridAtmosphereComponent : Component, IGridAtmosphereComponent
|
||||
{
|
||||
[Robust.Shared.IoC.Dependency] private IMapManager _mapManager = default!;
|
||||
[Robust.Shared.IoC.Dependency] private ITileDefinitionManager _tileDefinitionManager = default!;
|
||||
[Robust.Shared.IoC.Dependency] private IServerEntityManager _serverEntityManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Check current execution time every n instances processed.
|
||||
@@ -162,14 +164,13 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
var mapGrid = mapGridComponent.Grid;
|
||||
var tile = mapGrid.GetTileRef(indices).Tile;
|
||||
|
||||
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
|
||||
var tileDef = (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
|
||||
var tileDef = (ContentTileDefinition) _tileDefinitionManager[tile.TypeId];
|
||||
|
||||
var underplating = tileDefinitionManager["underplating"];
|
||||
var underplating = _tileDefinitionManager["underplating"];
|
||||
mapGrid.SetTile(indices, new Tile(underplating.TileId));
|
||||
|
||||
//Actually spawn the relevant tile item at the right position and give it some offset to the corner.
|
||||
var tileItem = IoCManager.Resolve<IServerEntityManager>().SpawnEntity(tileDef.ItemDropPrototypeName, new GridCoordinates(indices.X, indices.Y, mapGrid));
|
||||
var tileItem = _serverEntityManager.SpawnEntity(tileDef.ItemDropPrototypeName, new GridCoordinates(indices.X, indices.Y, mapGrid));
|
||||
tileItem.Transform.WorldPosition += (0.2f, 0.2f);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Server.Body;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Body.Surgery;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -24,8 +23,6 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
[RegisterComponent]
|
||||
public class DroppedBodyPartComponent : Component, IAfterInteract, IBodyPartContainer
|
||||
{
|
||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||
|
||||
private readonly Dictionary<int, object> _optionsCache = new Dictionary<int, object>();
|
||||
private BodyManagerComponent? _bodyManagerComponentCache;
|
||||
private int _idHash;
|
||||
@@ -121,7 +118,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
}
|
||||
else // If surgery cannot be performed, show message saying so.
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User,
|
||||
eventArgs.Target.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("You see no way to install {0:theName}.", Owner));
|
||||
}
|
||||
}
|
||||
@@ -147,7 +144,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(_bodyManagerComponentCache.Owner, _performerCache,
|
||||
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache,
|
||||
Loc.GetString("You see no useful way to attach {0:theName} anymore.", Owner));
|
||||
}
|
||||
|
||||
@@ -163,10 +160,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
message = Loc.GetString("You can't attach it!");
|
||||
}
|
||||
|
||||
_sharedNotifyManager.PopupMessage(
|
||||
_bodyManagerComponentCache.Owner,
|
||||
_performerCache,
|
||||
message);
|
||||
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache, message);
|
||||
}
|
||||
|
||||
private void OpenSurgeryUI(IPlayerSession session)
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
[RegisterComponent]
|
||||
public class DroppedMechanismComponent : Component, IAfterInteract
|
||||
{
|
||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public sealed override string Name => "DroppedMechanism";
|
||||
@@ -41,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
|
||||
private IEntity? _performerCache;
|
||||
|
||||
[ViewVariables] public Mechanism ContainedMechanism { get; private set; } = default!;
|
||||
[ViewVariables] public IMechanism ContainedMechanism { get; private set; } = default!;
|
||||
|
||||
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(GenericSurgeryUiKey.Key);
|
||||
|
||||
@@ -67,8 +66,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
|
||||
if (!droppedBodyPart.ContainedBodyPart.TryInstallDroppedMechanism(this))
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User,
|
||||
Loc.GetString("You can't fit it in!"));
|
||||
eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("You can't fit it in!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +81,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
}
|
||||
}
|
||||
|
||||
public void InitializeDroppedMechanism(Mechanism data)
|
||||
public void InitializeDroppedMechanism(IMechanism data)
|
||||
{
|
||||
ContainedMechanism = data;
|
||||
Owner.Name = Loc.GetString(ContainedMechanism.Name);
|
||||
@@ -141,7 +139,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
}
|
||||
else // If surgery cannot be performed, show message saying so.
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(eventArgs.Target, eventArgs.User,
|
||||
eventArgs.Target.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("You see no way to install the {0}.", Owner.Name));
|
||||
}
|
||||
}
|
||||
@@ -167,7 +165,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
// TODO: sanity checks to see whether user is in range, user is still able-bodied, target is still the same, etc etc
|
||||
if (!_optionsCache.TryGetValue(key, out var targetObject))
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(_bodyManagerComponentCache.Owner, _performerCache,
|
||||
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache,
|
||||
Loc.GetString("You see no useful way to use the {0} anymore.", Owner.Name));
|
||||
return;
|
||||
}
|
||||
@@ -177,10 +175,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
? Loc.GetString("You jam the {0} inside {1:them}.", ContainedMechanism.Name, _performerCache)
|
||||
: Loc.GetString("You can't fit it in!");
|
||||
|
||||
_sharedNotifyManager.PopupMessage(
|
||||
_bodyManagerComponentCache.Owner,
|
||||
_performerCache,
|
||||
message);
|
||||
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache, message);
|
||||
|
||||
// TODO: {1:theName}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -34,8 +33,6 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
[RegisterComponent]
|
||||
public class SurgeryToolComponent : Component, ISurgeon, IAfterInteract
|
||||
{
|
||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||
|
||||
public override string Name => "SurgeryTool";
|
||||
public override uint? NetID => ContentNetIDs.SURGERY;
|
||||
|
||||
@@ -131,7 +128,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
|
||||
public float BaseOperationTime { get => _baseOperateTime; set => _baseOperateTime = value; }
|
||||
|
||||
public void RequestMechanism(IEnumerable<Mechanism> options, ISurgeon.MechanismRequestCallback callback)
|
||||
public void RequestMechanism(IEnumerable<IMechanism> options, ISurgeon.MechanismRequestCallback callback)
|
||||
{
|
||||
var toSend = new Dictionary<string, int>();
|
||||
foreach (var mechanism in options)
|
||||
@@ -233,7 +230,7 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
|
||||
/// <summary>
|
||||
/// Called after the client chooses from a list of possible
|
||||
/// <see cref="Mechanism"/> to choose from.
|
||||
/// <see cref="IMechanism"/> to choose from.
|
||||
/// </summary>
|
||||
private void HandleReceiveMechanism(int key)
|
||||
{
|
||||
@@ -254,27 +251,13 @@ namespace Content.Server.GameObjects.Components.Body
|
||||
|
||||
private void SendNoUsefulWayToUsePopup()
|
||||
{
|
||||
if (_bodyManagerComponentCache == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_sharedNotifyManager.PopupMessage(
|
||||
_bodyManagerComponentCache.Owner,
|
||||
_performerCache,
|
||||
_bodyManagerComponentCache?.Owner.PopupMessage(_performerCache,
|
||||
Loc.GetString("You see no useful way to use {0:theName}.", Owner));
|
||||
}
|
||||
|
||||
private void SendNoUsefulWayToUseAnymorePopup()
|
||||
{
|
||||
if (_bodyManagerComponentCache == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_sharedNotifyManager.PopupMessage(
|
||||
_bodyManagerComponentCache.Owner,
|
||||
_performerCache,
|
||||
_bodyManagerComponentCache?.Owner.PopupMessage(_performerCache,
|
||||
Loc.GetString("You see no useful way to use {0:theName} anymore.", Owner));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Mobs.State;
|
||||
using Content.Server.GameObjects.Components.Strap;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects.Components.Buckle;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.Components.Strap;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -38,7 +38,6 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
private int _size;
|
||||
@@ -163,7 +162,7 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanBuckle(IEntity user, IEntity to, [MaybeNullWhen(false)] out StrapComponent strap)
|
||||
private bool CanBuckle(IEntity? user, IEntity to, [MaybeNullWhen(false)] out StrapComponent strap)
|
||||
{
|
||||
strap = null;
|
||||
|
||||
@@ -174,18 +173,16 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!ActionBlockerSystem.CanInteract(user))
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user,
|
||||
Loc.GetString("You can't do that!"));
|
||||
|
||||
user.PopupMessage(Loc.GetString("You can't do that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!to.TryGetComponent(out strap))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user,
|
||||
Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner));
|
||||
var message = Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner);
|
||||
Owner.PopupMessage(user, message);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -195,8 +192,7 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!Owner.InRangeUnobstructed(strap, _range, predicate: Ignored, popup: true))
|
||||
{
|
||||
_notifyManager.PopupMessage(strap.Owner, user,
|
||||
Loc.GetString("You can't reach there!"));
|
||||
strap.Owner.PopupMessage(user, Loc.GetString("You can't reach there!"));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -208,7 +204,7 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
if (!ContainerHelpers.TryGetContainer(strap.Owner, out var strapContainer) ||
|
||||
ownerContainer != strapContainer)
|
||||
{
|
||||
_notifyManager.PopupMessage(strap.Owner, user, Loc.GetString("You can't reach there!"));
|
||||
strap.Owner.PopupMessage(user, Loc.GetString("You can't reach there!"));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -216,18 +212,16 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!user.HasComponent<HandsComponent>())
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user,
|
||||
Loc.GetString("You don't have hands!"));
|
||||
|
||||
user.PopupMessage(Loc.GetString("You don't have hands!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Buckled)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user,
|
||||
Loc.GetString(Owner == user
|
||||
? "You are already buckled in!"
|
||||
: "{0:They} are already buckled in!", Owner));
|
||||
var message = Loc.GetString(Owner == user
|
||||
? "You are already buckled in!"
|
||||
: "{0:They} are already buckled in!", Owner);
|
||||
Owner.PopupMessage(user, message);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -237,10 +231,10 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
{
|
||||
if (parent == user.Transform)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user,
|
||||
Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner));
|
||||
var message = Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner);
|
||||
Owner.PopupMessage(user, message);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -250,10 +244,10 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!strap.HasSpace(this))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user,
|
||||
Loc.GetString(Owner == user
|
||||
? "You can't fit there!"
|
||||
: "{0:They} can't fit there!", Owner));
|
||||
var message = Loc.GetString(Owner == user
|
||||
? "You can't fit there!"
|
||||
: "{0:They} can't fit there!", Owner);
|
||||
Owner.PopupMessage(user, message);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -284,10 +278,10 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!strap.TryAdd(this))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user,
|
||||
Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner));
|
||||
var message = Loc.GetString(Owner == user
|
||||
? "You can't buckle yourself there!"
|
||||
: "You can't buckle {0:them} there!", Owner);
|
||||
Owner.PopupMessage(user, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -338,8 +332,7 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
if (!ActionBlockerSystem.CanInteract(user))
|
||||
{
|
||||
_notifyManager.PopupMessage(user, user,
|
||||
Loc.GetString("You can't do that!"));
|
||||
user.PopupMessage(Loc.GetString("You can't do that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,14 @@ using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Chemistry.ChemMaster;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
@@ -22,11 +23,7 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -43,8 +40,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
[ComponentReference(typeof(IInteractUsing))]
|
||||
public class ChemMasterComponent : SharedChemMasterComponent, IActivate, IInteractUsing, ISolutionChange
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
[ViewVariables] private ContainerSlot _beakerContainer = default!;
|
||||
[ViewVariables] private string _packPrototypeId = "";
|
||||
|
||||
@@ -272,8 +267,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
|
||||
private void TryCreatePackage(IEntity user, UiAction action, int pillAmount, int bottleAmount)
|
||||
{
|
||||
var random = IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
if (BufferSolution.CurrentVolume == 0)
|
||||
return;
|
||||
|
||||
@@ -302,15 +295,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
hands.PutInHand(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Put it on the floor
|
||||
bottle.Transform.GridPosition = user.Transform.GridPosition;
|
||||
//Give it an offset
|
||||
var x_negative = random.Prob(0.5f) ? -1 : 1;
|
||||
var y_negative = random.Prob(0.5f) ? -1 : 1;
|
||||
bottle.Transform.LocalPosition += new Vector2(random.NextFloat() * 0.2f * x_negative, random.NextFloat() * 0.2f * y_negative);
|
||||
bottle.RandomOffset(0.2f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -345,9 +335,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
//Put it on the floor
|
||||
pill.Transform.GridPosition = user.Transform.GridPosition;
|
||||
//Give it an offset
|
||||
var x_negative = random.Prob(0.5f) ? -1 : 1;
|
||||
var y_negative = random.Prob(0.5f) ? -1 : 1;
|
||||
pill.Transform.LocalPosition += new Vector2(random.NextFloat() * 0.2f * x_negative, random.NextFloat() * 0.2f * y_negative);
|
||||
pill.RandomOffset(0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,8 +355,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -390,15 +377,13 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hands.GetActiveHand == null)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have nothing on your hand."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have nothing on your hand."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -407,14 +392,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
if (HasBeaker)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("This ChemMaster already has a container in it."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("This ChemMaster already has a container in it."));
|
||||
}
|
||||
else if ((solution.Capabilities & SolutionCaps.FitsInDispenser) == 0) //Close enough to a chem master...
|
||||
{
|
||||
//If it can't fit in the chem master, don't put it in. For example, buckets and mop buckets can't fit.
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("That can't fit in the ChemMaster."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("That can't fit in the ChemMaster."));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -424,8 +407,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You can't put this in the ChemMaster."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You can't put this in the ChemMaster."));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -435,7 +417,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
|
||||
private void ClickSound()
|
||||
{
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Machines/machine_switch.ogg", Owner, AudioParams.Default.WithVolume(-2f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Server.GameObjects.Components.Body.Circulatory;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Chemistry;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -23,8 +22,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
[RegisterComponent]
|
||||
public class InjectorComponent : SharedInjectorComponent, IAfterInteract, IUse
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the injector is able to draw from containers or if it's a single use
|
||||
/// device that can only inject.
|
||||
@@ -100,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(Owner, user, Loc.GetString(msg));
|
||||
Owner.PopupMessage(user, Loc.GetString(msg));
|
||||
|
||||
Dirty();
|
||||
}
|
||||
@@ -165,8 +162,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
var realTransferAmount = ReagentUnit.Min(_transferAmount, targetBloodstream.EmptyVolume);
|
||||
if (realTransferAmount <= 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Container full."));
|
||||
Owner.PopupMessage(user, Loc.GetString("Container full."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -177,8 +173,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
return;
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Injected {0}u", removedSolution.TotalVolume));
|
||||
Owner.PopupMessage(user, Loc.GetString("Injected {0}u", removedSolution.TotalVolume));
|
||||
Dirty();
|
||||
}
|
||||
|
||||
@@ -194,8 +189,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
var realTransferAmount = ReagentUnit.Min(_transferAmount, targetSolution.EmptyVolume);
|
||||
if (realTransferAmount <= 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Container full."));
|
||||
Owner.PopupMessage(user, Loc.GetString("Container full."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,8 +200,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
return;
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Injected {0}u", removedSolution.TotalVolume));
|
||||
Owner.PopupMessage(user, Loc.GetString("Injected {0}u", removedSolution.TotalVolume));
|
||||
Dirty();
|
||||
}
|
||||
|
||||
@@ -223,8 +216,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
var realTransferAmount = ReagentUnit.Min(_transferAmount, targetSolution.CurrentVolume);
|
||||
if (realTransferAmount <= 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Container empty"));
|
||||
Owner.PopupMessage(user, Loc.GetString("Container empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,8 +227,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
return;
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user,
|
||||
Loc.GetString("Drew {0}u", removedSolution.TotalVolume));
|
||||
Owner.PopupMessage(user, Loc.GetString("Drew {0}u", removedSolution.TotalVolume));
|
||||
Dirty();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -19,8 +18,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
[RegisterComponent]
|
||||
class PourableComponent : Component, IInteractUsing
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public override string Name => "Pourable";
|
||||
|
||||
private ReagentUnit _transferAmount;
|
||||
@@ -87,8 +84,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
var realTransferAmount = ReagentUnit.Min(fromPourable.TransferAmount, toSolution.EmptyVolume);
|
||||
if (realTransferAmount <= 0) //Special message if container is full
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("Container is full"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("Container is full"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,8 +93,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
if (!toSolution.TryAddSolution(removedSolution))
|
||||
return false;
|
||||
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("Transferred {0}u", removedSolution.TotalVolume));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("Transferred {0}u", removedSolution.TotalVolume));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Chemistry.ReagentDispenser;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
@@ -40,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
[ComponentReference(typeof(IInteractUsing))]
|
||||
public class ReagentDispenserComponent : SharedReagentDispenserComponent, IActivate, IInteractUsing, ISolutionChange
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
[ViewVariables] private ContainerSlot _beakerContainer = default!;
|
||||
[ViewVariables] private string _packPrototypeId = "";
|
||||
@@ -99,8 +99,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
if (string.IsNullOrEmpty(_packPrototypeId)) return;
|
||||
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
if (!prototypeManager.TryIndex(_packPrototypeId, out ReagentDispenserInventoryPrototype packPrototype))
|
||||
if (!_prototypeManager.TryIndex(_packPrototypeId, out ReagentDispenserInventoryPrototype packPrototype))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -280,8 +279,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,15 +301,13 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hands.GetActiveHand == null)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have nothing on your hand."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have nothing on your hand."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,14 +316,12 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
{
|
||||
if (HasBeaker)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("This dispenser already has a container in it."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("This dispenser already has a container in it."));
|
||||
}
|
||||
else if ((solution.Capabilities & SolutionCaps.FitsInDispenser) == 0)
|
||||
{
|
||||
//If it can't fit in the dispenser, don't put it in. For example, buckets and mop buckets can't fit.
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("That can't fit in the dispenser."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("That can't fit in the dispenser."));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -337,8 +331,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You can't put this in the dispenser."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You can't put this in the dispenser."));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -348,11 +341,8 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
|
||||
private void ClickSound()
|
||||
{
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Machines/machine_switch.ogg", Owner, AudioParams.Default.WithVolume(-2f));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
var pos = tile.GridIndices.ToGridCoordinates(_mapManager, tile.GridIndex);
|
||||
SpillHelper.SpillAt(pos, contents.SplitSolution(amount), "PuddleSmear", false); //make non PuddleSmear?
|
||||
contents.SplitSolution(amount).SpillAt(pos, "PuddleSmear", false); // TODO: Make non PuddleSmear?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Shared.GameObjects.Components.Conveyor;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -170,7 +171,7 @@ namespace Content.Server.GameObjects.Components.Conveyor
|
||||
|
||||
Owner.AddComponent<ItemComponent>();
|
||||
_group?.RemoveConveyor(this);
|
||||
Owner.Transform.WorldPosition += (_random.NextFloat() * 0.4f - 0.2f, _random.NextFloat() * 0.4f - 0.2f);
|
||||
Owner.RandomOffset(0.2f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Content.Server.GameObjects.Components.Conveyor
|
||||
}
|
||||
|
||||
_group.AddConveyor(conveyor);
|
||||
user?.PopupMessage(user, Loc.GetString("Conveyor linked."));
|
||||
user?.PopupMessage(Loc.GetString("Conveyor linked."));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#nullable enable
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
@@ -11,13 +10,13 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Interfaces;
|
||||
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalRouterComponent;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Disposal
|
||||
@@ -27,7 +26,6 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
[ComponentReference(typeof(IDisposalTubeComponent))]
|
||||
public class DisposalRouterComponent : DisposalJunctionComponent, IActivate
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
public override string Name => "DisposalRouter";
|
||||
|
||||
[ViewVariables]
|
||||
@@ -160,8 +158,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#nullable enable
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
@@ -12,7 +12,6 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -25,7 +24,6 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
[ComponentReference(typeof(IDisposalTubeComponent))]
|
||||
public class DisposalTaggerComponent : DisposalTransitComponent, IActivate
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
public override string Name => "DisposalTagger";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
@@ -128,8 +126,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
using Content.Shared.GameObjects.Components.Disposal;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
@@ -43,7 +43,6 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
[ComponentReference(typeof(IInteractUsing))]
|
||||
public class DisposalUnitComponent : SharedDisposalUnitComponent, IInteractHand, IInteractUsing, IDragDropOn
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
public override string Name => "DisposalUnit";
|
||||
@@ -614,15 +613,13 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
{
|
||||
if (!ActionBlockerSystem.CanInteract(eventArgs.User))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("You can't do that!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can't do that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ContainerHelpers.IsInContainer(eventArgs.User))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("You can't reach there!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can't reach there!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -633,8 +630,7 @@ namespace Content.Server.GameObjects.Components.Disposal
|
||||
|
||||
if (!eventArgs.User.HasComponent<IHandsComponent>())
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("You have no hands!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You have no hands!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Content.Server.GameObjects.Components.VendingMachines;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects.Components.Doors;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
@@ -438,16 +439,14 @@ namespace Content.Server.GameObjects.Components.Doors
|
||||
{
|
||||
if (IsBolted())
|
||||
{
|
||||
var notify = IoCManager.Resolve<IServerNotifyManager>();
|
||||
notify.PopupMessage(Owner, eventArgs.User,
|
||||
Owner.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("The airlock's bolts prevent it from being forced!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsPowered())
|
||||
{
|
||||
var notify = IoCManager.Resolve<IServerNotifyManager>();
|
||||
notify.PopupMessage(Owner, eventArgs.User, Loc.GetString("The powered motors block your efforts!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("The powered motors block your efforts!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public class ExtinguisherCabinetComponent : Component, IInteractUsing, IInteractHand, IActivate
|
||||
{
|
||||
public override string Name => "ExtinguisherCabinet";
|
||||
|
||||
private bool _opened = false;
|
||||
private string _doorSound;
|
||||
|
||||
[ViewVariables] protected ContainerSlot ItemContainer;
|
||||
[ViewVariables] public string DoorSound => _doorSound;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
ItemContainer =
|
||||
ContainerManagerComponent.Ensure<ContainerSlot>("extinguisher_cabinet", Owner, out _);
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref _doorSound, "doorSound", "/Audio/Machines/machine_switch.ogg");
|
||||
}
|
||||
|
||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
||||
{
|
||||
if (!_opened)
|
||||
{
|
||||
_opened = true;
|
||||
ClickLatchSound();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ItemContainer.ContainedEntity != null || !eventArgs.Using.HasComponent<FireExtinguisherComponent>())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var handsComponent = eventArgs.User.GetComponent<IHandsComponent>();
|
||||
|
||||
if (!handsComponent.Drop(eventArgs.Using, ItemContainer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisuals();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
|
||||
{
|
||||
if (_opened)
|
||||
{
|
||||
if (ItemContainer.ContainedEntity == null)
|
||||
{
|
||||
_opened = false;
|
||||
ClickLatchSound();
|
||||
}
|
||||
else if (eventArgs.User.TryGetComponent(out HandsComponent hands))
|
||||
{
|
||||
Owner.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("You take {0:extinguisherName} from the {1:cabinetName}", ItemContainer.ContainedEntity.Name, Owner.Name));
|
||||
hands.PutInHandOrDrop(ItemContainer.ContainedEntity.GetComponent<ItemComponent>());
|
||||
}
|
||||
else if (ItemContainer.Remove(ItemContainer.ContainedEntity))
|
||||
{
|
||||
ItemContainer.ContainedEntity.Transform.GridPosition = Owner.Transform.GridPosition;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_opened = true;
|
||||
ClickLatchSound();
|
||||
}
|
||||
|
||||
UpdateVisuals();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IActivate.Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
_opened = !_opened;
|
||||
ClickLatchSound();
|
||||
UpdateVisuals();
|
||||
}
|
||||
|
||||
private void UpdateVisuals()
|
||||
{
|
||||
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
||||
{
|
||||
appearance.SetData(ExtinguisherCabinetVisuals.IsOpen, _opened);
|
||||
appearance.SetData(ExtinguisherCabinetVisuals.ContainsExtinguisher, ItemContainer.ContainedEntity != null);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClickLatchSound()
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>() // Don't have original click, this sounds close
|
||||
.PlayFromEntity(DoorSound, Owner, AudioHelpers.WithVariation(0.15f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class ExtinguisherCabinetFilledComponent : ExtinguisherCabinetComponent
|
||||
{
|
||||
public override string Name => "ExtinguisherCabinetFilled";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
ItemContainer.Insert(Owner.EntityManager.SpawnEntity("FireExtinguisher", Owner.Transform.GridPosition));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
// Need this as when we split the component's owner may be deleted
|
||||
var entityLocation = component.Owner.Transform.GridPosition;
|
||||
var solution = solutionComponent.SplitSolution(solutionComponent.CurrentVolume);
|
||||
SpillHelper.SpillAt(entityLocation, solution, "PuddleSmear");
|
||||
solution.SpillAt(entityLocation, "PuddleSmear");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
if (eventArgs.Target == null)
|
||||
{
|
||||
// Drop the liquid on the mop on to the ground
|
||||
SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(CurrentVolume), "PuddleSmear");
|
||||
contents.SplitSolution(CurrentVolume).SpillAt(eventArgs.ClickLocation, "PuddleSmear");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
|
||||
if (puddleCleaned) //After cleaning the puddle, make a new puddle with solution from the mop as a "wet floor". Then evaporate it slowly.
|
||||
{
|
||||
SpillHelper.SpillAt(eventArgs.ClickLocation, contents.SplitSolution(transferAmount), "PuddleSmear");
|
||||
contents.SplitSolution(transferAmount).SpillAt(eventArgs.ClickLocation, "PuddleSmear");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -6,7 +6,9 @@ using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
@@ -41,12 +43,13 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
// Small puddles will evaporate after a set delay
|
||||
|
||||
// TODO: 'leaves fluidtracks', probably in a separate component for stuff like gibb chunks?;
|
||||
// TODO: Add stuff like slipping -> probably in a separate component (for stuff like bananas)
|
||||
|
||||
// based on behaviour (e.g. someone being punched vs slashed with a sword would have different blood sprite)
|
||||
// to check for low volumes for evaporation or whatever
|
||||
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
public override string Name => "Puddle";
|
||||
|
||||
@@ -132,8 +135,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
// Random sprite state set server-side so it's consistent across all clients
|
||||
_spriteComponent = Owner.EnsureComponent<SpriteComponent>();
|
||||
|
||||
var robustRandom = IoCManager.Resolve<IRobustRandom>();
|
||||
var randomVariant = robustRandom.Next(0, _spriteVariants - 1);
|
||||
var randomVariant = _random.Next(0, _spriteVariants - 1);
|
||||
|
||||
if (_spriteComponent.BaseRSIPath != null)
|
||||
{
|
||||
@@ -338,43 +340,6 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move the below to SnapGrid?
|
||||
/// <summary>
|
||||
/// Will yield a random direction until none are left
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Direction> RandomDirections()
|
||||
{
|
||||
var directions = new[]
|
||||
{
|
||||
Direction.East,
|
||||
Direction.SouthEast,
|
||||
Direction.South,
|
||||
Direction.SouthWest,
|
||||
Direction.West,
|
||||
Direction.NorthWest,
|
||||
Direction.North,
|
||||
Direction.NorthEast,
|
||||
};
|
||||
|
||||
var robustRandom = IoCManager.Resolve<IRobustRandom>();
|
||||
var n = directions.Length;
|
||||
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
var k = robustRandom.Next(n + 1);
|
||||
var value = directions[k];
|
||||
directions[k] = directions[n];
|
||||
directions[n] = value;
|
||||
}
|
||||
|
||||
foreach (var direction in directions)
|
||||
{
|
||||
yield return direction;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get an adjacent coordinate to overflow to, unless it is blocked by a wall on the
|
||||
/// same tile or the tile is empty
|
||||
@@ -389,9 +354,13 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
|
||||
var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID);
|
||||
|
||||
if (!Owner.Transform.GridPosition.Offset(direction).TryGetTileRef(out var tile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If space return early, let that spill go out into the void
|
||||
var tileRef = mapGrid.GetTileRef(Owner.Transform.GridPosition.Offset(direction.ToVec()));
|
||||
if (tileRef.Tile.IsEmpty)
|
||||
if (tile.Value.Tile.IsEmpty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -419,8 +388,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
if (puddle == default)
|
||||
{
|
||||
var grid = _snapGrid.DirectionToGrid(direction);
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
puddle = () => entityManager.SpawnEntity(Owner.Prototype.ID, grid).GetComponent<PuddleComponent>();
|
||||
puddle = () => _entityManager.SpawnEntity(Owner.Prototype.ID, grid).GetComponent<PuddleComponent>();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -432,7 +400,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
/// <returns>Enumerable of the puddles found or to be created</returns>
|
||||
private IEnumerable<Func<PuddleComponent>> GetAllAdjacentOverflow()
|
||||
{
|
||||
foreach (var direction in RandomDirections())
|
||||
foreach (var direction in SharedDirectionExtensions.RandomDirections())
|
||||
{
|
||||
if (TryGetAdjacentOverflow(direction, out var puddle))
|
||||
{
|
||||
|
||||
128
Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs
Normal file
128
Content.Server/GameObjects/Components/Fluids/SpillExtensions.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
#nullable enable
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Chemistry;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Fluids
|
||||
{
|
||||
public static class SpillExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Spills the specified solution at the entity's location if possible.
|
||||
/// </summary>
|
||||
/// <param name="entity">
|
||||
/// The entity to use as a location to spill the solution at.
|
||||
/// </param>
|
||||
/// <param name="solution">Initial solution for the prototype.</param>
|
||||
/// <param name="prototype">The prototype to use.</param>
|
||||
/// <param name="sound">Play the spill sound.</param>
|
||||
/// <returns>The puddle if one was created, null otherwise.</returns>
|
||||
public static PuddleComponent? SpillAt(this Solution solution, IEntity entity, string prototype, bool sound = true)
|
||||
{
|
||||
var coordinates = entity.Transform.GridPosition;
|
||||
return solution.SpillAt(coordinates, prototype, sound);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spills the specified solution at the entity's location if possible.
|
||||
/// </summary>
|
||||
/// <param name="entity">
|
||||
/// The entity to use as a location to spill the solution at.
|
||||
/// </param>
|
||||
/// <param name="solution">Initial solution for the prototype.</param>
|
||||
/// <param name="prototype">The prototype to use.</param>
|
||||
/// <param name="puddle">The puddle if one was created, null otherwise.</param>
|
||||
/// <param name="sound">Play the spill sound.</param>
|
||||
/// <returns>True if a puddle was created, false otherwise.</returns>
|
||||
public static bool TrySpillAt(this Solution solution, IEntity entity, string prototype, [NotNullWhen(true)] out PuddleComponent? puddle, bool sound = true)
|
||||
{
|
||||
puddle = solution.SpillAt(entity, prototype, sound);
|
||||
return puddle != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spills solution at the specified grid coordinates.
|
||||
/// </summary>
|
||||
/// <param name="solution">Initial solution for the prototype.</param>
|
||||
/// <param name="coordinates">The coordinates to spill the solution at.</param>
|
||||
/// <param name="prototype">The prototype to use.</param>
|
||||
/// <param name="sound">Whether or not to play the spill sound.</param>
|
||||
/// <returns>The puddle if one was created, null otherwise.</returns>
|
||||
public static PuddleComponent? SpillAt(this Solution solution, GridCoordinates coordinates, string prototype, bool sound = true)
|
||||
{
|
||||
if (solution.TotalVolume == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
|
||||
|
||||
var mapGrid = mapManager.GetGrid(coordinates.GridID);
|
||||
|
||||
// If space return early, let that spill go out into the void
|
||||
var tileRef = mapGrid.GetTileRef(coordinates);
|
||||
if (tileRef.Tile.IsEmpty)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get normalized co-ordinate for spill location and spill it in the centre
|
||||
// TODO: Does SnapGrid or something else already do this?
|
||||
var spillTileMapGrid = mapManager.GetGrid(coordinates.GridID);
|
||||
var spillTileRef = spillTileMapGrid.GetTileRef(coordinates).GridIndices;
|
||||
var spillGridCoords = spillTileMapGrid.GridTileToLocal(spillTileRef);
|
||||
|
||||
var spilt = false;
|
||||
|
||||
foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.ParentMapId, spillGridCoords.Position))
|
||||
{
|
||||
if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!puddleComponent.TryAddSolution(solution, sound))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spilt = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Did we add to an existing puddle
|
||||
if (spilt)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var puddle = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
|
||||
var newPuddleComponent = puddle.GetComponent<PuddleComponent>();
|
||||
|
||||
newPuddleComponent.TryAddSolution(solution, sound);
|
||||
|
||||
return newPuddleComponent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spills the specified solution at the entity's location if possible.
|
||||
/// </summary>
|
||||
/// <param name="coordinates">The coordinates to spill the solution at.</param>
|
||||
/// <param name="solution">Initial solution for the prototype.</param>
|
||||
/// <param name="prototype">The prototype to use.</param>
|
||||
/// <param name="puddle">The puddle if one was created, null otherwise.</param>
|
||||
/// <param name="sound">Play the spill sound.</param>
|
||||
/// <returns>True if a puddle was created, false otherwise.</returns>
|
||||
public static bool TrySpillAt(this Solution solution, GridCoordinates coordinates, string prototype, [NotNullWhen(true)] out PuddleComponent? puddle, bool sound = true)
|
||||
{
|
||||
puddle = solution.SpillAt(coordinates, prototype, sound);
|
||||
return puddle != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
#nullable enable
|
||||
using Content.Shared.Chemistry;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Fluids
|
||||
{
|
||||
public static class SpillHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Spills the specified solution at the entity's location if possible.
|
||||
/// </summary>
|
||||
/// <param name="entity">Entity location to spill at</param>
|
||||
/// <param name="solution">Initial solution for the prototype</param>
|
||||
/// <param name="prototype">Prototype to use</param>
|
||||
/// <param name="sound">Play the spill sound</param>
|
||||
internal static void SpillAt(IEntity entity, Solution solution, string prototype, bool sound = true)
|
||||
{
|
||||
var entityLocation = entity.Transform.GridPosition;
|
||||
SpillAt(entityLocation, solution, prototype, sound);
|
||||
}
|
||||
|
||||
// Other functions will be calling this one
|
||||
|
||||
/// <summary>
|
||||
/// Spills solution at the specified grid co-ordinates
|
||||
/// </summary>
|
||||
/// <param name="gridCoordinates"></param>
|
||||
/// <param name="solution">Initial solution for the prototype</param>
|
||||
/// <param name="prototype">Prototype to use</param>
|
||||
/// <param name="sound">Play the spill sound</param>
|
||||
internal static PuddleComponent? SpillAt(GridCoordinates gridCoordinates, Solution solution, string prototype, bool sound = true)
|
||||
{
|
||||
if (solution.TotalVolume == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
|
||||
|
||||
var mapGrid = mapManager.GetGrid(gridCoordinates.GridID);
|
||||
|
||||
// If space return early, let that spill go out into the void
|
||||
var tileRef = mapGrid.GetTileRef(gridCoordinates);
|
||||
if (tileRef.Tile.IsEmpty)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get normalized co-ordinate for spill location and spill it in the centre
|
||||
// TODO: Does SnapGrid or something else already do this?
|
||||
var spillTileMapGrid = mapManager.GetGrid(gridCoordinates.GridID);
|
||||
var spillTileRef = spillTileMapGrid.GetTileRef(gridCoordinates).GridIndices;
|
||||
var spillGridCoords = spillTileMapGrid.GridTileToLocal(spillTileRef);
|
||||
|
||||
var spilt = false;
|
||||
|
||||
foreach (var spillEntity in entityManager.GetEntitiesAt(spillTileMapGrid.ParentMapId, spillGridCoords.Position))
|
||||
{
|
||||
if (!spillEntity.TryGetComponent(out PuddleComponent? puddleComponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!puddleComponent.TryAddSolution(solution, sound))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spilt = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Did we add to an existing puddle
|
||||
if (spilt)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var puddle = serverEntityManager.SpawnEntity(prototype, spillGridCoords);
|
||||
var newPuddleComponent = puddle.GetComponent<PuddleComponent>();
|
||||
newPuddleComponent.TryAddSolution(solution, sound);
|
||||
return newPuddleComponent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
@@ -17,7 +17,6 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
[RegisterComponent]
|
||||
class SprayComponent : Component, IAfterInteract
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||
|
||||
public override string Name => "Spray";
|
||||
@@ -71,7 +70,7 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
{
|
||||
if (CurrentVolume <= 0)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, eventArgs.User, Loc.GetString("It's empty!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("It's empty!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Items.Clothing;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.GameObjects.EntitySystems.Click;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Inventory;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -29,7 +28,6 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
public class InventoryComponent : SharedInventoryComponent, IExAct, IEffectBlocker, IPressureProtection
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _serverNotifyManager = default!;
|
||||
|
||||
[ViewVariables]
|
||||
private readonly Dictionary<Slots, ContainerSlot> _slotContainers = new Dictionary<Slots, ContainerSlot>();
|
||||
@@ -432,7 +430,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
hands.PutInHand(clothing);
|
||||
|
||||
if (reason != null)
|
||||
_serverNotifyManager.PopupMessageCursor(Owner, reason);
|
||||
Owner.PopupMessageCursor(reason);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Content.Server.GameObjects.Components.ActionBlocking;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.GUI;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
@@ -17,7 +16,6 @@ using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
@@ -27,11 +25,9 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
[RegisterComponent]
|
||||
public sealed class StrippableComponent : SharedStrippableComponent, IDragDrop
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public const float StripDelay = 2f;
|
||||
|
||||
[ViewVariables]
|
||||
[ViewVariables]
|
||||
private BoundUserInterface? UserInterface => Owner.GetUIOrNull(StrippingUiKey.Key);
|
||||
|
||||
public override void Initialize()
|
||||
@@ -46,7 +42,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
Owner.EnsureComponent<InventoryComponent>();
|
||||
Owner.EnsureComponent<HandsComponent>();
|
||||
Owner.EnsureComponent<CuffableComponent>();
|
||||
|
||||
|
||||
if (Owner.TryGetComponent(out CuffableComponent? cuffed))
|
||||
{
|
||||
cuffed.OnCuffedStateChanged += UpdateSubscribed;
|
||||
@@ -104,7 +100,7 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
private Dictionary<EntityUid, string> GetHandcuffs()
|
||||
{
|
||||
var dictionary = new Dictionary<EntityUid, string>();
|
||||
|
||||
|
||||
if (!Owner.TryGetComponent(out CuffableComponent? cuffed))
|
||||
{
|
||||
return dictionary;
|
||||
@@ -173,13 +169,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("You aren't holding anything!"));
|
||||
user.PopupMessageCursor(Loc.GetString("You aren't holding anything!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!userHands.CanDrop(userHands.ActiveHand!))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("You can't drop that!"));
|
||||
user.PopupMessageCursor(Loc.GetString("You can't drop that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -188,13 +184,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (inventory.TryGetSlotItem(slot, out ItemComponent _))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} already {0:have} something there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} already {0:have} something there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!inventory.CanEquip(slot, item, false))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot equip that there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} cannot equip that there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -238,13 +234,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("You aren't holding anything!"));
|
||||
user.PopupMessageCursor(Loc.GetString("You aren't holding anything!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!userHands.CanDrop(userHands.ActiveHand!))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("You can't drop that!"));
|
||||
user.PopupMessageCursor(Loc.GetString("You can't drop that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -253,13 +249,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (hands.TryGetItem(hand, out var _))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} already {0:have} something there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} already {0:have} something there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hands.CanPutInHand(item, hand, false))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot put that there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} cannot put that there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -304,13 +300,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (!inventory.TryGetSlotItem(slot, out ItemComponent itemToTake))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} {0:have} nothing there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} {0:have} nothing there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!inventory.CanUnequip(slot, false))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot unequip that!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} cannot unequip that!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -355,13 +351,13 @@ namespace Content.Server.GameObjects.Components.GUI
|
||||
|
||||
if (!hands.TryGetItem(hand, out var heldItem))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} {0:have} nothing there!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} {0:have} nothing there!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hands.CanDrop(hand, false))
|
||||
{
|
||||
_notifyManager.PopupMessageCursor(user, Loc.GetString("{0:They} cannot drop that!", Owner));
|
||||
user.PopupMessageCursor(Loc.GetString("{0:They} cannot drop that!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Gravity;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
@@ -111,9 +112,8 @@ namespace Content.Server.GameObjects.Components.Gravity
|
||||
breakable.FixAllDamage();
|
||||
_intact = true;
|
||||
|
||||
var notifyManager = IoCManager.Resolve<IServerNotifyManager>();
|
||||
|
||||
notifyManager.PopupMessage(Owner, eventArgs.User, Loc.GetString("You repair {0:theName} with {1:theName}", Owner, eventArgs.Using));
|
||||
Owner.PopupMessage(eventArgs.User,
|
||||
Loc.GetString("You repair {0:theName} with {1:theName}", Owner, eventArgs.Using));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ using System;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Mobs;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Instruments;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
@@ -38,7 +37,6 @@ namespace Content.Server.GameObjects.Components.Instruments
|
||||
IUse,
|
||||
IThrown
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private static readonly TimeSpan OneSecAgo = TimeSpan.FromSeconds(-1);
|
||||
@@ -166,11 +164,11 @@ namespace Content.Server.GameObjects.Components.Instruments
|
||||
switch (_laggedBatches)
|
||||
{
|
||||
case (int) (MaxMidiLaggedBatches * (1 / 3d)) + 1:
|
||||
_notifyManager.PopupMessage(Owner, InstrumentPlayer.AttachedEntity,
|
||||
Owner.PopupMessage(InstrumentPlayer.AttachedEntity,
|
||||
"Your fingers are beginning to a cramp a little!");
|
||||
break;
|
||||
case (int) (MaxMidiLaggedBatches * (2 / 3d)) + 1:
|
||||
_notifyManager.PopupMessage(Owner, InstrumentPlayer.AttachedEntity,
|
||||
Owner.PopupMessage(InstrumentPlayer.AttachedEntity,
|
||||
"Your fingers are seriously cramping up!");
|
||||
break;
|
||||
}
|
||||
@@ -333,7 +331,7 @@ namespace Content.Server.GameObjects.Components.Instruments
|
||||
|
||||
InstrumentPlayer = null;
|
||||
|
||||
_notifyManager.PopupMessage(Owner, mob, "Your fingers cramp up from playing!");
|
||||
Owner.PopupMessage(mob, "Your fingers cramp up from playing!");
|
||||
}
|
||||
|
||||
_timer += delta;
|
||||
|
||||
@@ -17,7 +17,6 @@ using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
@@ -31,8 +30,6 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
internal sealed class HandheldLightComponent : SharedHandheldLightComponent, IUse, IExamine, IInteractUsing,
|
||||
IMapInit
|
||||
{
|
||||
[Dependency] private readonly ISharedNotifyManager _notifyManager = default!;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)] public float Wattage { get; set; } = 10;
|
||||
[ViewVariables] private ContainerSlot _cellContainer = default!;
|
||||
|
||||
@@ -152,7 +149,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Machines/button.ogg", Owner);
|
||||
|
||||
_notifyManager.PopupMessage(Owner, user, Loc.GetString("Cell missing..."));
|
||||
Owner.PopupMessage(user, Loc.GetString("Cell missing..."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,7 +159,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
if (Wattage > cell.CurrentCharge)
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/Machines/button.ogg", Owner);
|
||||
_notifyManager.PopupMessage(Owner, user, Loc.GetString("Dead cell..."));
|
||||
Owner.PopupMessage(user, Loc.GetString("Dead cell..."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Server.Atmos;
|
||||
using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Server.Utility;
|
||||
@@ -15,7 +14,6 @@ using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -33,8 +31,6 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
public class WelderComponent : ToolComponent, IExamine, IUse, ISuicideAct, ISolutionChange
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public override string Name => "Welder";
|
||||
public override uint? NetID => ContentNetIDs.WELDER;
|
||||
@@ -108,7 +104,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
|
||||
if (!CanWeld(DefaultFuelCost))
|
||||
{
|
||||
_notifyManager.PopupMessage(target, user, "Can't weld!");
|
||||
target.PopupMessage(user, "Can't weld!");
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -137,13 +133,13 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
if (!WelderLit)
|
||||
{
|
||||
if(!silent) _notifyManager.PopupMessage(Owner, user, Loc.GetString("The welder is turned off!"));
|
||||
if(!silent) Owner.PopupMessage(user, Loc.GetString("The welder is turned off!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanWeld(value))
|
||||
{
|
||||
if(!silent) _notifyManager.PopupMessage(Owner, user, Loc.GetString("The welder does not have enough fuel for that!"));
|
||||
if(!silent) Owner.PopupMessage(user, Loc.GetString("The welder does not have enough fuel for that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -192,7 +188,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
|
||||
if (!CanLitWelder())
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, user, Loc.GetString("The welder has no fuel left!"));
|
||||
Owner.PopupMessage(user, Loc.GetString("The welder has no fuel left!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects;
|
||||
using Content.Shared.GameObjects.Components.Items;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
|
||||
|
||||
@@ -20,8 +19,6 @@ namespace Content.Server.GameObjects.Components.Items.Clothing
|
||||
[ComponentReference(typeof(IItemComponent))]
|
||||
public class ClothingComponent : ItemComponent, IUse
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _serverNotifyManager = default!;
|
||||
|
||||
public override string Name => "Clothing";
|
||||
public override uint? NetID => ContentNetIDs.CLOTHING;
|
||||
|
||||
@@ -112,7 +109,7 @@ namespace Content.Server.GameObjects.Components.Items.Clothing
|
||||
if (!inv.Equip(slot, this, true, out var reason))
|
||||
{
|
||||
if (reason != null)
|
||||
_serverNotifyManager.PopupMessage(Owner, user, reason);
|
||||
Owner.PopupMessage(user, reason);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Items
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class FireExtinguisherComponent : Component
|
||||
{
|
||||
public override string Name => "FireExtinguisher";
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -15,8 +14,6 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
[RegisterComponent]
|
||||
public class RCDAmmoComponent : Component, IAfterInteract, IExamine
|
||||
{
|
||||
[Dependency] private IServerNotifyManager _serverNotifyManager = default!;
|
||||
|
||||
public override string Name => "RCDAmmo";
|
||||
|
||||
//How much ammo we refill
|
||||
@@ -43,17 +40,16 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
|
||||
if (rcdComponent.maxAmmo - rcdComponent._ammo < refillAmmo)
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(rcdComponent.Owner, eventArgs.User, "The RCD is full!");
|
||||
rcdComponent.Owner.PopupMessage(eventArgs.User, Loc.GetString("The RCD is full!"));
|
||||
return;
|
||||
}
|
||||
|
||||
rcdComponent._ammo = Math.Min(rcdComponent.maxAmmo, rcdComponent._ammo + refillAmmo);
|
||||
_serverNotifyManager.PopupMessage(rcdComponent.Owner, eventArgs.User, "You refill the RCD.");
|
||||
rcdComponent.Owner.PopupMessage(eventArgs.User, Loc.GetString("You refill the RCD."));
|
||||
|
||||
//Deleting a held item causes a lot of errors
|
||||
hands.Drop(Owner, false);
|
||||
Owner.Delete();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Utility;
|
||||
@@ -30,7 +29,6 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _serverNotifyManager = default!;
|
||||
|
||||
public override string Name => "RCD";
|
||||
private RcdMode _mode = 0; //What mode are we on? Can be floors, walls, deconstruct.
|
||||
@@ -86,12 +84,12 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
int mode = (int) _mode; //Firstly, cast our RCDmode mode to an int (enums are backed by ints anyway by default)
|
||||
mode = (++mode) % _modes.Length; //Then, do a rollover on the value so it doesnt hit an invalid state
|
||||
_mode = (RcdMode) mode; //Finally, cast the newly acquired int mode to an RCDmode so we can use it.
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"The RCD is now set to {this._mode} mode."); //Prints an overhead message above the RCD
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("The RCD is now set to {0} mode.", _mode)); //Prints an overhead message above the RCD
|
||||
}
|
||||
|
||||
public void Examine(FormattedMessage message, bool inDetailsRange)
|
||||
{
|
||||
message.AddMarkup(Loc.GetString("It's currently on {0} mode, and holds {1} charges.",_mode.ToString(), this._ammo));
|
||||
message.AddMarkup(Loc.GetString("It's currently on {0} mode, and holds {1} charges.",_mode.ToString(), _ammo));
|
||||
}
|
||||
|
||||
public async void AfterInteract(AfterInteractEventArgs eventArgs)
|
||||
@@ -159,7 +157,7 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
//Less expensive checks first. Failing those ones, we need to check that the tile isn't obstructed.
|
||||
if (_ammo <= 0)
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"The RCD is out of ammo!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("The RCD is out of ammo!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -180,7 +178,7 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
case RcdMode.Floors:
|
||||
if (!tile.Tile.IsEmpty)
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"You can only build a floor on space!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can only build a floor on space!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -195,13 +193,13 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
//They tried to decon a turf but the turf is blocked
|
||||
if (eventArgs.Target == null && tile.IsBlockedTurf(true))
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"That tile is obstructed!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("That tile is obstructed!"));
|
||||
return false;
|
||||
}
|
||||
//They tried to decon a non-turf but it's not in the whitelist
|
||||
if (eventArgs.Target != null && !eventArgs.Target.TryGetComponent(out RCDDeconstructWhitelist rcd_decon))
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"You can't deconstruct that!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You can't deconstruct that!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -210,25 +208,25 @@ namespace Content.Server.GameObjects.Components.Items.RCD
|
||||
case RcdMode.Walls:
|
||||
if (tile.Tile.IsEmpty)
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"Cannot build a wall on space!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("You cannot build a wall on space!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tile.IsBlockedTurf(true))
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"That tile is obstructed!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("That tile is obstructed!"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case RcdMode.Airlock:
|
||||
if (tile.Tile.IsEmpty)
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"Cannot build an airlock on space!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("Cannot build an airlock on space!"));
|
||||
return false;
|
||||
}
|
||||
if (tile.IsBlockedTurf(true))
|
||||
{
|
||||
_serverNotifyManager.PopupMessage(Owner, eventArgs.User, $"That tile is obstructed!");
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("That tile is obstructed!"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -4,10 +4,7 @@ using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.Body;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Interactable;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.Components.Storage;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
@@ -35,6 +32,8 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
||||
[ComponentReference(typeof(IStorageComponent))]
|
||||
public class EntityStorageComponent : Component, IActivate, IStorageComponent, IInteractUsing, IDestroyAct, IActionBlocker, IExAct
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
public override string Name => "EntityStorage";
|
||||
|
||||
private const float MaxSize = 1.0f; // maximum width or height of an entity allowed inside the storage.
|
||||
@@ -301,14 +300,13 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
||||
case RelayMovementEntityMessage msg:
|
||||
if (msg.Entity.HasComponent<HandsComponent>())
|
||||
{
|
||||
var timing = IoCManager.Resolve<IGameTiming>();
|
||||
if (timing.CurTime <
|
||||
if (_gameTiming.CurTime <
|
||||
_lastInternalOpenAttempt + InternalOpenAttemptDelay)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_lastInternalOpenAttempt = timing.CurTime;
|
||||
_lastInternalOpenAttempt = _gameTiming.CurTime;
|
||||
TryOpenStorage(msg.Entity);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace Content.Server.GameObjects.Components.Items.Storage.Fill
|
||||
void IMapInit.MapInit()
|
||||
{
|
||||
var storage = Owner.GetComponent<IStorageComponent>();
|
||||
var random = IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
void Spawn(string prototype)
|
||||
{
|
||||
|
||||
@@ -126,8 +126,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
||||
{
|
||||
if (!reader.IsAllowed(user))
|
||||
{
|
||||
IoCManager.Resolve<IServerNotifyManager>()
|
||||
.PopupMessage(Owner, user, Loc.GetString("Access denied"));
|
||||
Owner.PopupMessage(user, Loc.GetString("Access denied"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Server.Utility;
|
||||
@@ -27,7 +26,6 @@ using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Content.Shared.GameObjects.Components.Body;
|
||||
@@ -44,8 +42,6 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly RecipeManager _recipeManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
#region YAMLSERIALIZE
|
||||
private int _cookTimeDefault;
|
||||
@@ -206,8 +202,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
||||
{
|
||||
if (!Powered)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("It has no power!"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("It has no power!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -215,7 +210,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
||||
|
||||
if (itemEntity == null)
|
||||
{
|
||||
eventArgs.User.PopupMessage(eventArgs.User, Loc.GetString("You have no active hand!"));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You have no active hand!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -236,8 +231,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
||||
var realTransferAmount = ReagentUnit.Min(attackPourable.TransferAmount, solution.EmptyVolume);
|
||||
if (realTransferAmount <= 0) //Special message if container is full
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("Container is full"));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("Container is full"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -248,15 +242,14 @@ namespace Content.Server.GameObjects.Components.Kitchen
|
||||
return false;
|
||||
}
|
||||
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User,
|
||||
Loc.GetString("Transferred {0}u", removedSolution.TotalVolume));
|
||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("Transferred {0}u", removedSolution.TotalVolume));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!itemEntity.TryGetComponent(typeof(ItemComponent), out var food))
|
||||
{
|
||||
|
||||
_notifyManager.PopupMessage(Owner, eventArgs.User, "That won't work!");
|
||||
Owner.PopupMessage(eventArgs.User, "That won't work!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Content.Server.GameObjects.Components.MachineLinking
|
||||
{
|
||||
if (transmitter == null)
|
||||
{
|
||||
user.PopupMessage(user, Loc.GetString("Signal not set."));
|
||||
user.PopupMessage(Loc.GetString("Signal not set."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Mobs;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Preferences;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Medical
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public class CloningPodComponent : SharedCloningPodComponent, IActivate
|
||||
{
|
||||
[Dependency] private readonly IServerPreferencesManager _prefsManager = null!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = null!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = null!;
|
||||
|
||||
[ViewVariables]
|
||||
private bool Powered => !Owner.TryGetComponent(out PowerReceiverComponent? receiver) || receiver.Powered;
|
||||
|
||||
[ViewVariables]
|
||||
private BoundUserInterface? UserInterface =>
|
||||
Owner.GetUIOrNull(CloningPodUIKey.Key);
|
||||
|
||||
private ContainerSlot _bodyContainer = default!;
|
||||
private Mind? _capturedMind;
|
||||
private CloningPodStatus _status;
|
||||
private float _cloningProgress = 0;
|
||||
private float _cloningTime;
|
||||
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
serializer.DataField(ref _cloningTime, "cloningTime", 10f);
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
if (UserInterface != null)
|
||||
{
|
||||
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
|
||||
}
|
||||
|
||||
_bodyContainer = ContainerManagerComponent.Ensure<ContainerSlot>($"{Name}-bodyContainer", Owner);
|
||||
|
||||
//TODO: write this so that it checks for a change in power events for GORE POD cases
|
||||
var newState = GetUserInterfaceState();
|
||||
UserInterface?.SetState(newState);
|
||||
|
||||
UpdateUserInterface();
|
||||
|
||||
Owner.EntityManager.EventBus.SubscribeEvent<GhostComponent.GhostReturnMessage>(EventSource.Local, this,
|
||||
HandleGhostReturn);
|
||||
}
|
||||
|
||||
public void Update(float frametime)
|
||||
{
|
||||
if (_bodyContainer.ContainedEntity != null &&
|
||||
Powered)
|
||||
{
|
||||
_cloningProgress += frametime;
|
||||
_cloningProgress = MathHelper.Clamp(_cloningProgress, 0f, _cloningTime);
|
||||
}
|
||||
|
||||
if (_cloningProgress >= _cloningTime &&
|
||||
_bodyContainer.ContainedEntity != null &&
|
||||
_capturedMind?.Session.AttachedEntity == _bodyContainer.ContainedEntity &&
|
||||
Powered)
|
||||
{
|
||||
_bodyContainer.Remove(_bodyContainer.ContainedEntity);
|
||||
_capturedMind = null;
|
||||
_cloningProgress = 0f;
|
||||
|
||||
_status = CloningPodStatus.Idle;
|
||||
UpdateAppearance();
|
||||
}
|
||||
|
||||
UpdateUserInterface();
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
if (UserInterface != null)
|
||||
{
|
||||
UserInterface.OnReceiveMessage -= OnUiReceiveMessage;
|
||||
}
|
||||
|
||||
Owner.EntityManager.EventBus.UnsubscribeEvent<GhostComponent.GhostReturnMessage>(EventSource.Local, this);
|
||||
|
||||
base.OnRemove();
|
||||
}
|
||||
|
||||
private void UpdateUserInterface()
|
||||
{
|
||||
if (!Powered) return;
|
||||
|
||||
UserInterface?.SetState(GetUserInterfaceState());
|
||||
}
|
||||
|
||||
private CloningPodBoundUserInterfaceState GetUserInterfaceState()
|
||||
{
|
||||
return new CloningPodBoundUserInterfaceState(CloningSystem.getIdToUser(), _cloningProgress,
|
||||
(_status == CloningPodStatus.Cloning));
|
||||
}
|
||||
|
||||
private void UpdateAppearance()
|
||||
{
|
||||
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||
{
|
||||
appearance.SetData(CloningPodVisuals.Status, _status);
|
||||
}
|
||||
}
|
||||
|
||||
public void Activate(ActivateEventArgs eventArgs)
|
||||
{
|
||||
if (!Powered ||
|
||||
!eventArgs.User.TryGetComponent(out IActorComponent? actor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UserInterface?.Open(actor.playerSession);
|
||||
}
|
||||
|
||||
private async void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||
{
|
||||
if (!(obj.Message is CloningPodUiButtonPressedMessage message)) return;
|
||||
|
||||
switch (message.Button)
|
||||
{
|
||||
case UiButton.Clone:
|
||||
|
||||
if (message.ScanId == null) return;
|
||||
|
||||
if (_bodyContainer.ContainedEntity != null ||
|
||||
!CloningSystem.Minds.TryGetValue(message.ScanId.Value, out var mind))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dead =
|
||||
mind.OwnedEntity.TryGetComponent<IDamageableComponent>(out var damageable) &&
|
||||
damageable.CurrentDamageState == DamageState.Dead;
|
||||
if (!dead) return;
|
||||
|
||||
|
||||
var mob = _entityManager.SpawnEntity("HumanMob_Content", Owner.Transform.MapPosition);
|
||||
var client = _playerManager
|
||||
.GetPlayersBy(x => x.SessionId == mind.SessionId).First();
|
||||
mob.GetComponent<HumanoidAppearanceComponent>()
|
||||
.UpdateFromProfile(GetPlayerProfileAsync(client.Name).Result);
|
||||
mob.Name = GetPlayerProfileAsync(client.Name).Result.Name;
|
||||
|
||||
_bodyContainer.Insert(mob);
|
||||
_capturedMind = mind;
|
||||
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local,
|
||||
new CloningStartedMessage(_capturedMind));
|
||||
_status = CloningPodStatus.NoMind;
|
||||
UpdateAppearance();
|
||||
|
||||
break;
|
||||
|
||||
case UiButton.Eject:
|
||||
if (_bodyContainer.ContainedEntity == null || _cloningProgress < _cloningTime) break;
|
||||
|
||||
_bodyContainer.Remove(_bodyContainer.ContainedEntity!);
|
||||
_capturedMind = null;
|
||||
_cloningProgress = 0f;
|
||||
_status = CloningPodStatus.Idle;
|
||||
UpdateAppearance();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public class CloningStartedMessage : EntitySystemMessage
|
||||
{
|
||||
public CloningStartedMessage(Mind capturedMind)
|
||||
{
|
||||
CapturedMind = capturedMind;
|
||||
}
|
||||
|
||||
public Mind CapturedMind { get; }
|
||||
}
|
||||
|
||||
|
||||
private async Task<HumanoidCharacterProfile> GetPlayerProfileAsync(string username)
|
||||
{
|
||||
return (HumanoidCharacterProfile) (await _prefsManager.GetPreferencesAsync(username))
|
||||
.SelectedCharacter;
|
||||
}
|
||||
|
||||
private void HandleGhostReturn(GhostComponent.GhostReturnMessage message)
|
||||
{
|
||||
if (message.Sender == _capturedMind)
|
||||
{
|
||||
//If the captured mind is in a ghost, we want to get rid of it.
|
||||
_capturedMind.VisitingEntity?.Delete();
|
||||
|
||||
//Transfer the mind to the new mob
|
||||
_capturedMind.TransferTo(_bodyContainer.ContainedEntity);
|
||||
|
||||
_status = CloningPodStatus.Cloning;
|
||||
UpdateAppearance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Body;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Players;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Medical;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
@@ -13,21 +18,24 @@ using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Medical
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public class MedicalScannerComponent : SharedMedicalScannerComponent, IActivate
|
||||
public class MedicalScannerComponent : SharedMedicalScannerComponent, IActivate, IDragDropOn
|
||||
{
|
||||
private ContainerSlot _bodyContainer = default!;
|
||||
private readonly Vector2 _ejectOffset = new Vector2(-0.5f, 0f);
|
||||
|
||||
[Dependency] private readonly IPlayerManager _playerManager = null!;
|
||||
public bool IsOccupied => _bodyContainer.ContainedEntity != null;
|
||||
|
||||
[ViewVariables]
|
||||
@@ -68,13 +76,12 @@ namespace Content.Server.GameObjects.Components.Medical
|
||||
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||
{
|
||||
appearance?.SetData(MedicalScannerVisuals.Status, MedicalScannerStatus.Open);
|
||||
};
|
||||
}
|
||||
|
||||
return EmptyUIState;
|
||||
}
|
||||
|
||||
if (!body.TryGetComponent(out IDamageableComponent? damageable) ||
|
||||
damageable.CurrentDamageState == DamageState.Dead)
|
||||
if (!body.TryGetComponent(out IDamageableComponent? damageable))
|
||||
{
|
||||
return EmptyUIState;
|
||||
}
|
||||
@@ -82,7 +89,14 @@ namespace Content.Server.GameObjects.Components.Medical
|
||||
var classes = new Dictionary<DamageClass, int>(damageable.DamageClasses);
|
||||
var types = new Dictionary<DamageType, int>(damageable.DamageTypes);
|
||||
|
||||
return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types, CloningSystem.HasUid(body.Uid));
|
||||
if (_bodyContainer.ContainedEntity?.Uid == null)
|
||||
{
|
||||
return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types, true);
|
||||
}
|
||||
|
||||
|
||||
return new MedicalScannerBoundUserInterfaceState(body.Uid, classes, types,
|
||||
CloningSystem.HasDnaScan(_bodyContainer.ContainedEntity.GetComponent<MindComponent>().Mind));
|
||||
}
|
||||
|
||||
private void UpdateUserInterface()
|
||||
@@ -207,22 +221,41 @@ namespace Content.Server.GameObjects.Components.Medical
|
||||
|
||||
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
|
||||
{
|
||||
if (!(obj.Message is UiButtonPressedMessage message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(obj.Message is UiButtonPressedMessage message)) return;
|
||||
|
||||
switch (message.Button)
|
||||
{
|
||||
case UiButton.ScanDNA:
|
||||
if (_bodyContainer.ContainedEntity != null)
|
||||
{
|
||||
CloningSystem.AddToScannedUids(_bodyContainer.ContainedEntity.Uid);
|
||||
//TODO: Show a 'ERROR: Body is completely devoid of soul' if no Mind owns the entity.
|
||||
CloningSystem.AddToDnaScans(_playerManager
|
||||
.GetPlayersBy(playerSession =>
|
||||
{
|
||||
var mindOwnedMob = playerSession.ContentData()?.Mind?.OwnedEntity;
|
||||
|
||||
return mindOwnedMob != null && mindOwnedMob ==
|
||||
_bodyContainer.ContainedEntity;
|
||||
}).Single()
|
||||
.ContentData()
|
||||
?.Mind);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanDragDropOn(DragDropEventArgs eventArgs)
|
||||
{
|
||||
return eventArgs.Dropped.HasComponent<BodyManagerComponent>();
|
||||
}
|
||||
|
||||
public bool DragDropOn(DragDropEventArgs eventArgs)
|
||||
{
|
||||
_bodyContainer.Insert(eventArgs.Dropped);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Server.GameObjects.Components.Body;
|
||||
using Content.Server.GameObjects.Components.Medical;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.Interfaces.GameTicking;
|
||||
using Content.Server.Mobs;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
@@ -14,6 +21,7 @@ using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Serilog.Debugging;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Mobs
|
||||
{
|
||||
@@ -50,6 +58,45 @@ namespace Content.Server.GameObjects.Components.Mobs
|
||||
set => _showExamineInfo = value;
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
private BoundUserInterface? UserInterface =>
|
||||
Owner.GetUIOrNull(SharedAcceptCloningComponent.AcceptCloningUiKey.Key);
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Owner.EntityManager.EventBus.SubscribeEvent<CloningPodComponent.CloningStartedMessage>(
|
||||
EventSource.Local, this,
|
||||
HandleCloningStartedMessage);
|
||||
|
||||
if (UserInterface != null)
|
||||
{
|
||||
UserInterface.OnReceiveMessage += OnUiAcceptCloningMessage;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCloningStartedMessage(CloningPodComponent.CloningStartedMessage ev)
|
||||
{
|
||||
if (ev.CapturedMind == Mind)
|
||||
{
|
||||
UserInterface?.Open(Mind.Session);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUiAcceptCloningMessage(ServerBoundUserInterfaceMessage obj)
|
||||
{
|
||||
if (!(obj.Message is SharedAcceptCloningComponent.UiButtonPressedMessage message)) return;
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new GhostComponent.GhostReturnMessage(Mind));
|
||||
}
|
||||
|
||||
public override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
Owner.EntityManager.EventBus.UnsubscribeEvent<CloningPodComponent.CloningStartedMessage>(EventSource.Local, this);
|
||||
if (UserInterface != null) UserInterface.OnReceiveMessage -= OnUiAcceptCloningMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Don't call this unless you know what the hell you're doing.
|
||||
/// Use <see cref="Mind.TransferTo(IEntity)"/> instead.
|
||||
@@ -133,13 +180,19 @@ namespace Content.Server.GameObjects.Components.Mobs
|
||||
if (!HasMind)
|
||||
{
|
||||
message.AddMarkup(!dead
|
||||
? $"[color=red]" + Loc.GetString("{0:They} {0:are} totally catatonic. The stresses of life in deep-space must have been too much for {0:them}. Any recovery is unlikely.", Owner) + "[/color]"
|
||||
? $"[color=red]" +
|
||||
Loc.GetString(
|
||||
"{0:They} {0:are} totally catatonic. The stresses of life in deep-space must have been too much for {0:them}. Any recovery is unlikely.",
|
||||
Owner) + "[/color]"
|
||||
: $"[color=purple]" + Loc.GetString("{0:Their} soul has departed.", Owner) + "[/color]");
|
||||
}
|
||||
else if (Mind?.Session == null)
|
||||
{
|
||||
if(!dead)
|
||||
message.AddMarkup("[color=yellow]" + Loc.GetString("{0:They} {0:have} a blank, absent-minded stare and appears completely unresponsive to anything. {0:They} may snap out of it soon.", Owner) + "[/color]");
|
||||
if (!dead)
|
||||
message.AddMarkup("[color=yellow]" +
|
||||
Loc.GetString(
|
||||
"{0:They} {0:have} a blank, absent-minded stare and appears completely unresponsive to anything. {0:They} may snap out of it soon.",
|
||||
Owner) + "[/color]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Content.Server.GameObjects.Components.Mobs
|
||||
hands.StopPull();
|
||||
break;
|
||||
default:
|
||||
player.PopupMessage(player, msg.Effect.ToString());
|
||||
player.PopupMessage(msg.Effect.ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@ namespace Content.Server.GameObjects.Components.Mobs.Speech
|
||||
[RegisterComponent]
|
||||
public class OwOAccentComponent : Component, IAccentComponent
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random;
|
||||
|
||||
public override string Name => "OwOAccent";
|
||||
|
||||
private static readonly IReadOnlyList<string> Faces = new List<string>{
|
||||
" (・`ω´・)", " ;;w;;", " owo", " UwU", " >w<", " ^w^"
|
||||
}.AsReadOnly();
|
||||
private string RandomFace => IoCManager.Resolve<IRobustRandom>().Pick(Faces);
|
||||
private string RandomFace => _random.Pick(Faces);
|
||||
|
||||
private static readonly Dictionary<string, string> SpecialWords = new Dictionary<string, string>
|
||||
{
|
||||
@@ -23,7 +25,7 @@ namespace Content.Server.GameObjects.Components.Mobs.Speech
|
||||
|
||||
public string Accentuate(string message)
|
||||
{
|
||||
foreach ((var word,var repl) in SpecialWords)
|
||||
foreach (var (word, repl) in SpecialWords)
|
||||
{
|
||||
message = message.Replace(word, repl);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace Content.Server.GameObjects.Components.Movement
|
||||
[RegisterComponent, ComponentReference(typeof(IMoverComponent))]
|
||||
public class AiControllerComponent : Component, IMoverComponent
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IGameTicker _gameTicker = default!;
|
||||
|
||||
private string? _logicName;
|
||||
private float _visionRadius;
|
||||
|
||||
@@ -36,7 +39,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
||||
}
|
||||
|
||||
public AiLogicProcessor? Processor { get; set; }
|
||||
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? StartingGearPrototype { get; set; }
|
||||
|
||||
@@ -61,13 +64,13 @@ namespace Content.Server.GameObjects.Components.Movement
|
||||
protected override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
|
||||
|
||||
if (StartingGearPrototype != null)
|
||||
{
|
||||
var startingGear = IoCManager.Resolve<IPrototypeManager>().Index<StartingGearPrototype>(StartingGearPrototype);
|
||||
IoCManager.Resolve<IGameTicker>().EquipStartingGear(Owner, startingGear);
|
||||
var startingGear = _prototypeManager.Index<StartingGearPrototype>(StartingGearPrototype);
|
||||
_gameTicker.EquipStartingGear(Owner, startingGear);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -77,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
||||
|
||||
serializer.DataField(ref _logicName, "logic", null);
|
||||
serializer.DataReadWriteFunction(
|
||||
"startingGear",
|
||||
"startingGear",
|
||||
null,
|
||||
startingGear => StartingGearPrototype = startingGear,
|
||||
() => StartingGearPrototype);
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Content.Server.GameObjects.Components.Movement
|
||||
canVault = CanVault(eventArgs.User, eventArgs.Dropped, eventArgs.Target, out reason);
|
||||
|
||||
if (!canVault)
|
||||
eventArgs.User.PopupMessage(eventArgs.User, reason);
|
||||
eventArgs.User.PopupMessage(reason);
|
||||
|
||||
return canVault;
|
||||
}
|
||||
|
||||
@@ -130,13 +130,13 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
|
||||
if (!Opened)
|
||||
{
|
||||
target.PopupMessage(target, Loc.GetString("Open it first!"));
|
||||
target.PopupMessage(Loc.GetString("Open it first!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_contents.CurrentVolume.Float() <= 0)
|
||||
{
|
||||
target.PopupMessage(target, Loc.GetString("It's empty!"));
|
||||
target.PopupMessage(Loc.GetString("It's empty!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -151,14 +151,14 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
if (_useSound == null) return false;
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f));
|
||||
target.PopupMessage(target, Loc.GetString("Slurp"));
|
||||
target.PopupMessage(Loc.GetString("Slurp"));
|
||||
UpdateAppearance();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Stomach was full or can't handle whatever solution we have.
|
||||
_contents.TryAddSolution(split);
|
||||
target.PopupMessage(target, Loc.GetString("You've had enough {0}!", Owner.Name));
|
||||
target.PopupMessage(Loc.GetString("You've had enough {0}!", Owner.Name));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
Opened = true;
|
||||
|
||||
var solution = component.SplitSolution(component.CurrentVolume);
|
||||
SpillHelper.SpillAt(Owner, solution, "PuddleSmear");
|
||||
solution.SpillAt(Owner, "PuddleSmear");
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity(_burstSound, Owner,
|
||||
AudioParams.Default.WithVolume(-4));
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
if (_utensilsNeeded != UtensilType.None)
|
||||
{
|
||||
eventArgs.User.PopupMessage(eventArgs.User, Loc.GetString("You need to use a {0} to eat that!", _utensilsNeeded));
|
||||
eventArgs.User.PopupMessage(Loc.GetString("You need to use a {0} to eat that!", _utensilsNeeded));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
|
||||
if (UsesRemaining <= 0)
|
||||
{
|
||||
user.PopupMessage(user, Loc.GetString("{0:TheName} is empty!", Owner));
|
||||
user.PopupMessage(Loc.GetString("{0:TheName} is empty!", Owner));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Nutrition;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -19,6 +18,8 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
[RegisterComponent]
|
||||
public sealed class HungerComponent : SharedHungerComponent
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
// Base stuff
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float BaseDecayRate
|
||||
@@ -141,7 +142,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
base.Startup();
|
||||
// Similar functionality to SS13. Should also stagger people going to the chef.
|
||||
_currentHunger = IoCManager.Resolve<IRobustRandom>().Next(
|
||||
_currentHunger = _random.Next(
|
||||
(int)_hungerThresholds[HungerThreshold.Peckish] + 10,
|
||||
(int)_hungerThresholds[HungerThreshold.Okay] - 1);
|
||||
_currentHungerThreshold = GetHungerThreshold(_currentHunger);
|
||||
|
||||
@@ -6,7 +6,6 @@ using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.Components.Movement;
|
||||
using Content.Shared.GameObjects.Components.Nutrition;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -19,6 +18,8 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
[RegisterComponent]
|
||||
public sealed class ThirstComponent : SharedThirstComponent
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
// Base stuff
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float BaseDecayRate
|
||||
@@ -136,7 +137,7 @@ namespace Content.Server.GameObjects.Components.Nutrition
|
||||
protected override void Startup()
|
||||
{
|
||||
base.Startup();
|
||||
_currentThirst = IoCManager.Resolve<IRobustRandom>().Next(
|
||||
_currentThirst = _random.Next(
|
||||
(int)ThirstThresholds[ThirstThreshold.Thirsty] + 10,
|
||||
(int)ThirstThresholds[ThirstThreshold.Okay] - 1);
|
||||
_currentThirstThreshold = GetThirstThreshold(_currentThirst);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Server.Players;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.Mobs;
|
||||
using Content.Server.Players;
|
||||
using Content.Shared.GameObjects.Components.Observer;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components;
|
||||
@@ -31,7 +33,7 @@ namespace Content.Server.GameObjects.Components.Observer
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
Owner.EnsureComponent<VisibilityComponent>().Layer = (int)VisibilityFlags.Ghost;
|
||||
Owner.EnsureComponent<VisibilityComponent>().Layer = (int) VisibilityFlags.Ghost;
|
||||
}
|
||||
|
||||
public override ComponentState GetComponentState() => new GhostComponentState(CanReturnToBody);
|
||||
@@ -43,18 +45,19 @@ namespace Content.Server.GameObjects.Components.Observer
|
||||
switch (message)
|
||||
{
|
||||
case PlayerAttachedMsg msg:
|
||||
msg.NewPlayer.VisibilityMask |= (int)VisibilityFlags.Ghost;
|
||||
msg.NewPlayer.VisibilityMask |= (int) VisibilityFlags.Ghost;
|
||||
Dirty();
|
||||
break;
|
||||
case PlayerDetachedMsg msg:
|
||||
msg.OldPlayer.VisibilityMask &= ~(int)VisibilityFlags.Ghost;
|
||||
msg.OldPlayer.VisibilityMask &= ~(int) VisibilityFlags.Ghost;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession session = null)
|
||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel,
|
||||
ICommonSession session = null)
|
||||
{
|
||||
base.HandleNetworkMessage(message, netChannel, session);
|
||||
|
||||
@@ -67,10 +70,29 @@ namespace Content.Server.GameObjects.Components.Observer
|
||||
actor.playerSession.ContentData().Mind.UnVisit();
|
||||
Owner.Delete();
|
||||
}
|
||||
|
||||
break;
|
||||
case ReturnToCloneComponentMessage reenter:
|
||||
|
||||
if (Owner.TryGetComponent(out VisitingMindComponent mind))
|
||||
{
|
||||
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new GhostReturnMessage(mind.Mind));
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public class GhostReturnMessage : EntitySystemMessage
|
||||
{
|
||||
public GhostReturnMessage(Mind sender)
|
||||
{
|
||||
Sender = sender;
|
||||
}
|
||||
|
||||
public Mind Sender { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Server.GameObjects.Components.NodeContainer;
|
||||
using Content.Server.GameObjects.Components.NodeContainer.NodeGroups;
|
||||
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
|
||||
using Content.Server.GameObjects.Components.Power.PowerNetComponents;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.GameObjects.Components.Power.AME;
|
||||
@@ -20,11 +19,11 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Interfaces;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Power.AME
|
||||
{
|
||||
@@ -33,8 +32,6 @@ namespace Content.Server.GameObjects.Components.Power.AME
|
||||
[ComponentReference(typeof(IInteractUsing))]
|
||||
public class AMEControllerComponent : SharedAMEControllerComponent, IActivate, IInteractUsing
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(AMEControllerUiKey.Key);
|
||||
[ViewVariables] private bool _injecting;
|
||||
[ViewVariables] public int InjectionAmount;
|
||||
@@ -117,8 +114,7 @@ namespace Content.Server.GameObjects.Components.Power.AME
|
||||
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -328,15 +324,13 @@ namespace Content.Server.GameObjects.Components.Power.AME
|
||||
{
|
||||
if (!args.User.TryGetComponent(out IHandsComponent? hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hands.GetActiveHand == null)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have nothing on your hand."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have nothing on your hand."));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -345,22 +339,19 @@ namespace Content.Server.GameObjects.Components.Power.AME
|
||||
{
|
||||
if (HasJar)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("The controller already has a jar loaded."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("The controller already has a jar loaded."));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_jarSlot.Insert(activeHandEntity);
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You insert the jar into the fuel slot."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You insert the jar into the fuel slot."));
|
||||
UpdateUserInterface();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You can't put that in the controller..."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You can't put that in the controller..."));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.GameObjects.Components.Interactable;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||
using Content.Shared.GameObjects.Components.Interactable;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
@@ -10,6 +9,7 @@ using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Interfaces;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Power.AME
|
||||
{
|
||||
@@ -19,15 +19,14 @@ namespace Content.Server.GameObjects.Components.Power.AME
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public override string Name => "AMEPart";
|
||||
|
||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
|
||||
{
|
||||
if (!args.User.TryGetComponent(out IHandsComponent hands))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, args.User,
|
||||
Loc.GetString("You have no hands."));
|
||||
Owner.PopupMessage(args.User, Loc.GetString("You have no hands."));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
||||
[RegisterComponent]
|
||||
public class PowerProviderComponent : BaseApcNetComponent, IPowerProvider
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager;
|
||||
|
||||
public override string Name => "PowerProvider";
|
||||
|
||||
/// <summary>
|
||||
@@ -91,14 +94,13 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
||||
|
||||
private List<PowerReceiverComponent> FindAvailableReceivers()
|
||||
{
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var nearbyEntities = IoCManager.Resolve<IServerEntityManager>()
|
||||
var nearbyEntities = _serverEntityManager
|
||||
.GetEntitiesInRange(Owner, PowerTransferRange);
|
||||
return nearbyEntities.Select(entity => entity.TryGetComponent<PowerReceiverComponent>(out var receiver) ? receiver : null)
|
||||
.Where(receiver => receiver != null)
|
||||
.Where(receiver => receiver.Connectable)
|
||||
.Where(receiver => receiver.NeedsProvider)
|
||||
.Where(receiver => receiver.Owner.Transform.GridPosition.Distance(mapManager, Owner.Transform.GridPosition) < Math.Min(PowerTransferRange, receiver.PowerReceptionRange))
|
||||
.Where(receiver => receiver.Owner.Transform.GridPosition.Distance(_mapManager, Owner.Transform.GridPosition) < Math.Min(PowerTransferRange, receiver.PowerReceptionRange))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
||||
[RegisterComponent]
|
||||
public class PowerReceiverComponent : Component, IExamine
|
||||
{
|
||||
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
public override string Name => "PowerReceiver";
|
||||
|
||||
public event EventHandler<PowerStateEventArgs> OnPowerStateChanged;
|
||||
@@ -116,16 +119,16 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents
|
||||
|
||||
private bool TryFindAvailableProvider(out IPowerProvider foundProvider)
|
||||
{
|
||||
var nearbyEntities = IoCManager.Resolve<IServerEntityManager>()
|
||||
var nearbyEntities = _serverEntityManager
|
||||
.GetEntitiesInRange(Owner, PowerReceptionRange);
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
|
||||
foreach (var entity in nearbyEntities)
|
||||
{
|
||||
if (entity.TryGetComponent<PowerProviderComponent>(out var provider))
|
||||
{
|
||||
if (provider.Connectable)
|
||||
{
|
||||
var distanceToProvider = provider.Owner.Transform.GridPosition.Distance(mapManager, Owner.Transform.GridPosition);
|
||||
var distanceToProvider = provider.Owner.Transform.GridPosition.Distance(_mapManager, Owner.Transform.GridPosition);
|
||||
if (distanceToProvider < Math.Min(PowerReceptionRange, provider.PowerTransferRange))
|
||||
{
|
||||
foundProvider = provider;
|
||||
|
||||
@@ -4,7 +4,6 @@ using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Items.Storage;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
@@ -32,6 +31,8 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
||||
[RegisterComponent]
|
||||
public class PoweredLightComponent : Component, IInteractHand, IInteractUsing, IMapInit, ISignalReceiver
|
||||
{
|
||||
[Dependency] private IGameTiming _gameTiming = default!;
|
||||
|
||||
public override string Name => "PoweredLight";
|
||||
|
||||
private static readonly TimeSpan _thunkDelay = TimeSpan.FromSeconds(2);
|
||||
@@ -41,6 +42,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
||||
|
||||
private LightBulbType BulbType = LightBulbType.Tube;
|
||||
[ViewVariables] private ContainerSlot _lightBulbContainer;
|
||||
|
||||
[ViewVariables]
|
||||
private LightBulbComponent LightBulb
|
||||
{
|
||||
@@ -63,8 +65,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
||||
case BeginDeconstructCompMsg msg:
|
||||
if (!msg.BlockDeconstruct && !(_lightBulbContainer.ContainedEntity is null))
|
||||
{
|
||||
var notifyManager = IoCManager.Resolve<IServerNotifyManager>();
|
||||
notifyManager.PopupMessage(Owner, msg.User, "Remove the bulb.");
|
||||
Owner.PopupMessage(msg.User, Loc.GetString("Remove the bulb."));
|
||||
msg.BlockDeconstruct = true;
|
||||
}
|
||||
break;
|
||||
@@ -211,7 +212,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
|
||||
sprite.LayerSetState(0, "on");
|
||||
light.Enabled = true;
|
||||
light.Color = LightBulb.Color;
|
||||
var time = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||
var time = _gameTiming.CurTime;
|
||||
if (time > _lastThunk + _thunkDelay)
|
||||
{
|
||||
_lastThunk = time;
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
||||
[RegisterComponent]
|
||||
public class HitscanComponent : Component
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
public override string Name => "Hitscan";
|
||||
public CollisionGroup CollisionMask => (CollisionGroup) _collisionMask;
|
||||
private int _collisionMask;
|
||||
@@ -60,7 +62,7 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
||||
public void FireEffects(IEntity user, float distance, Angle angle, IEntity hitEntity = null)
|
||||
{
|
||||
var effectSystem = EntitySystem.Get<EffectSystem>();
|
||||
_startTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||
_startTime = _gameTiming.CurTime;
|
||||
_deathTime = _startTime + TimeSpan.FromSeconds(1);
|
||||
|
||||
var afterEffect = AfterEffects(user.Transform.GridPosition, angle, distance, 1.0f);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -13,7 +14,7 @@ namespace Content.Server.GameObjects.Components
|
||||
class RadioComponent : Component, IUse, IListen
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
|
||||
public override string Name => "Radio";
|
||||
|
||||
@@ -51,8 +52,7 @@ namespace Content.Server.GameObjects.Components
|
||||
|
||||
public void Speaker(string message)
|
||||
{
|
||||
var chat = IoCManager.Resolve<IChatManager>();
|
||||
chat.EntitySay(Owner, message);
|
||||
_chatManager.EntitySay(Owner, message);
|
||||
}
|
||||
|
||||
public bool UseEntity(UseEntityEventArgs eventArgs)
|
||||
@@ -60,11 +60,11 @@ namespace Content.Server.GameObjects.Components
|
||||
RadioOn = !RadioOn;
|
||||
if(RadioOn)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, eventArgs.User, "The radio is now on.");
|
||||
Owner.PopupMessage(eventArgs.User, "The radio is now on.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner, eventArgs.User, "The radio is now off.");
|
||||
Owner.PopupMessage(eventArgs.User, "The radio is now off.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Content.Server.GameObjects.Components.Research
|
||||
[ComponentReference(typeof(SharedLatheDatabaseComponent))]
|
||||
public class ProtolatheDatabaseComponent : SharedProtolatheDatabaseComponent
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public override string Name => "ProtolatheDatabase";
|
||||
|
||||
public override ComponentState GetComponentState()
|
||||
@@ -24,13 +26,11 @@ namespace Content.Server.GameObjects.Components.Research
|
||||
{
|
||||
if (!Owner.TryGetComponent(out TechnologyDatabaseComponent database)) return;
|
||||
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
foreach (var technology in database.Technologies)
|
||||
{
|
||||
foreach (var id in technology.UnlockedRecipes)
|
||||
{
|
||||
var recipe = (LatheRecipePrototype)prototypeManager.Index(typeof(LatheRecipePrototype), id);
|
||||
var recipe = (LatheRecipePrototype) _prototypeManager.Index(typeof(LatheRecipePrototype), id);
|
||||
UnlockRecipe(recipe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +57,7 @@ namespace Content.Server.GameObjects.Components.Research
|
||||
switch (message.Message)
|
||||
{
|
||||
case ConsoleUnlockTechnologyMessage msg:
|
||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
if (!protoMan.TryIndex(msg.Id, out TechnologyPrototype tech)) break;
|
||||
if (!_prototypeManager.TryIndex(msg.Id, out TechnologyPrototype tech)) break;
|
||||
if (client.Server == null) break;
|
||||
if (!client.Server.CanUnlockTechnology(tech)) break;
|
||||
if (client.Server.UnlockTechnology(tech))
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#nullable enable
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -14,8 +13,6 @@ namespace Content.Server.GameObjects.Components.Rotatable
|
||||
[RegisterComponent]
|
||||
public class FlippableComponent : Component
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public override string Name => "Flippable";
|
||||
|
||||
private string? _entity;
|
||||
@@ -25,7 +22,7 @@ namespace Content.Server.GameObjects.Components.Rotatable
|
||||
if (Owner.TryGetComponent(out ICollidableComponent? collidable) &&
|
||||
collidable.Anchored)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, Loc.GetString("It's stuck."));
|
||||
Owner.PopupMessage(user, Loc.GetString("It's stuck."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.GameObjects.Verbs;
|
||||
using Content.Shared.Interfaces;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -13,8 +12,6 @@ namespace Content.Server.GameObjects.Components.Rotatable
|
||||
[RegisterComponent]
|
||||
public class RotatableComponent : Component
|
||||
{
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
|
||||
|
||||
public override string Name => "Rotatable";
|
||||
|
||||
private void TryRotate(IEntity user, Angle angle)
|
||||
@@ -23,7 +20,7 @@ namespace Content.Server.GameObjects.Components.Rotatable
|
||||
{
|
||||
if (collidable.Anchored)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, user, Loc.GetString("It's stuck."));
|
||||
Owner.PopupMessage(user, Loc.GetString("It's stuck."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Timers;
|
||||
@@ -19,8 +18,6 @@ namespace Content.Server.GameObjects.Components.Stack
|
||||
[RegisterComponent]
|
||||
public class StackComponent : SharedStackComponent, IInteractUsing, IExamine
|
||||
{
|
||||
[Dependency] private readonly ISharedNotifyManager _sharedNotifyManager = default!;
|
||||
|
||||
private bool _throwIndividually = false;
|
||||
|
||||
public override int Count
|
||||
@@ -82,20 +79,19 @@ namespace Content.Server.GameObjects.Components.Stack
|
||||
|
||||
if (toTransfer > 0)
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(popupPos, eventArgs.User, $"+{toTransfer}");
|
||||
popupPos.PopupMessage(eventArgs.User, $"+{toTransfer}");
|
||||
|
||||
if (stack.AvailableSpace == 0)
|
||||
{
|
||||
|
||||
Timer.Spawn(300, () => _sharedNotifyManager.PopupMessage(popupPos, eventArgs.User, "Stack is now full."));
|
||||
Timer.Spawn(300, () => popupPos.PopupMessage(eventArgs.User, "Stack is now full."));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (toTransfer == 0 && stack.AvailableSpace == 0)
|
||||
{
|
||||
_sharedNotifyManager.PopupMessage(popupPos, eventArgs.User, "Stack is already full.");
|
||||
popupPos.PopupMessage(eventArgs.User, "Stack is already full.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -15,12 +15,15 @@ namespace Content.Server.GameObjects.Components.StationEvents
|
||||
[RegisterComponent]
|
||||
public sealed class RadiationPulseComponent : SharedRadiationPulseComponent
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private const float MinPulseLifespan = 0.8f;
|
||||
private const float MaxPulseLifespan = 2.5f;
|
||||
|
||||
public float DPS => _dps;
|
||||
private float _dps;
|
||||
|
||||
|
||||
private TimeSpan _endTime;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
@@ -33,15 +36,15 @@ namespace Content.Server.GameObjects.Components.StationEvents
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
var currentTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||
var currentTime = _gameTiming.CurTime;
|
||||
var duration =
|
||||
TimeSpan.FromSeconds(
|
||||
IoCManager.Resolve<IRobustRandom>().NextFloat() * (MaxPulseLifespan - MinPulseLifespan) +
|
||||
_random.NextFloat() * (MaxPulseLifespan - MinPulseLifespan) +
|
||||
MinPulseLifespan);
|
||||
|
||||
_endTime = currentTime + duration;
|
||||
|
||||
Timer.Spawn(duration,
|
||||
|
||||
Timer.Spawn(duration,
|
||||
() =>
|
||||
{
|
||||
if (!Owner.Deleted)
|
||||
@@ -59,4 +62,4 @@ namespace Content.Server.GameObjects.Components.StationEvents
|
||||
return new RadiationPulseMessage(_endTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Content.Shared.Utility;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
||||
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct, IWires
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private bool _ejecting;
|
||||
private TimeSpan _animationDuration = TimeSpan.Zero;
|
||||
@@ -77,8 +78,7 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
||||
private void InitializeFromPrototype()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_packPrototypeId)) { return; }
|
||||
var prototypeManger = IoCManager.Resolve<IPrototypeManager>();
|
||||
if (!prototypeManger.TryIndex(_packPrototypeId, out VendingMachineInventoryPrototype packPrototype))
|
||||
if (!_prototypeManager.TryIndex(_packPrototypeId, out VendingMachineInventoryPrototype packPrototype))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,13 +12,14 @@ namespace Content.Server.GameObjects.Components.Weapon
|
||||
[RegisterComponent]
|
||||
public sealed class FlashableComponent : SharedFlashableComponent
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
|
||||
private double _duration;
|
||||
private TimeSpan _lastFlash;
|
||||
|
||||
public void Flash(double duration)
|
||||
{
|
||||
var timing = IoCManager.Resolve<IGameTiming>();
|
||||
_lastFlash = timing.CurTime;
|
||||
_lastFlash = _gameTiming.CurTime;
|
||||
_duration = duration;
|
||||
Dirty();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user