mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-06-09 13:26:34 +02:00
merge remote wizden/master
This commit is contained in:
@@ -9,6 +9,11 @@
|
|||||||
## Технические детали
|
## Технические детали
|
||||||
<!-- Краткое описание изменений в коде для облегчения проверки. -->
|
<!-- Краткое описание изменений в коде для облегчения проверки. -->
|
||||||
|
|
||||||
|
## Test plan
|
||||||
|
<!--
|
||||||
|
Describe how you tested the pull request, and how someone reviewing this PR can test it themselves.
|
||||||
|
-->
|
||||||
|
|
||||||
## Медиа
|
## Медиа
|
||||||
<!-- Прикрепите медиафайлы, если PR вносит изменения в игру (одежда, предметы, механики и т.д.).
|
<!-- Прикрепите медиафайлы, если PR вносит изменения в игру (одежда, предметы, механики и т.д.).
|
||||||
Небольшие исправления/рефакторинг освобождаются от этого требования. -->
|
Небольшие исправления/рефакторинг освобождаются от этого требования. -->
|
||||||
@@ -16,6 +21,7 @@
|
|||||||
## Требования
|
## Требования
|
||||||
<!-- Подтвердите следующее, поставив X в скобках без пробелов [X]: -->
|
<!-- Подтвердите следующее, поставив X в скобках без пробелов [X]: -->
|
||||||
- [ ] Я прочитал(а) и следую [Рекомендациям по оформлению Pull Request и Changelog](https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html).
|
- [ ] Я прочитал(а) и следую [Рекомендациям по оформлению Pull Request и Changelog](https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html).
|
||||||
|
- [ ] I have tested this pull request and written instructions on how to test it
|
||||||
- [ ] Я добавил(а) медиафайлы к этому PR или он не требует демонстрации в игре.
|
- [ ] Я добавил(а) медиафайлы к этому PR или он не требует демонстрации в игре.
|
||||||
<!-- Вы должны понимать, что несоблюдение вышеуказанного может привести к закрытию вашего PR по усмотрению сопровождающего -->
|
<!-- Вы должны понимать, что несоблюдение вышеуказанного может привести к закрытию вашего PR по усмотрению сопровождающего -->
|
||||||
|
|
||||||
|
|||||||
@@ -317,3 +317,6 @@ Resources/MapImages
|
|||||||
|
|
||||||
# Direnv stuff
|
# Direnv stuff
|
||||||
.direnv/
|
.direnv/
|
||||||
|
|
||||||
|
# C# Dev Kit cache file
|
||||||
|
*.lscache
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ namespace Content.Client.Actions
|
|||||||
SetIcon(actionId, new SpriteSpecifier.EntityPrototype(id));
|
SetIcon(actionId, new SpriteSpecifier.EntityPrototype(id));
|
||||||
SetEvent(actionId, new StartPlacementActionEvent()
|
SetEvent(actionId, new StartPlacementActionEvent()
|
||||||
{
|
{
|
||||||
PlacementOption = "SnapgridCenter",
|
PlacementOption = proto.PlacementMode,
|
||||||
EntityType = id
|
EntityType = id
|
||||||
});
|
});
|
||||||
_metaData.SetEntityName(actionId, proto.Name);
|
_metaData.SetEntityName(actionId, proto.Name);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Content.Shared.Cargo;
|
|
||||||
using Content.Client.Cargo.UI;
|
using Content.Client.Cargo.UI;
|
||||||
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.Cargo.BUI;
|
using Content.Shared.Cargo.BUI;
|
||||||
using Content.Shared.Cargo.Components;
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.Cargo.Events;
|
using Content.Shared.Cargo.Events;
|
||||||
@@ -7,15 +7,15 @@ using Content.Shared.Cargo.Prototypes;
|
|||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.Cargo.BUI
|
namespace Content.Client.Cargo.BUI
|
||||||
{
|
{
|
||||||
public sealed class CargoOrderConsoleBoundUserInterface : BoundUserInterface
|
public sealed partial class CargoOrderConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||||
{
|
{
|
||||||
private readonly SharedCargoSystem _cargoSystem;
|
[Dependency] private SharedCargoSystem _cargoSystem = default!;
|
||||||
|
[Dependency] private IdentitySystem _identity = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private CargoConsoleMenu? _menu;
|
private CargoConsoleMenu? _menu;
|
||||||
@@ -44,11 +44,6 @@ namespace Content.Client.Cargo.BUI
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private CargoProductPrototype? _product;
|
private CargoProductPrototype? _product;
|
||||||
|
|
||||||
public CargoOrderConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
|
||||||
{
|
|
||||||
_cargoSystem = EntMan.System<SharedCargoSystem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Open()
|
protected override void Open()
|
||||||
{
|
{
|
||||||
base.Open();
|
base.Open();
|
||||||
@@ -59,12 +54,9 @@ namespace Content.Client.Cargo.BUI
|
|||||||
var localPlayer = dependencies.Resolve<IPlayerManager>().LocalEntity;
|
var localPlayer = dependencies.Resolve<IPlayerManager>().LocalEntity;
|
||||||
var description = new FormattedMessage();
|
var description = new FormattedMessage();
|
||||||
|
|
||||||
string orderRequester;
|
var orderRequester = Loc.GetString("cargo-console-paper-approver-default");
|
||||||
|
|
||||||
if (EntMan.EntityExists(localPlayer))
|
if (EntMan.EntityExists(localPlayer))
|
||||||
orderRequester = Identity.Name(localPlayer.Value, EntMan);
|
orderRequester = _identity.GetIdentityShortInfo(localPlayer.Value, Owner) ?? orderRequester;
|
||||||
else
|
|
||||||
orderRequester = string.Empty;
|
|
||||||
|
|
||||||
_orderMenu = new CargoConsoleOrderMenu();
|
_orderMenu = new CargoConsoleOrderMenu();
|
||||||
|
|
||||||
@@ -142,6 +134,11 @@ namespace Content.Client.Cargo.BUI
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_menu.ProductCatalogue = cState.Products;
|
_menu.ProductCatalogue = cState.Products;
|
||||||
|
_menu.ShuttleCapacityLabel.Text = Loc.GetString(
|
||||||
|
"cargo-console-menu-order-capacity-number",
|
||||||
|
("count", OrderCount),
|
||||||
|
("capacity", OrderCapacity)
|
||||||
|
);
|
||||||
|
|
||||||
_menu?.UpdateStation(station);
|
_menu?.UpdateStation(station);
|
||||||
Populate(cState.Orders);
|
Populate(cState.Orders);
|
||||||
|
|||||||
@@ -52,7 +52,8 @@
|
|||||||
<PanelContainer StyleClasses="LowDivider" Margin="0 -2 0 -1"/>
|
<PanelContainer StyleClasses="LowDivider" Margin="0 -2 0 -1"/>
|
||||||
|
|
||||||
<Label Name="ShuttleCapacityLabel"
|
<Label Name="ShuttleCapacityLabel"
|
||||||
Text="0/20"
|
Text="0/0"
|
||||||
|
Access="Public"
|
||||||
Margin="4 0"/>
|
Margin="4 0"/>
|
||||||
</GridContainer>
|
</GridContainer>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
|
||||||
Resizable="False"
|
Resizable="False"
|
||||||
MaxSize="400 800"
|
MaxSize="400 800"
|
||||||
MinSize="400 150">
|
MinSize="400 150">
|
||||||
@@ -10,7 +9,7 @@
|
|||||||
<!-- Header text -->
|
<!-- Header text -->
|
||||||
<controls:StripeBack>
|
<controls:StripeBack>
|
||||||
<PanelContainer>
|
<PanelContainer>
|
||||||
<RichTextLabel Name="EmergencyBroadcastText" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10 10 10 10" ReservesSpace="False"/>
|
<RichTextLabel Text="{Loc 'holopad-window-emergency-broadcast-in-progress'}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10 10 10 10" ReservesSpace="False"/>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</controls:StripeBack>
|
</controls:StripeBack>
|
||||||
|
|
||||||
@@ -52,8 +51,8 @@
|
|||||||
<controls:StripeBack>
|
<controls:StripeBack>
|
||||||
<PanelContainer>
|
<PanelContainer>
|
||||||
<BoxContainer Orientation="Vertical">
|
<BoxContainer Orientation="Vertical">
|
||||||
<RichTextLabel Name="SubtitleText" HorizontalAlignment="Center" Margin="0 5 0 0"/>
|
<RichTextLabel Text="{Loc 'holopad-window-subtitle'}" HorizontalAlignment="Center" Margin="0 5 0 0"/>
|
||||||
<RichTextLabel Name="OptionsText" HorizontalAlignment="Center" Margin="0 0 0 5"/>
|
<RichTextLabel Text="{Loc 'holopad-window-options'}" HorizontalAlignment="Center" Margin="0 0 0 5"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
</controls:StripeBack>
|
</controls:StripeBack>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Content.Client.Holopad;
|
namespace Content.Client.Holopad;
|
||||||
|
|
||||||
@@ -19,22 +18,18 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
{
|
{
|
||||||
[Dependency] private IEntityManager _entManager = default!;
|
[Dependency] private IEntityManager _entManager = default!;
|
||||||
[Dependency] private IPlayerManager _playerManager = default!;
|
[Dependency] private IPlayerManager _playerManager = default!;
|
||||||
|
[Dependency] private ILogManager _logManager = default!;
|
||||||
[Dependency] private IGameTiming _timing = default!;
|
[Dependency] private IGameTiming _timing = default!;
|
||||||
|
|
||||||
private readonly SharedHolopadSystem _holopadSystem = default!;
|
private readonly SharedHolopadSystem _holopadSystem = default!;
|
||||||
private readonly SharedTelephoneSystem _telephoneSystem = default!;
|
private readonly SharedTelephoneSystem _telephoneSystem = default!;
|
||||||
private readonly AccessReaderSystem _accessReaderSystem = default!;
|
private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||||
private readonly PopupSystem _popupSystem = default!;
|
private readonly PopupSystem _popupSystem = default!;
|
||||||
|
private readonly ISawmill _sawmill = default!;
|
||||||
|
|
||||||
private EntityUid? _owner = null;
|
private EntityUid? _owner = null;
|
||||||
private HolopadUiKey _currentUiKey;
|
private HolopadUiKey _currentUiKey;
|
||||||
private TelephoneState _currentState;
|
private string _currentSearch = string.Empty;
|
||||||
private TelephoneState _previousState;
|
|
||||||
private TimeSpan _buttonUnlockTime;
|
|
||||||
private float _updateTimer = 0.25f;
|
|
||||||
|
|
||||||
private const float UpdateTime = 0.25f;
|
|
||||||
private TimeSpan _buttonUnlockDelay = TimeSpan.FromSeconds(0.5f);
|
|
||||||
|
|
||||||
public event Action<NetEntity>? SendHolopadStartNewCallMessageAction;
|
public event Action<NetEntity>? SendHolopadStartNewCallMessageAction;
|
||||||
public event Action? SendHolopadAnswerCallMessageAction;
|
public event Action? SendHolopadAnswerCallMessageAction;
|
||||||
@@ -43,6 +38,9 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
public event Action? SendHolopadActivateProjectorMessageAction;
|
public event Action? SendHolopadActivateProjectorMessageAction;
|
||||||
public event Action? SendHolopadRequestStationAiMessageAction;
|
public event Action? SendHolopadRequestStationAiMessageAction;
|
||||||
|
|
||||||
|
private TimeSpan _updateDelay = TimeSpan.FromSeconds(0.25f);
|
||||||
|
private TimeSpan _nextUpdate;
|
||||||
|
|
||||||
public HolopadWindow()
|
public HolopadWindow()
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
@@ -52,8 +50,7 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
_telephoneSystem = _entManager.System<SharedTelephoneSystem>();
|
_telephoneSystem = _entManager.System<SharedTelephoneSystem>();
|
||||||
_accessReaderSystem = _entManager.System<AccessReaderSystem>();
|
_accessReaderSystem = _entManager.System<AccessReaderSystem>();
|
||||||
_popupSystem = _entManager.System<PopupSystem>();
|
_popupSystem = _entManager.System<PopupSystem>();
|
||||||
|
_sawmill = _logManager.GetSawmill("Holopad");
|
||||||
_buttonUnlockTime = _timing.CurTime + _buttonUnlockDelay;
|
|
||||||
|
|
||||||
// Assign button actions
|
// Assign button actions
|
||||||
AnswerCallButton.OnPressed += args => { OnHolopadAnswerCallMessage(); };
|
AnswerCallButton.OnPressed += args => { OnHolopadAnswerCallMessage(); };
|
||||||
@@ -78,10 +75,6 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
{
|
{
|
||||||
BackgroundColor = new Color(82, 82, 82),
|
BackgroundColor = new Color(82, 82, 82),
|
||||||
};
|
};
|
||||||
|
|
||||||
EmergencyBroadcastText.SetMessage(FormattedMessage.FromMarkupOrThrow(Loc.GetString("holopad-window-emergency-broadcast-in-progress")));
|
|
||||||
SubtitleText.SetMessage(FormattedMessage.FromMarkupOrThrow(Loc.GetString("holopad-window-subtitle")));
|
|
||||||
OptionsText.SetMessage(FormattedMessage.FromMarkupOrThrow(Loc.GetString("holopad-window-options")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region: Button actions
|
#region: Button actions
|
||||||
@@ -166,16 +159,28 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
|
|
||||||
public void UpdateState(Dictionary<NetEntity, string> holopads)
|
public void UpdateState(Dictionary<NetEntity, string> holopads)
|
||||||
{
|
{
|
||||||
if (_owner == null || !_entManager.TryGetComponent<TelephoneComponent>(_owner.Value, out var telephone))
|
if (!_entManager.TryGetComponent<TelephoneComponent>(_owner, out var telephone))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Caller ID text
|
// Caller and holopad ID text
|
||||||
var callerId = _telephoneSystem.GetFormattedCallerIdForEntity(telephone.LastCallerId.Item1, telephone.LastCallerId.Item2, Color.LightGray, "Default", 11);
|
var callerId = _telephoneSystem.GetFormattedCallerIdForEntity(telephone.LastCallerId?.CallerId, telephone.LastCallerId?.CallerJob, Color.LightGray, "Default", 11);
|
||||||
var holoapdId = _telephoneSystem.GetFormattedDeviceIdForEntity(telephone.LastCallerId.Item3, Color.LightGray, "Default", 11);
|
var holopadId = _telephoneSystem.GetFormattedDeviceIdForEntity(telephone.LastCallerId?.DeviceId, Color.LightGray, "Default", 11);
|
||||||
|
|
||||||
CallerIdText.SetMessage(FormattedMessage.FromMarkupPermissive(callerId));
|
if (!FormattedMessage.TryFromMarkup(callerId, out var callerIdMsg))
|
||||||
HolopadIdText.SetMessage(FormattedMessage.FromMarkupPermissive(holoapdId));
|
{
|
||||||
LockOutIdText.SetMessage(FormattedMessage.FromMarkupPermissive(callerId));
|
callerIdMsg = FormattedMessage.FromMarkupPermissive(callerId);
|
||||||
|
_sawmill.Error($"CallerId markup text was incorrectly formatted: {callerIdMsg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FormattedMessage.TryFromMarkup(holopadId, out var holopadIdMsg))
|
||||||
|
{
|
||||||
|
holopadIdMsg = FormattedMessage.FromMarkupPermissive(holopadId);
|
||||||
|
_sawmill.Error($"HolopadId markup text was incorrectly formatted: {holopadIdMsg}");
|
||||||
|
}
|
||||||
|
|
||||||
|
CallerIdText.SetMessage(callerIdMsg);
|
||||||
|
LockOutIdText.SetMessage(callerIdMsg);
|
||||||
|
HolopadIdText.SetMessage(holopadIdMsg);
|
||||||
|
|
||||||
// Sort holopads alphabetically
|
// Sort holopads alphabetically
|
||||||
var holopadArray = holopads.ToArray();
|
var holopadArray = holopads.ToArray();
|
||||||
@@ -183,7 +188,9 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
|
|
||||||
// Clear excess children from the contact list
|
// Clear excess children from the contact list
|
||||||
while (ContactsList.ChildCount > holopadArray.Length)
|
while (ContactsList.ChildCount > holopadArray.Length)
|
||||||
|
{
|
||||||
ContactsList.RemoveChild(ContactsList.GetChild(ContactsList.ChildCount - 1));
|
ContactsList.RemoveChild(ContactsList.GetChild(ContactsList.ChildCount - 1));
|
||||||
|
}
|
||||||
|
|
||||||
// Make / update required children
|
// Make / update required children
|
||||||
for (int i = 0; i < holopadArray.Length; i++)
|
for (int i = 0; i < holopadArray.Length; i++)
|
||||||
@@ -213,55 +220,57 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
|
|
||||||
private void UpdateAppearance()
|
private void UpdateAppearance()
|
||||||
{
|
{
|
||||||
if (_owner == null || !_entManager.TryGetComponent<TelephoneComponent>(_owner.Value, out var telephone))
|
if (!_entManager.TryGetComponent<TelephoneComponent>(_owner, out var telephone))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_owner == null || !_entManager.TryGetComponent<HolopadComponent>(_owner.Value, out var holopad))
|
if (!_entManager.TryGetComponent<HolopadComponent>(_owner, out var holopad))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hasBroadcastAccess = !_holopadSystem.IsHolopadBroadcastOnCoolDown((_owner.Value, holopad));
|
var broadcastOnCooldown = _holopadSystem.IsHolopadBroadcastOnCoolDown((_owner.Value, holopad));
|
||||||
var localPlayer = _playerManager.LocalSession?.AttachedEntity;
|
var localPlayer = _playerManager.LocalSession?.AttachedEntity;
|
||||||
|
|
||||||
|
// Update container visibility
|
||||||
ControlsLockOutContainer.Visible = _holopadSystem.IsHolopadControlLocked((_owner.Value, holopad), localPlayer);
|
ControlsLockOutContainer.Visible = _holopadSystem.IsHolopadControlLocked((_owner.Value, holopad), localPlayer);
|
||||||
ControlsContainer.Visible = !ControlsLockOutContainer.Visible;
|
ControlsContainer.Visible = !ControlsLockOutContainer.Visible;
|
||||||
|
|
||||||
// Temporarily disable the interface buttons when the call state changes to prevent any misclicks
|
// Update contact button visibility
|
||||||
if (_currentState != telephone.CurrentState)
|
if (SearchLineEdit.Text != _currentSearch)
|
||||||
{
|
{
|
||||||
_previousState = _currentState;
|
_currentSearch = SearchLineEdit.Text;
|
||||||
_currentState = telephone.CurrentState;
|
|
||||||
_buttonUnlockTime = _timing.CurTime + _buttonUnlockDelay;
|
foreach (var child in ContactsList.Children)
|
||||||
|
{
|
||||||
|
if (child is not HolopadContactButton contactButton)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var passesFilter = string.IsNullOrEmpty(SearchLineEdit.Text) ||
|
||||||
|
contactButton.Text?.Contains(SearchLineEdit.Text, StringComparison.CurrentCultureIgnoreCase) == true;
|
||||||
|
|
||||||
|
contactButton.Visible = passesFilter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var lockButtons = _timing.CurTime < _buttonUnlockTime;
|
// Update timers
|
||||||
|
if (ControlsContainer.Visible)
|
||||||
// Make / update required children
|
|
||||||
foreach (var child in ContactsList.Children)
|
|
||||||
{
|
{
|
||||||
if (child is not HolopadContactButton contactButton)
|
var cooldown = _holopadSystem.GetHolopadBroadcastCoolDown((_owner.Value, holopad));
|
||||||
continue;
|
var cooldownString = $"{cooldown.Minutes:00}:{cooldown.Seconds:00}";
|
||||||
|
|
||||||
var passesFilter = string.IsNullOrEmpty(SearchLineEdit.Text) ||
|
StartBroadcastButton.Text = broadcastOnCooldown
|
||||||
contactButton.Text?.Contains(SearchLineEdit.Text, StringComparison.CurrentCultureIgnoreCase) == true;
|
? Loc.GetString("holopad-window-emergency-broadcast-with-countdown", ("countdown", cooldownString))
|
||||||
|
: Loc.GetString("holopad-window-emergency-broadcast");
|
||||||
contactButton.Visible = passesFilter;
|
|
||||||
contactButton.Disabled = (_currentState != TelephoneState.Idle || lockButtons);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update control text
|
if (ControlsLockOutContainer.Visible)
|
||||||
var cooldown = _holopadSystem.GetHolopadBroadcastCoolDown((_owner.Value, holopad));
|
{
|
||||||
var cooldownString = $"{cooldown.Minutes:00}:{cooldown.Seconds:00}";
|
var lockout = _holopadSystem.GetHolopadControlLockedPeriod((_owner.Value, holopad));
|
||||||
|
var lockoutString = $"{lockout.Minutes:00}:{lockout.Seconds:00}";
|
||||||
|
|
||||||
StartBroadcastButton.Text = _holopadSystem.IsHolopadBroadcastOnCoolDown((_owner.Value, holopad)) ?
|
LockOutCountDownText.Text = Loc.GetString("holopad-window-controls-unlock-countdown", ("countdown", lockoutString));
|
||||||
Loc.GetString("holopad-window-emergency-broadcast-with-countdown", ("countdown", cooldownString)) :
|
}
|
||||||
Loc.GetString("holopad-window-emergency-broadcast");
|
|
||||||
|
|
||||||
var lockout = _holopadSystem.GetHolopadControlLockedPeriod((_owner.Value, holopad));
|
// Update call status text
|
||||||
var lockoutString = $"{lockout.Minutes:00}:{lockout.Seconds:00}";
|
switch (telephone.CurrentState)
|
||||||
|
|
||||||
LockOutCountDownText.Text = Loc.GetString("holopad-window-controls-unlock-countdown", ("countdown", lockoutString));
|
|
||||||
|
|
||||||
switch (_currentState)
|
|
||||||
{
|
{
|
||||||
case TelephoneState.Idle:
|
case TelephoneState.Idle:
|
||||||
CallStatusText.Text = Loc.GetString("holopad-window-no-calls-in-progress"); break;
|
CallStatusText.Text = Loc.GetString("holopad-window-no-calls-in-progress"); break;
|
||||||
@@ -277,7 +286,7 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
CallStatusText.Text = Loc.GetString("holopad-window-call-in-progress"); break;
|
CallStatusText.Text = Loc.GetString("holopad-window-call-in-progress"); break;
|
||||||
|
|
||||||
case TelephoneState.EndingCall:
|
case TelephoneState.EndingCall:
|
||||||
if (_previousState == TelephoneState.Calling || _previousState == TelephoneState.Idle)
|
if (telephone.PreviousState == TelephoneState.Calling || telephone.PreviousState == TelephoneState.Idle)
|
||||||
CallStatusText.Text = Loc.GetString("holopad-window-call-rejected");
|
CallStatusText.Text = Loc.GetString("holopad-window-call-rejected");
|
||||||
else
|
else
|
||||||
CallStatusText.Text = Loc.GetString("holopad-window-call-ending");
|
CallStatusText.Text = Loc.GetString("holopad-window-call-ending");
|
||||||
@@ -285,31 +294,29 @@ public sealed partial class HolopadWindow : FancyWindow
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update control disability
|
// Update control disability
|
||||||
AnswerCallButton.Disabled = (_currentState != TelephoneState.Ringing || lockButtons);
|
AnswerCallButton.Disabled = telephone.CurrentState is not TelephoneState.Ringing;
|
||||||
EndCallButton.Disabled = (_currentState == TelephoneState.Idle || _currentState == TelephoneState.EndingCall || lockButtons);
|
EndCallButton.Disabled = telephone.CurrentState is TelephoneState.Idle or TelephoneState.EndingCall;
|
||||||
StartBroadcastButton.Disabled = (_currentState != TelephoneState.Idle || !hasBroadcastAccess || lockButtons);
|
StartBroadcastButton.Disabled = telephone.CurrentState is not TelephoneState.Idle || broadcastOnCooldown;
|
||||||
RequestStationAiButton.Disabled = (_currentState != TelephoneState.Idle || lockButtons);
|
RequestStationAiButton.Disabled = telephone.CurrentState is not TelephoneState.Idle;
|
||||||
ActivateProjectorButton.Disabled = (_currentState != TelephoneState.Idle || lockButtons);
|
ActivateProjectorButton.Disabled = telephone.CurrentState is not TelephoneState.Idle;
|
||||||
|
|
||||||
// Update control visibility
|
// Update control visibility
|
||||||
FetchingAvailableHolopadsContainer.Visible = (ContactsList.ChildCount == 0);
|
FetchingAvailableHolopadsContainer.Visible = ContactsList.ChildCount == 0;
|
||||||
ActiveCallControlsContainer.Visible = (_currentState != TelephoneState.Idle || _currentUiKey == HolopadUiKey.AiRequestWindow);
|
ActiveCallControlsContainer.Visible = telephone.CurrentState is not TelephoneState.Idle || _currentUiKey is HolopadUiKey.AiRequestWindow;
|
||||||
CallPlacementControlsContainer.Visible = !ActiveCallControlsContainer.Visible;
|
CallPlacementControlsContainer.Visible = !ActiveCallControlsContainer.Visible;
|
||||||
CallerIdContainer.Visible = (_currentState == TelephoneState.Ringing);
|
CallerIdContainer.Visible = telephone.CurrentState is TelephoneState.Ringing;
|
||||||
AnswerCallButton.Visible = (_currentState == TelephoneState.Ringing);
|
AnswerCallButton.Visible = telephone.CurrentState is TelephoneState.Ringing;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void FrameUpdate(FrameEventArgs args)
|
protected override void FrameUpdate(FrameEventArgs args)
|
||||||
{
|
{
|
||||||
base.FrameUpdate(args);
|
base.FrameUpdate(args);
|
||||||
|
|
||||||
_updateTimer += args.DeltaSeconds;
|
if (_timing.CurTime < _nextUpdate)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_updateTimer >= UpdateTime)
|
_nextUpdate = _timing.CurTime + _updateDelay;
|
||||||
{
|
UpdateAppearance();
|
||||||
_updateTimer -= UpdateTime;
|
|
||||||
UpdateAppearance();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class HolopadContactButton : Button
|
private sealed class HolopadContactButton : Button
|
||||||
|
|||||||
@@ -1,52 +1,70 @@
|
|||||||
<Control xmlns="https://spacestation14.io"
|
<Control xmlns="https://spacestation14.io"
|
||||||
xmlns:pllax="clr-namespace:Content.Client.Parallax"
|
xmlns:pllax="clr-namespace:Content.Client.Parallax"
|
||||||
xmlns:clog="clr-namespace:Content.Client.Changelog">
|
xmlns:clog="clr-namespace:Content.Client.Changelog"
|
||||||
|
xmlns:system="clr-namespace:System;assembly=System.Runtime">
|
||||||
<pllax:ParallaxControl
|
<pllax:ParallaxControl
|
||||||
ParallaxPrototype="TrainStation"
|
Name="BackgroundParallax"
|
||||||
SpeedX="5"
|
SpeedX="5"
|
||||||
SpeedY="20"
|
SpeedY="20"
|
||||||
ScaleX="3"
|
ScaleX="3"
|
||||||
ScaleY="3"/>
|
ScaleY="3" />
|
||||||
<BoxContainer Name="VBox"
|
<BoxContainer Name="VBox"
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
HorizontalExpand="True"
|
HorizontalExpand="True"
|
||||||
VerticalExpand="True"
|
VerticalExpand="True">
|
||||||
StyleIdentifier="mainMenuVBox"
|
<PanelContainer StyleClasses="BackgroundPanel">
|
||||||
SeparationOverride="3">
|
<BoxContainer Orientation="Vertical"
|
||||||
<TextureRect Name="Logo"
|
HorizontalAlignment="Center"
|
||||||
Stretch="KeepCentered"/>
|
VerticalAlignment="Center"
|
||||||
<GridContainer Columns="2">
|
HorizontalExpand="True"
|
||||||
<Label Text="{Loc 'main-menu-username-label'}" />
|
VerticalExpand="True"
|
||||||
<LineEdit Name="UsernameBox"
|
StyleIdentifier="mainMenuVBox"
|
||||||
Access="Public"
|
Margin="4 16">
|
||||||
PlaceHolder="{Loc 'main-menu-username-text'}"
|
<TextureRect Name="Logo"
|
||||||
HorizontalExpand="True" />
|
Stretch="KeepCentered" />
|
||||||
<Label Text="{Loc 'main-menu-address-label'}"/>
|
<GridContainer Columns="2" Margin="0 4">
|
||||||
<LineEdit Name="AddressBox"
|
<Label Text="{Loc 'main-menu-username-label'}" />
|
||||||
Access="Public"
|
<LineEdit Name="UsernameBox"
|
||||||
Text="localhost"
|
Access="Public"
|
||||||
PlaceHolder="server address:port"
|
PlaceHolder="{Loc 'main-menu-username-text'}"
|
||||||
HorizontalExpand="True" />
|
HorizontalExpand="True" />
|
||||||
</GridContainer>
|
<Label Text="{Loc 'main-menu-address-label'}" />
|
||||||
<Button Name="DirectConnectButton"
|
<LineEdit Name="AddressBox"
|
||||||
Access="Public"
|
Access="Public"
|
||||||
Text="{Loc 'main-menu-direct-connect-button'}"
|
Text="localhost"
|
||||||
TextAlign="Center"
|
PlaceHolder="server address:port"
|
||||||
StyleIdentifier="mainMenu"/>
|
HorizontalExpand="True" />
|
||||||
<Button Name="OptionsButton"
|
</GridContainer>
|
||||||
Access="Public"
|
<Button Name="DirectConnectButton"
|
||||||
Text="{Loc 'main-menu-options-button'}"
|
Access="Public"
|
||||||
TextAlign="Center"
|
Text="{Loc 'main-menu-direct-connect-button'}"
|
||||||
StyleIdentifier="mainMenu"/>
|
TextAlign="Center"
|
||||||
<Button Name="QuitButton"
|
StyleClasses="OpenLeft"
|
||||||
Access="Public"
|
StyleIdentifier="mainMenu" />
|
||||||
Text="{Loc 'main-menu-quit-button'}"
|
<clog:ChangelogButton
|
||||||
TextAlign="Center"
|
Name="ChangelogButton"
|
||||||
StyleIdentifier="mainMenu"/>
|
StyleIdentifier="mainMenu"
|
||||||
<clog:ChangelogButton
|
StyleClasses="OpenBoth"
|
||||||
Name="ChangelogButton"
|
Access="Public" />
|
||||||
Access="Public"/>
|
<Button Name="OptionsButton"
|
||||||
|
Access="Public"
|
||||||
|
Text="{Loc 'main-menu-options-button'}"
|
||||||
|
TextAlign="Center"
|
||||||
|
StyleClasses="OpenBoth"
|
||||||
|
StyleIdentifier="mainMenu" />
|
||||||
|
<Button Name="QuitButton"
|
||||||
|
Access="Public"
|
||||||
|
Text="{Loc 'main-menu-quit-button'}"
|
||||||
|
TextAlign="Center"
|
||||||
|
StyleIdentifier="mainMenu">
|
||||||
|
<Control.StyleClasses>
|
||||||
|
<system:String>negative</system:String>
|
||||||
|
<system:String>OpenRight</system:String>
|
||||||
|
</Control.StyleClasses>
|
||||||
|
</Button>
|
||||||
|
</BoxContainer>
|
||||||
|
</PanelContainer>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</Control>
|
</Control>
|
||||||
|
|||||||
@@ -1,21 +1,43 @@
|
|||||||
using Robust.Client.AutoGenerated;
|
using Content.Client.Parallax.Data;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared;
|
using Robust.Shared;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Client.MainMenu.UI;
|
namespace Content.Client.MainMenu.UI;
|
||||||
|
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class MainMenuControl : Control
|
public sealed partial class MainMenuControl : Control
|
||||||
{
|
{
|
||||||
|
[Dependency] private IRobustRandom _random = default!;
|
||||||
|
|
||||||
public const string StyleIdentifierMainMenu = "mainMenu";
|
public const string StyleIdentifierMainMenu = "mainMenu";
|
||||||
public const string StyleIdentifierMainMenuVBox = "mainMenuVBox";
|
public const string StyleIdentifierMainMenuVBox = "mainMenuVBox";
|
||||||
|
|
||||||
|
private static readonly ProtoId<ParallaxPrototype>[] Parallaxes =
|
||||||
|
[
|
||||||
|
"Wizard",
|
||||||
|
"TrainStation",
|
||||||
|
"PlasmaStation",
|
||||||
|
"AmberStation",
|
||||||
|
"FastSpace",
|
||||||
|
"AspidParallax",
|
||||||
|
"OriginStation",
|
||||||
|
"Default",
|
||||||
|
"Sky",
|
||||||
|
"KettleStation",
|
||||||
|
"BagelStation",
|
||||||
|
"ExoStation",
|
||||||
|
];
|
||||||
|
|
||||||
public MainMenuControl(IResourceCache resCache, IConfigurationManager configMan)
|
public MainMenuControl(IResourceCache resCache, IConfigurationManager configMan)
|
||||||
{
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
|
LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);
|
||||||
@@ -25,6 +47,10 @@ public sealed partial class MainMenuControl : Control
|
|||||||
LayoutContainer.SetMarginTop(VBox, 30);
|
LayoutContainer.SetMarginTop(VBox, 30);
|
||||||
LayoutContainer.SetGrowHorizontal(VBox, LayoutContainer.GrowDirection.Begin);
|
LayoutContainer.SetGrowHorizontal(VBox, LayoutContainer.GrowDirection.Begin);
|
||||||
|
|
||||||
|
// I don't just enumerate them all as there's some hideous parallaxes, and it's easier
|
||||||
|
// to update an allowlist than to randomly get an ugly one to fix a blocklist.
|
||||||
|
BackgroundParallax.ParallaxPrototype = _random.Pick(Parallaxes).Id;
|
||||||
|
|
||||||
var logoTexture = resCache.GetResource<TextureResource>("/Textures/Logo/logo.png");
|
var logoTexture = resCache.GetResource<TextureResource>("/Textures/Logo/logo.png");
|
||||||
Logo.Texture = logoTexture;
|
Logo.Texture = logoTexture;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Movement.Components;
|
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Shared.Physics.Components;
|
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Client.Movement.Systems;
|
namespace Content.Client.Movement.Systems;
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
<ui1:EscapeMenu xmlns="https://spacestation14.io"
|
<ui1:EscapeMenu xmlns="https://spacestation14.io"
|
||||||
xmlns:changelog="clr-namespace:Content.Client.Changelog"
|
xmlns:changelog="clr-namespace:Content.Client.Changelog"
|
||||||
xmlns:ui="clr-namespace:Content.Client.Voting.UI"
|
xmlns:ui="clr-namespace:Content.Client.Voting.UI"
|
||||||
xmlns:ui1="clr-namespace:Content.Client.Options.UI"
|
xmlns:ui1="clr-namespace:Content.Client.Options.UI"
|
||||||
Title="{Loc 'ui-escape-title'}"
|
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||||
Resizable="False">
|
Title="{Loc 'ui-escape-title'}"
|
||||||
|
Resizable="False">
|
||||||
|
|
||||||
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
|
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
|
||||||
<ui:VoteCallMenuButton />
|
<ui:VoteCallMenuButton />
|
||||||
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
||||||
<Button Access="Public" Name="RulesButton" Text="{Loc 'ui-escape-rules'}" />
|
<Button Access="Public" Name="RulesButton" Text="{Loc 'ui-escape-rules'}" StyleClasses="OpenLeft" />
|
||||||
<Button Access="Public" Name="GuidebookButton" Text="{Loc 'ui-escape-guidebook'}" />
|
<Button Access="Public" Name="GuidebookButton" Text="{Loc 'ui-escape-guidebook'}" StyleClasses="OpenBoth" />
|
||||||
<Button Access="Public" Name="WikiButton" Text="{Loc 'ui-escape-wiki'}" />
|
<Button Access="Public" Name="WikiButton" Text="{Loc 'ui-escape-wiki'}" StyleClasses="OpenBoth" />
|
||||||
<changelog:ChangelogButton Access="Public" Name="ChangelogButton" />
|
<changelog:ChangelogButton Access="Public" Name="ChangelogButton" StyleClasses="OpenBoth"/>
|
||||||
<Button Access="Public" Name="FeedbackButton" Text="{Loc 'ui-escape-feedback'}"/>
|
<Button Access="Public" Name="FeedbackButton" Text="{Loc 'ui-escape-feedback'}" StyleClasses="OpenRight"/>
|
||||||
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
||||||
<Button Access="Public" Name="OptionsButton" Text="{Loc 'ui-escape-options'}" />
|
<Button Access="Public" Name="OptionsButton" Text="{Loc 'ui-escape-options'}" />
|
||||||
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
<PanelContainer StyleClasses="LowDivider" Margin="0 2.5 0 2.5" />
|
||||||
<Button Access="Public" Name="DisconnectButton" Text="{Loc 'ui-escape-disconnect'}" />
|
<Button Access="Public" Name="DisconnectButton" Text="{Loc 'ui-escape-disconnect'}">
|
||||||
<Button Access="Public" Name="QuitButton" Text="{Loc 'ui-escape-quit'}" StyleClasses="ButtonColorRed" />
|
<Control.StyleClasses>
|
||||||
|
<system:String>negative</system:String>
|
||||||
|
<system:String>OpenLeft</system:String>
|
||||||
|
</Control.StyleClasses>
|
||||||
|
</Button>
|
||||||
|
<Button Access="Public" Name="QuitButton" Text="{Loc 'ui-escape-quit'}">
|
||||||
|
<Control.StyleClasses>
|
||||||
|
<system:String>negative</system:String>
|
||||||
|
<system:String>OpenRight</system:String>
|
||||||
|
</Control.StyleClasses>
|
||||||
|
</Button>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</ui1:EscapeMenu>
|
</ui1:EscapeMenu>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<Label Text="{Loc 'ui-options-accessability-header-visuals'}"
|
<Label Text="{Loc 'ui-options-accessability-header-visuals'}"
|
||||||
StyleClasses="LabelKeyText"/>
|
StyleClasses="LabelKeyText"/>
|
||||||
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
|
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
|
||||||
|
<CheckBox Name="DisableAiStaticCheckBox" Text="{Loc 'ui-options-disable-ai-static'}" />
|
||||||
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
|
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
|
||||||
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
|
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
|
||||||
<ui:OptionSlider Name="ScreenShakeIntensitySlider" Title="{Loc 'ui-options-screen-shake-intensity'}" />
|
<ui:OptionSlider Name="ScreenShakeIntensitySlider" Title="{Loc 'ui-options-screen-shake-intensity'}" />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public sealed partial class AccessibilityTab : Control
|
|||||||
Control.AddOptionCheckBox(CCVars.ChatEnableColorName, EnableColorNameCheckBox);
|
Control.AddOptionCheckBox(CCVars.ChatEnableColorName, EnableColorNameCheckBox);
|
||||||
Control.AddOptionCheckBox(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox);
|
Control.AddOptionCheckBox(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox);
|
||||||
Control.AddOptionCheckBox(CCVars.ReducedMotion, ReducedMotionCheckBox);
|
Control.AddOptionCheckBox(CCVars.ReducedMotion, ReducedMotionCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.DisableAiStatic, DisableAiStaticCheckBox);
|
||||||
Control.AddOptionPercentSlider(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider);
|
Control.AddOptionPercentSlider(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider);
|
||||||
Control.AddOptionPercentSlider(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider);
|
Control.AddOptionPercentSlider(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider);
|
||||||
Control.AddOptionPercentSlider(CCVars.SpeechBubbleTextOpacity, SpeechBubbleTextOpacitySlider);
|
Control.AddOptionPercentSlider(CCVars.SpeechBubbleTextOpacity, SpeechBubbleTextOpacitySlider);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Graphics;
|
using Content.Client.Graphics;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Silicons.StationAi;
|
using Content.Shared.Silicons.StationAi;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
@@ -14,10 +16,12 @@ namespace Content.Client.Silicons.StationAi;
|
|||||||
public sealed partial class StationAiOverlay : Overlay
|
public sealed partial class StationAiOverlay : Overlay
|
||||||
{
|
{
|
||||||
private static readonly ProtoId<ShaderPrototype> CameraStaticShader = "CameraStatic";
|
private static readonly ProtoId<ShaderPrototype> CameraStaticShader = "CameraStatic";
|
||||||
|
private static readonly ProtoId<ShaderPrototype> CameraStaticAccessibleShader = "CameraStaticAccessible";
|
||||||
private static readonly ProtoId<ShaderPrototype> StencilMaskShader = "StencilMask";
|
private static readonly ProtoId<ShaderPrototype> StencilMaskShader = "StencilMask";
|
||||||
private static readonly ProtoId<ShaderPrototype> StencilDrawShader = "StencilDraw";
|
private static readonly ProtoId<ShaderPrototype> StencilDrawShader = "StencilDraw";
|
||||||
|
|
||||||
[Dependency] private IClyde _clyde = default!;
|
[Dependency] private IClyde _clyde = default!;
|
||||||
|
[Dependency] private IConfigurationManager _cfg = default!;
|
||||||
[Dependency] private IEntityManager _entManager = default!;
|
[Dependency] private IEntityManager _entManager = default!;
|
||||||
[Dependency] private IGameTiming _timing = default!;
|
[Dependency] private IGameTiming _timing = default!;
|
||||||
[Dependency] private IPlayerManager _player = default!;
|
[Dependency] private IPlayerManager _player = default!;
|
||||||
@@ -29,12 +33,20 @@ public sealed partial class StationAiOverlay : Overlay
|
|||||||
|
|
||||||
private readonly OverlayResourceCache<CachedResources> _resources = new();
|
private readonly OverlayResourceCache<CachedResources> _resources = new();
|
||||||
|
|
||||||
|
private ProtoId<ShaderPrototype> _activeShader = CameraStaticShader;
|
||||||
private float _updateRate = 1f / 30f;
|
private float _updateRate = 1f / 30f;
|
||||||
private float _accumulator;
|
private float _accumulator;
|
||||||
|
|
||||||
public StationAiOverlay()
|
public StationAiOverlay()
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
|
_cfg.OnValueChanged(CCVars.DisableAiStatic, OnAiStaticChanged, invokeImmediately: true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAiStaticChanged(bool toggle)
|
||||||
|
{
|
||||||
|
_activeShader = toggle ? CameraStaticAccessibleShader : CameraStaticShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Draw(in OverlayDrawArgs args)
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
@@ -97,7 +109,7 @@ public sealed partial class StationAiOverlay : Overlay
|
|||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
worldHandle.SetTransform(invMatrix);
|
worldHandle.SetTransform(invMatrix);
|
||||||
var shader = _proto.Index(CameraStaticShader).Instance();
|
var shader = _proto.Index(_activeShader).Instance();
|
||||||
worldHandle.UseShader(shader);
|
worldHandle.UseShader(shader);
|
||||||
worldHandle.DrawRect(worldBounds, Color.White);
|
worldHandle.DrawRect(worldBounds, Color.White);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -239,11 +239,15 @@ public abstract class RadialMenuButtonBase : BaseButton
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Function == EngineKeyFunctions.UIClick
|
if (args.Function.IsClickOrAltClick())
|
||||||
|| args.Function == ContentKeyFunctions.AltActivateItemInWorld)
|
|
||||||
{
|
|
||||||
base.KeyBindUp(args);
|
base.KeyBindUp(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Function.IsClickOrAltClick())
|
||||||
|
base.KeyBindDown(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,11 +289,15 @@ public sealed class RadialMenuContextualCentralTextureButton : TextureButton
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Function == EngineKeyFunctions.UIClick
|
if (args.Function.IsClickOrAltClick())
|
||||||
|| args.Function == ContentKeyFunctions.AltActivateItemInWorld)
|
|
||||||
{
|
|
||||||
base.KeyBindUp(args);
|
base.KeyBindUp(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Function.IsClickOrAltClick())
|
||||||
|
base.KeyBindDown(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,3 +692,12 @@ public class RadialMenuButtonWithSector : RadialMenuButton, IRadialMenuItemWithS
|
|||||||
return new Angle(angleSectorFrom).EqualsApprox(new Angle(angleSectorTo));
|
return new Angle(angleSectorFrom).EqualsApprox(new Angle(angleSectorTo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static file class RadialMenuButtonsHelpers
|
||||||
|
{
|
||||||
|
public static bool IsClickOrAltClick(this BoundKeyFunction function)
|
||||||
|
{
|
||||||
|
return function == EngineKeyFunctions.UIClick
|
||||||
|
|| function == ContentKeyFunctions.AltActivateItemInWorld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ public abstract partial class GameTest
|
|||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
_pairDestroyed = true;
|
_pairDestroyed = true;
|
||||||
|
Assert.Fail();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ public static class CompConstraintExtensions
|
|||||||
{
|
{
|
||||||
extension(Has)
|
extension(Has)
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Comp{T}"/>
|
||||||
public static ResolvableConstraintExpression Comp<T>(IIntegrationInstance instance)
|
public static ResolvableConstraintExpression Comp<T>(IIntegrationInstance instance)
|
||||||
where T : IComponent
|
where T : IComponent
|
||||||
{
|
{
|
||||||
return new ConstraintExpression().Comp<T>(instance);
|
return new ConstraintExpression().Comp<T>(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Comp(Type, IIntegrationInstance)"/>
|
||||||
public static ResolvableConstraintExpression Comp(Type t, IIntegrationInstance instance)
|
public static ResolvableConstraintExpression Comp(Type t, IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return new ConstraintExpression().Comp(t, instance);
|
return new ConstraintExpression().Comp(t, instance);
|
||||||
@@ -34,12 +36,52 @@ public static class CompConstraintExtensions
|
|||||||
|
|
||||||
extension(ConstraintExpression expr)
|
extension(ConstraintExpression expr)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint which will either test for the existence of a <typeparamref name="T"/>
|
||||||
|
/// on the entity being tested or apply any following constraint to that component.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The component Type to check for.</typeparam>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity has an ItemComponent on the server.
|
||||||
|
/// Assert.That(myEntity, Has.Comp<ItemComponent>(Server));
|
||||||
|
///
|
||||||
|
/// // Assert that the server-sided entity myEntity has an ItemComponent with a Size field equal to "Small"
|
||||||
|
/// Assert.That(myEntity,
|
||||||
|
/// Has
|
||||||
|
/// .Comp<ItemComponent>(Server)
|
||||||
|
/// .Property(nameof(ItemComponent.Size))
|
||||||
|
/// .EqualTo("Small")
|
||||||
|
/// );
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public ResolvableConstraintExpression Comp<T>(IIntegrationInstance instance)
|
public ResolvableConstraintExpression Comp<T>(IIntegrationInstance instance)
|
||||||
where T : IComponent
|
where T : IComponent
|
||||||
{
|
{
|
||||||
return expr.Append(new CompOperator(typeof(T), instance));
|
return expr.Append(new CompOperator(typeof(T), instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint which will either test for the existence of a component of the specified type
|
||||||
|
/// on the entity being tested or apply any following constraint to that component.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">The Type of the component to check for.</param>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity has an ItemComponent on the server.
|
||||||
|
/// Assert.That(myEntity, Has.Comp(typeof(ItemComponent), Server));
|
||||||
|
///
|
||||||
|
/// // Assert that the server-sided entity myEntity has an ItemComponent with a Size field equal to "Small"
|
||||||
|
/// Assert.That(myEntity,
|
||||||
|
/// Has
|
||||||
|
/// .Comp(typeof(ItemComponent), Server)
|
||||||
|
/// .Property(nameof(ItemComponent.Size))
|
||||||
|
/// .EqualTo("Small")
|
||||||
|
/// );
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public ResolvableConstraintExpression Comp(Type t, IIntegrationInstance instance)
|
public ResolvableConstraintExpression Comp(Type t, IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.Append(new CompOperator(t, instance));
|
return expr.Append(new CompOperator(t, instance));
|
||||||
|
|||||||
@@ -56,36 +56,43 @@ public static class LifeStageConstraintExtensions
|
|||||||
{
|
{
|
||||||
extension(Is)
|
extension(Is)
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).LifeStage"/>
|
||||||
public static LifeStageConstraint LifeStage(EntityLifeStage stage, IIntegrationInstance instance)
|
public static LifeStageConstraint LifeStage(EntityLifeStage stage, IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return new LifeStageConstraint(stage, instance);
|
return new LifeStageConstraint(stage, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).PreInit"/>
|
||||||
public static LifeStageConstraint PreInit(IIntegrationInstance instance)
|
public static LifeStageConstraint PreInit(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.PreInit, instance);
|
return Is.LifeStage(EntityLifeStage.PreInit, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Initializing"/>
|
||||||
public static LifeStageConstraint Initializing(IIntegrationInstance instance)
|
public static LifeStageConstraint Initializing(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.Initializing, instance);
|
return Is.LifeStage(EntityLifeStage.Initializing, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Initialized"/>
|
||||||
public static LifeStageConstraint Initialized(IIntegrationInstance instance)
|
public static LifeStageConstraint Initialized(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.Initialized, instance);
|
return Is.LifeStage(EntityLifeStage.Initialized, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).MapInitialized"/>
|
||||||
public static LifeStageConstraint MapInitialized(IIntegrationInstance instance)
|
public static LifeStageConstraint MapInitialized(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.MapInitialized, instance);
|
return Is.LifeStage(EntityLifeStage.MapInitialized, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Terminating"/>
|
||||||
public static LifeStageConstraint Terminating(IIntegrationInstance instance)
|
public static LifeStageConstraint Terminating(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.Terminating, instance);
|
return Is.LifeStage(EntityLifeStage.Terminating, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="extension(ConstraintExpression).Deleted"/>
|
||||||
public static LifeStageConstraint Deleted(IIntegrationInstance instance)
|
public static LifeStageConstraint Deleted(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return Is.LifeStage(EntityLifeStage.Deleted, instance);
|
return Is.LifeStage(EntityLifeStage.Deleted, instance);
|
||||||
@@ -94,6 +101,17 @@ public static class LifeStageConstraintExtensions
|
|||||||
|
|
||||||
extension(ConstraintExpression expr)
|
extension(ConstraintExpression expr)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the given lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stage">The <see cref="EntityLifeStage"/> to check for.</param>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is MapInitialized.
|
||||||
|
/// Assert.That(myEntity, Is.LifeStage(EntityLifeStage.MapInitialized, Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint LifeStage(EntityLifeStage stage, IIntegrationInstance instance)
|
public LifeStageConstraint LifeStage(EntityLifeStage stage, IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
var c = new LifeStageConstraint(stage, instance);
|
var c = new LifeStageConstraint(stage, instance);
|
||||||
@@ -103,31 +121,91 @@ public static class LifeStageConstraintExtensions
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the PreInit lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity has not yet been initialized.
|
||||||
|
/// Assert.That(myEntity, Is.PreInit(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint PreInit(IIntegrationInstance instance)
|
public LifeStageConstraint PreInit(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.PreInit, instance);
|
return expr.LifeStage(EntityLifeStage.PreInit, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the Intializing lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is Initializing.
|
||||||
|
/// Assert.That(myEntity, Is.Initializing(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint Initializing(IIntegrationInstance instance)
|
public LifeStageConstraint Initializing(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.Initializing, instance);
|
return expr.LifeStage(EntityLifeStage.Initializing, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the Initialized lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is Initialized.
|
||||||
|
/// Assert.That(myEntity, Is.Initialized(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint Initialized(IIntegrationInstance instance)
|
public LifeStageConstraint Initialized(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.Initialized, instance);
|
return expr.LifeStage(EntityLifeStage.Initialized, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the MapInitialized lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is MapInitialized.
|
||||||
|
/// Assert.That(myEntity, Is.MapInitialized(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint MapInitialized(IIntegrationInstance instance)
|
public LifeStageConstraint MapInitialized(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.MapInitialized, instance);
|
return expr.LifeStage(EntityLifeStage.MapInitialized, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the Terminating lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is Terminating.
|
||||||
|
/// Assert.That(myEntity, Is.Terminating(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint Terminating(IIntegrationInstance instance)
|
public LifeStageConstraint Terminating(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.Terminating, instance);
|
return expr.LifeStage(EntityLifeStage.Terminating, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new constraint that checks if the entity is in the Deleted lifestage.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The <see cref="IIntegrationInstance"/> (i.e. Server or Client) on which to perform the test.</param>
|
||||||
|
/// <example>
|
||||||
|
/// <code>
|
||||||
|
/// // Assert that the server-sided entity myEntity is Deleted.
|
||||||
|
/// Assert.That(myEntity, Is.Deleted(Server));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
public LifeStageConstraint Deleted(IIntegrationInstance instance)
|
public LifeStageConstraint Deleted(IIntegrationInstance instance)
|
||||||
{
|
{
|
||||||
return expr.LifeStage(EntityLifeStage.Deleted, instance);
|
return expr.LifeStage(EntityLifeStage.Deleted, instance);
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.IntegrationTests.Fixtures;
|
using Content.IntegrationTests.Fixtures;
|
||||||
|
using Content.IntegrationTests.Fixtures.Attributes;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Database;
|
using Content.Server.Database;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Shared.Administration.Logs;
|
using Content.Shared.Administration.Logs;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Tests.Administration.Logs;
|
namespace Content.IntegrationTests.Tests.Administration.Logs;
|
||||||
|
|
||||||
@@ -23,29 +23,28 @@ public sealed class AddTests : GameTest
|
|||||||
Connected = true
|
Connected = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[SidedDependency(Side.Server)] private readonly IAdminLogManager _sAdminLogManager = null!;
|
||||||
|
[SidedDependency(Side.Server)] private readonly IServerDbManager _sDbManager = null!;
|
||||||
|
[SidedDependency(Side.Server)] private readonly GameTicker _sGameTicker = null!;
|
||||||
|
[SidedDependency(Side.Server)] private readonly IPlayerManager _sPlayerManager = null!;
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task AddAndGetSingleLog()
|
public async Task AddAndGetSingleLog()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
var sEntities = server.ResolveDependency<IEntityManager>();
|
|
||||||
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
|
|
||||||
var guid = Guid.NewGuid();
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
await pair.CreateTestMap();
|
await Pair.CreateTestMap();
|
||||||
var coordinates = pair.TestMap!.GridCoords;
|
var coordinates = Pair.TestMap!.GridCoords;
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var entity = sEntities.SpawnEntity(null, coordinates);
|
var entity = SSpawnAtPosition(null, coordinates);
|
||||||
|
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{entity:Entity} test log: {guid}");
|
_sAdminLogManager.Add(LogType.Unknown, $"{entity:Entity} test log: {guid}");
|
||||||
});
|
});
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = sAdminLogSystem.CurrentRoundJson(new LogFilter
|
var logs = _sAdminLogManager.CurrentRoundJson(new LogFilter
|
||||||
{
|
{
|
||||||
Search = guid.ToString()
|
Search = guid.ToString()
|
||||||
});
|
});
|
||||||
@@ -69,32 +68,22 @@ public sealed class AddTests : GameTest
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task AddAndGetUnformattedLog()
|
public async Task AddAndGetUnformattedLog()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sDatabase = server.ResolveDependency<IServerDbManager>();
|
|
||||||
var sEntities = server.ResolveDependency<IEntityManager>();
|
|
||||||
var sSystems = server.ResolveDependency<IEntitySystemManager>();
|
|
||||||
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
var sGamerTicker = sSystems.GetEntitySystem<GameTicker>();
|
|
||||||
|
|
||||||
var guid = Guid.NewGuid();
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
var testMap = await pair.CreateTestMap();
|
var testMap = await Pair.CreateTestMap();
|
||||||
var coordinates = testMap.GridCoords;
|
var coordinates = testMap.GridCoords;
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var entity = sEntities.SpawnEntity(null, coordinates);
|
var entity = SSpawnAtPosition(null, coordinates);
|
||||||
|
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{entity} test log: {guid}");
|
_sAdminLogManager.Add(LogType.Unknown, $"{entity} test log: {guid}");
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedAdminLog log = default;
|
SharedAdminLog log = default;
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
|
var logs = await _sAdminLogManager.CurrentRoundLogs(new LogFilter
|
||||||
{
|
{
|
||||||
Search = guid.ToString()
|
Search = guid.ToString()
|
||||||
});
|
});
|
||||||
@@ -110,12 +99,12 @@ public sealed class AddTests : GameTest
|
|||||||
|
|
||||||
var filter = new LogFilter
|
var filter = new LogFilter
|
||||||
{
|
{
|
||||||
Round = sGamerTicker.RoundId,
|
Round = _sGameTicker.RoundId,
|
||||||
Search = log.Message,
|
Search = log.Message,
|
||||||
Types = new HashSet<LogType> { log.Type },
|
Types = new HashSet<LogType> { log.Type },
|
||||||
};
|
};
|
||||||
|
|
||||||
await foreach (var json in sDatabase.GetAdminLogsJson(filter))
|
await foreach (var json in _sDbManager.GetAdminLogsJson(filter))
|
||||||
{
|
{
|
||||||
var root = json.RootElement;
|
var root = json.RootElement;
|
||||||
|
|
||||||
@@ -133,27 +122,21 @@ public sealed class AddTests : GameTest
|
|||||||
[TestCase(500)]
|
[TestCase(500)]
|
||||||
public async Task BulkAddLogs(int amount)
|
public async Task BulkAddLogs(int amount)
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var testMap = await Pair.CreateTestMap();
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sEntities = server.ResolveDependency<IEntityManager>();
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
|
|
||||||
var testMap = await pair.CreateTestMap();
|
|
||||||
var coordinates = testMap.GridCoords;
|
var coordinates = testMap.GridCoords;
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var entity = sEntities.SpawnEntity(null, coordinates);
|
var entity = SSpawnAtPosition(null, coordinates);
|
||||||
|
|
||||||
for (var i = 0; i < amount; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{entity:Entity} test log.");
|
_sAdminLogManager.Add(LogType.Unknown, $"{entity:Entity} test log.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var messages = await sAdminLogSystem.CurrentRoundLogs();
|
var messages = await _sAdminLogManager.CurrentRoundLogs();
|
||||||
return messages.Count >= amount;
|
return messages.Count >= amount;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -161,28 +144,22 @@ public sealed class AddTests : GameTest
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task AddPlayerSessionLog()
|
public async Task AddPlayerSessionLog()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sPlayers = server.ResolveDependency<IPlayerManager>();
|
|
||||||
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
Guid playerGuid = default;
|
Guid playerGuid = default;
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var player = sPlayers.Sessions.First();
|
var player = _sPlayerManager.Sessions.First();
|
||||||
playerGuid = player.UserId;
|
playerGuid = player.UserId;
|
||||||
|
|
||||||
Assert.DoesNotThrow(() =>
|
Assert.DoesNotThrow(() =>
|
||||||
{
|
{
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{player:Player} test log.");
|
_sAdminLogManager.Add(LogType.Unknown, $"{player:Player} test log.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = await sAdminLogSystem.CurrentRoundLogs();
|
var logs = await _sAdminLogManager.CurrentRoundLogs();
|
||||||
if (logs.Count == 0)
|
if (logs.Count == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -196,24 +173,18 @@ public sealed class AddTests : GameTest
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task DuplicatePlayerDoesNotThrowTest()
|
public async Task DuplicatePlayerDoesNotThrowTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sPlayers = server.ResolveDependency<IPlayerManager>();
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
|
|
||||||
var guid = Guid.NewGuid();
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var player = sPlayers.Sessions.Single();
|
var player = _sPlayerManager.Sessions.Single();
|
||||||
|
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
|
_sAdminLogManager.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
|
||||||
});
|
});
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
|
var logs = await _sAdminLogManager.CurrentRoundLogs(new LogFilter
|
||||||
{
|
{
|
||||||
Search = guid.ToString()
|
Search = guid.ToString()
|
||||||
});
|
});
|
||||||
@@ -230,25 +201,18 @@ public sealed class AddTests : GameTest
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task DuplicatePlayerIdDoesNotThrowTest()
|
public async Task DuplicatePlayerIdDoesNotThrowTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sPlayers = server.ResolveDependency<IPlayerManager>();
|
|
||||||
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
|
|
||||||
var guid = Guid.NewGuid();
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
var player = sPlayers.Sessions.Single();
|
var player = _sPlayerManager.Sessions.Single();
|
||||||
|
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
|
_sAdminLogManager.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
|
||||||
});
|
});
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
|
var logs = await _sAdminLogManager.CurrentRoundLogs(new LogFilter
|
||||||
{
|
{
|
||||||
Search = guid.ToString()
|
Search = guid.ToString()
|
||||||
});
|
});
|
||||||
@@ -272,35 +236,30 @@ public sealed class PreRoundAddTests : GameTest
|
|||||||
AdminLogsEnabled = true
|
AdminLogsEnabled = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[SidedDependency(Side.Server)] private readonly IAdminLogManager _sAdminLogManager = null!;
|
||||||
|
[SidedDependency(Side.Server)] private readonly IServerDbManager _sDbManager = null!;
|
||||||
|
[SidedDependency(Side.Server)] private readonly GameTicker _sGameTicker = null!;
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task PreRoundAddAndGetSingle()
|
public async Task PreRoundAddAndGetSingle()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
|
||||||
var server = pair.Server;
|
|
||||||
|
|
||||||
var sDatabase = server.ResolveDependency<IServerDbManager>();
|
|
||||||
var sSystems = server.ResolveDependency<IEntitySystemManager>();
|
|
||||||
|
|
||||||
var sAdminLogSystem = server.ResolveDependency<IAdminLogManager>();
|
|
||||||
var sGamerTicker = sSystems.GetEntitySystem<GameTicker>();
|
|
||||||
|
|
||||||
var guid = Guid.NewGuid();
|
var guid = Guid.NewGuid();
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
sAdminLogSystem.Add(LogType.Unknown, $"test log: {guid}");
|
_sAdminLogManager.Add(LogType.Unknown, $"test log: {guid}");
|
||||||
});
|
});
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
await Server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
sGamerTicker.StartRound(true);
|
_sGameTicker.StartRound(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedAdminLog log = default;
|
SharedAdminLog log = default;
|
||||||
|
|
||||||
await PoolManager.WaitUntil(server, async () =>
|
await PoolManager.WaitUntil(Server, async () =>
|
||||||
{
|
{
|
||||||
var logs = await sAdminLogSystem.CurrentRoundLogs(new LogFilter
|
var logs = await _sAdminLogManager.CurrentRoundLogs(new LogFilter
|
||||||
{
|
{
|
||||||
Search = guid.ToString()
|
Search = guid.ToString()
|
||||||
});
|
});
|
||||||
@@ -316,12 +275,12 @@ public sealed class PreRoundAddTests : GameTest
|
|||||||
|
|
||||||
var filter = new LogFilter
|
var filter = new LogFilter
|
||||||
{
|
{
|
||||||
Round = sGamerTicker.RoundId,
|
Round = _sGameTicker.RoundId,
|
||||||
Search = log.Message,
|
Search = log.Message,
|
||||||
Types = new HashSet<LogType> { log.Type },
|
Types = new HashSet<LogType> { log.Type },
|
||||||
};
|
};
|
||||||
|
|
||||||
await foreach (var json in sDatabase.GetAdminLogsJson(filter))
|
await foreach (var json in _sDbManager.GetAdminLogsJson(filter))
|
||||||
{
|
{
|
||||||
var root = json.RootElement;
|
var root = json.RootElement;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
using Content.Server.Atmos.Piping.Trinary.Components;
|
||||||
|
using Content.Shared.Atmos.Components;
|
||||||
|
using Content.Shared.Atmos.Piping.Binary.Components;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.IntegrationTests.Tests.Atmos;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test for ensuring that atmospherics components deserialize and spawn with settings applied.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture]
|
||||||
|
public sealed class AtmosMapLoadSettingsTest : AtmosTest
|
||||||
|
{
|
||||||
|
// These values correspond to settings in the test map.
|
||||||
|
private const float PumpSetting = 180f;
|
||||||
|
private const float MixerMainSetting = 0.1f;
|
||||||
|
private const float MixerSideSetting = 0.9f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test map containing saved atmos components.
|
||||||
|
/// </summary>
|
||||||
|
protected override ResPath? TestMapPath => new("Maps/Test/Atmospherics/load_atmos_test_room.yml");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test to verify that the settings have been properly applied.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task TestMapLoading()
|
||||||
|
{
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
var volumePumpQuery = SEntMan.EntityQueryEnumerator<GasVolumePumpComponent>();
|
||||||
|
while (volumePumpQuery.MoveNext(out var volumePump))
|
||||||
|
{
|
||||||
|
using (Assert.EnterMultipleScope())
|
||||||
|
{
|
||||||
|
Assert.That(volumePump.Enabled, Is.True, "Volume pump did not load enabled!");
|
||||||
|
Assert.That(
|
||||||
|
volumePump.TransferRate,
|
||||||
|
Is.EqualTo(PumpSetting),
|
||||||
|
"Volume pump did not load correct setting!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pressurePumpQuery = SEntMan.EntityQueryEnumerator<GasPressurePumpComponent>();
|
||||||
|
while (pressurePumpQuery.MoveNext(out var pressurePump))
|
||||||
|
{
|
||||||
|
using (Assert.EnterMultipleScope())
|
||||||
|
{
|
||||||
|
Assert.That(pressurePump.Enabled, Is.True, "Pressure pump did not load enabled!");
|
||||||
|
Assert.That(
|
||||||
|
pressurePump.TargetPressure,
|
||||||
|
Is.EqualTo(PumpSetting),
|
||||||
|
"Pressure pump did not load correct setting!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mixerQuery = SEntMan.EntityQueryEnumerator<GasMixerComponent>();
|
||||||
|
while (mixerQuery.MoveNext(out var mixer))
|
||||||
|
{
|
||||||
|
using (Assert.EnterMultipleScope())
|
||||||
|
{
|
||||||
|
Assert.That(mixer.Enabled, Is.True, "Mixer did not load enabled!");
|
||||||
|
Assert.That(
|
||||||
|
mixer.TargetPressure,
|
||||||
|
Is.EqualTo(PumpSetting),
|
||||||
|
"Mixer pump did not load correct setting!"
|
||||||
|
);
|
||||||
|
Assert.That(
|
||||||
|
mixer.InletOneConcentration,
|
||||||
|
Is.EqualTo(MixerMainSetting),
|
||||||
|
"Mixer split did not load correct setting!"
|
||||||
|
);
|
||||||
|
Assert.That(
|
||||||
|
mixer.InletTwoConcentration,
|
||||||
|
Is.EqualTo(MixerSideSetting),
|
||||||
|
"Mixer split did not load correct setting!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,9 @@ public sealed class SharedGasSpecificHeatsTest
|
|||||||
|
|
||||||
_sAtmos = _sEntMan.System<Content.Server.Atmos.EntitySystems.AtmosphereSystem>();
|
_sAtmos = _sEntMan.System<Content.Server.Atmos.EntitySystems.AtmosphereSystem>();
|
||||||
_cAtmos = _cEntMan.System<AtmosphereSystem>();
|
_cAtmos = _cEntMan.System<AtmosphereSystem>();
|
||||||
|
|
||||||
|
// ensure that client and server atmos are fully inited otherwise arrays might not agree
|
||||||
|
await _pair.ReallyBeIdle(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TearDown]
|
[TearDown]
|
||||||
|
|||||||
@@ -0,0 +1,495 @@
|
|||||||
|
using Content.IntegrationTests.Tests.Interaction;
|
||||||
|
using Content.Shared.Hands.EntitySystems;
|
||||||
|
using Content.Shared.Inventory.VirtualItem;
|
||||||
|
using Content.Shared.Item;
|
||||||
|
using Content.Shared.Wieldable;
|
||||||
|
using Content.Shared.Wieldable.Components;
|
||||||
|
|
||||||
|
namespace Content.IntegrationTests.Tests.Hands;
|
||||||
|
|
||||||
|
[TestOf(typeof(MultiHandedItemComponent))]
|
||||||
|
[TestOf(typeof(WieldableComponent))]
|
||||||
|
public abstract class BaseMultiHandedItemTest : InteractionTest
|
||||||
|
{
|
||||||
|
protected SharedHandsSystem CHands = default!;
|
||||||
|
protected SharedHandsSystem SHands = default!;
|
||||||
|
protected SharedWieldableSystem SWieldable = default!;
|
||||||
|
|
||||||
|
protected const string Dummy1 = "DummyOneHanded";
|
||||||
|
protected const string Dummy2 = "DummyTwoHanded";
|
||||||
|
protected const string Dummy3 = "DummyThreeHanded";
|
||||||
|
protected const string Dummy4 = "DummyFourHanded";
|
||||||
|
protected const string Crowbar1 = "CrowbarOneHanded";
|
||||||
|
protected const string Crowbar2 = "CrowbarTwoHanded";
|
||||||
|
protected const string Crowbar3 = "CrowbarThreeHanded";
|
||||||
|
protected const string CrowbarWield1 = "CrowbarWieldableOneHanded";
|
||||||
|
protected const string CrowbarWield2 = "CrowbarWieldableTwoHanded";
|
||||||
|
protected const string CrowbarWield3 = "CrowbarWieldableThreeHanded";
|
||||||
|
|
||||||
|
[TestPrototypes]
|
||||||
|
private const string TestPrototypes = @$"
|
||||||
|
- type: entity
|
||||||
|
id: {Dummy1}
|
||||||
|
name: Urist McOneHand
|
||||||
|
components:
|
||||||
|
- type: DoAfter
|
||||||
|
- type: Hands
|
||||||
|
hands:
|
||||||
|
hand_right:
|
||||||
|
location: Right
|
||||||
|
sortedHands:
|
||||||
|
- hand_right
|
||||||
|
- type: ComplexInteraction
|
||||||
|
- type: MindContainer
|
||||||
|
- type: Puller
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Dummy1}
|
||||||
|
id: {Dummy2}
|
||||||
|
name: Urist McTwoHands
|
||||||
|
components:
|
||||||
|
- type: Hands
|
||||||
|
hands:
|
||||||
|
hand_right:
|
||||||
|
location: Right
|
||||||
|
hand_left:
|
||||||
|
location: Left
|
||||||
|
sortedHands:
|
||||||
|
- hand_right
|
||||||
|
- hand_left
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Dummy1}
|
||||||
|
id: {Dummy3}
|
||||||
|
name: Urist McThreeHands
|
||||||
|
components:
|
||||||
|
- type: Hands
|
||||||
|
hands:
|
||||||
|
hand_right:
|
||||||
|
location: Right
|
||||||
|
hand_middle:
|
||||||
|
location: Middle
|
||||||
|
hand_left:
|
||||||
|
location: Left
|
||||||
|
sortedHands:
|
||||||
|
- hand_right
|
||||||
|
- hand_middle
|
||||||
|
- hand_left
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Dummy1}
|
||||||
|
id: {Dummy4}
|
||||||
|
name: Urist McFourHands
|
||||||
|
components:
|
||||||
|
- type: Hands
|
||||||
|
hands:
|
||||||
|
hand_right1:
|
||||||
|
location: Right
|
||||||
|
hand_right2:
|
||||||
|
location: Right
|
||||||
|
hand_left1:
|
||||||
|
location: Left
|
||||||
|
hand_left2:
|
||||||
|
location: Left
|
||||||
|
sortedHands:
|
||||||
|
- hand_right1
|
||||||
|
- hand_right2
|
||||||
|
- hand_left1
|
||||||
|
- hand_left2
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: {Crowbar1}
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Tools/crowbar.rsi
|
||||||
|
state: icon
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Crowbar1}
|
||||||
|
id: {Crowbar2}
|
||||||
|
components:
|
||||||
|
- type: MultiHandedItem
|
||||||
|
handsNeeded: 2
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Crowbar1}
|
||||||
|
id: {Crowbar3}
|
||||||
|
components:
|
||||||
|
- type: MultiHandedItem
|
||||||
|
handsNeeded: 3
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Crowbar1}
|
||||||
|
id: {CrowbarWield1}
|
||||||
|
components:
|
||||||
|
- type: Wieldable
|
||||||
|
freeHandsRequired: 0
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Crowbar1}
|
||||||
|
id: {CrowbarWield2}
|
||||||
|
components:
|
||||||
|
- type: Wieldable
|
||||||
|
freeHandsRequired: 1
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: {Crowbar1}
|
||||||
|
id: {CrowbarWield3}
|
||||||
|
components:
|
||||||
|
- type: Wieldable
|
||||||
|
freeHandsRequired: 2
|
||||||
|
";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public override async Task Setup()
|
||||||
|
{
|
||||||
|
await base.Setup();
|
||||||
|
|
||||||
|
CHands = CEntMan.System<SharedHandsSystem>();
|
||||||
|
SHands = SEntMan.System<SharedHandsSystem>();
|
||||||
|
SWieldable = SEntMan.System<SharedWieldableSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task AssertHandItems(int hands, int freeHands, int items, int virtualItems)
|
||||||
|
{
|
||||||
|
await RunTicks(3);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var itemCount = 0;
|
||||||
|
var virtualItemCount = 0;
|
||||||
|
|
||||||
|
foreach (var item in SHands.EnumerateHeld(SPlayer))
|
||||||
|
{
|
||||||
|
itemCount++;
|
||||||
|
if (SEntMan.HasComponent<VirtualItemComponent>(item))
|
||||||
|
virtualItemCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.GetHandCount(SPlayer), Is.EqualTo(hands));
|
||||||
|
Assert.That(SHands.CountFreeHands(SPlayer), Is.EqualTo(freeHands));
|
||||||
|
Assert.That(itemCount, Is.EqualTo(items));
|
||||||
|
Assert.That(virtualItemCount, Is.EqualTo(virtualItems));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await Client.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
var itemCount = 0;
|
||||||
|
var virtualItemCount = 0;
|
||||||
|
|
||||||
|
foreach (var item in CHands.EnumerateHeld(CPlayer))
|
||||||
|
{
|
||||||
|
itemCount++;
|
||||||
|
if (CEntMan.HasComponent<VirtualItemComponent>(item))
|
||||||
|
virtualItemCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(CHands.GetHandCount(CPlayer), Is.EqualTo(hands));
|
||||||
|
Assert.That(CHands.CountFreeHands(CPlayer), Is.EqualTo(freeHands));
|
||||||
|
Assert.That(itemCount, Is.EqualTo(items));
|
||||||
|
Assert.That(virtualItemCount, Is.EqualTo(virtualItems));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need a separate fixture for each hand amount so that we can override the PlayerPrototype
|
||||||
|
public sealed class OneHandedItemTestFixture : BaseMultiHandedItemTest
|
||||||
|
{
|
||||||
|
protected override string PlayerPrototype => Dummy1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries out a few possible combinations for using multi-handed and wieldable items while having one hand.
|
||||||
|
/// This does not cover all possible scenarios, so if something breaks at some point then add it here as well.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task OneHandedItemTest()
|
||||||
|
{
|
||||||
|
// Start with one empty hand
|
||||||
|
await AssertHandItems(1, 1, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a one-handed item with one hand
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Pickup();
|
||||||
|
await SwapHands(); // does nothing but we try anyways
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
|
||||||
|
// We cannot pick up a second item
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
|
||||||
|
// We can drop our current item to free up the hand
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(1, 1, 0, 0);
|
||||||
|
|
||||||
|
// We cannot pick up a multi-handed item
|
||||||
|
await SpawnTarget(Crowbar2);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(1, 1, 0, 0);
|
||||||
|
|
||||||
|
// Spawn a wieldable Crowbar that does not need extra hands, pick it up, wield it
|
||||||
|
await SpawnTarget(CrowbarWield1);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
|
||||||
|
// Drop the wielded item
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(1, 1, 0, 0);
|
||||||
|
|
||||||
|
// Spawn a wieldable Crowbar that needs extra hands, pick it up, fail to wield it
|
||||||
|
await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(1, 0, 1, 0);
|
||||||
|
|
||||||
|
// Drop the unwielded item
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(1, 1, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TwoHandedItemTestFixture : BaseMultiHandedItemTest
|
||||||
|
{
|
||||||
|
protected override string PlayerPrototype => Dummy2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries out a few possible combinations for using multi-handed and wieldable items while having two hands.
|
||||||
|
/// This does not cover all possible scenarios, so if something breaks at some point then add it here as well.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task TwoHandedItemTest()
|
||||||
|
{
|
||||||
|
// Start with two empty hands
|
||||||
|
await AssertHandItems(2, 2, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a one-handed item with one hand
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Pickup();
|
||||||
|
await SwapHands();
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
|
||||||
|
// We can pick up another one-handed item with the second hand
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Pickup();
|
||||||
|
await SwapHands();
|
||||||
|
await AssertHandItems(2, 0, 2, 0);
|
||||||
|
|
||||||
|
// We cannot pick up a third item
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 0, 2, 0);
|
||||||
|
|
||||||
|
// Drop all items
|
||||||
|
await DropAll();
|
||||||
|
await AssertHandItems(2, 2, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a two-handed item with two hands
|
||||||
|
await SpawnTarget(Crowbar2);
|
||||||
|
await Pickup();
|
||||||
|
await SwapHands();
|
||||||
|
await AssertHandItems(2, 0, 2, 1);
|
||||||
|
|
||||||
|
// We cannot pick up a second item
|
||||||
|
await SpawnTarget(Crowbar1);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 0, 2, 1);
|
||||||
|
|
||||||
|
// Drop all items
|
||||||
|
await DropAll();
|
||||||
|
await AssertHandItems(2, 2, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a one-handed item with one hand
|
||||||
|
var handOneItem = await SpawnTarget(Crowbar1);
|
||||||
|
await Pickup();
|
||||||
|
await SwapHands();
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
|
||||||
|
// We cannot pick up a two-handed item with only one free hand
|
||||||
|
await SpawnTarget(Crowbar2);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
|
||||||
|
// We can pick up a one handed wieldable item
|
||||||
|
await SpawnTarget(CrowbarWield1);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(2, 0, 2, 0);
|
||||||
|
|
||||||
|
// We can wield the one-handed wieldable item without dropping other items
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
Assert.That(SHands.IsHolding(SPlayer, ToServer(handOneItem)), Is.True);
|
||||||
|
await AssertHandItems(2, 0, 2, 0);
|
||||||
|
|
||||||
|
// Drop it and pick up a two-handed wieldable item
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(2, 0, 2, 0);
|
||||||
|
|
||||||
|
// We can wield the two-handed wieldable item, but drop the item in the other hand while doing so
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
Assert.That(SHands.IsHolding(SPlayer, ToServer(handOneItem)), Is.False);
|
||||||
|
await AssertHandItems(2, 0, 2, 1);
|
||||||
|
|
||||||
|
// Drop the wielded item
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(2, 2, 0, 0);
|
||||||
|
|
||||||
|
// We cannot pick up a three-handed item
|
||||||
|
await SpawnTarget(Crowbar3);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 2, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a three-handed wieldable item
|
||||||
|
await SpawnTarget(CrowbarWield3);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SHands.TryPickupAnyHand(SPlayer, STarget.Value), Is.True);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
|
||||||
|
// But we cannot wield it
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.False);
|
||||||
|
});
|
||||||
|
await AssertHandItems(2, 1, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ThreeHandedItemTestFixture : BaseMultiHandedItemTest
|
||||||
|
{
|
||||||
|
protected override string PlayerPrototype => Dummy3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries out a few possible combinations for using multi-handed and wieldable items while having three hands.
|
||||||
|
/// This does not cover all possible scenarios, so if something breaks at some point then add it here as well.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task ThreeHandedItemTest()
|
||||||
|
{
|
||||||
|
// Start with three empty hands
|
||||||
|
await AssertHandItems(3, 3, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a three-handed item
|
||||||
|
await SpawnTarget(Crowbar3);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(3, 0, 3, 2);
|
||||||
|
|
||||||
|
// Drop it
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(3, 3, 0, 0);
|
||||||
|
|
||||||
|
// We can pick up a two-handed wieldable item
|
||||||
|
var handOneItem = await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(3, 2, 1, 0);
|
||||||
|
|
||||||
|
// And we can wield it
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
await AssertHandItems(3, 1, 2, 1);
|
||||||
|
|
||||||
|
// We can pick up a second two-handed wieldable item
|
||||||
|
await SwapHands();
|
||||||
|
await SwapHands();
|
||||||
|
await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(3, 0, 3, 1);
|
||||||
|
|
||||||
|
// And wielding it drops the first item
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
Assert.That(SHands.IsHolding(SPlayer, ToServer(handOneItem)), Is.False);
|
||||||
|
await AssertHandItems(3, 1, 2, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FourHandedItemTestFixture : BaseMultiHandedItemTest
|
||||||
|
{
|
||||||
|
protected override string PlayerPrototype => Dummy4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries out a few possible combinations for using multi-handed and wieldable items while having four hands.
|
||||||
|
/// This does not cover all possible scenarios, so if something breaks at some point then add it here as well.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task FourHandedItemTest()
|
||||||
|
{
|
||||||
|
// Start with four empty hands
|
||||||
|
await AssertHandItems(4, 4, 0, 0);
|
||||||
|
|
||||||
|
// We can wield two two-handed wieldable items at the same time
|
||||||
|
await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(4, 3, 1, 0);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
await AssertHandItems(4, 2, 2, 1);
|
||||||
|
await SwapHands();
|
||||||
|
await SwapHands();
|
||||||
|
await SpawnTarget(CrowbarWield2);
|
||||||
|
await Pickup();
|
||||||
|
await AssertHandItems(4, 1, 3, 1);
|
||||||
|
await Server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
Assert.That(SWieldable.TryWield(STarget.Value, SPlayer), Is.True);
|
||||||
|
});
|
||||||
|
await AssertHandItems(4, 0, 4, 2);
|
||||||
|
|
||||||
|
// Drop the first item
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(4, 2, 2, 1);
|
||||||
|
|
||||||
|
// Drop the second item
|
||||||
|
await SwapHands();
|
||||||
|
await SwapHands();
|
||||||
|
await Drop();
|
||||||
|
await AssertHandItems(4, 4, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using Content.IntegrationTests.Fixtures;
|
using Content.IntegrationTests.Fixtures;
|
||||||
|
using Content.IntegrationTests.Fixtures.Attributes;
|
||||||
using Content.IntegrationTests.Utility;
|
using Content.IntegrationTests.Utility;
|
||||||
using Content.Shared.Body;
|
using Content.Shared.Body;
|
||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
@@ -21,10 +23,10 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
private static readonly ProtoId<SpeciesPrototype> Vox = "Vox";
|
private static readonly ProtoId<SpeciesPrototype> Vox = "Vox";
|
||||||
private static string[] _species = GameDataScrounger.PrototypesOfKind<SpeciesPrototype>();
|
private static string[] _species = GameDataScrounger.PrototypesOfKind<SpeciesPrototype>();
|
||||||
|
|
||||||
private BodySystem _bodySystem;
|
[SidedDependency(Side.Server)] private BodySystem _bodySystem = default!;
|
||||||
private HumanoidProfileSystem _humanoidProfile;
|
[SidedDependency(Side.Server)] private HumanoidProfileSystem _humanoidProfile = default!;
|
||||||
private MarkingManager _markingManager;
|
[SidedDependency(Side.Server)] private MarkingManager _markingManager = default!;
|
||||||
private SharedVisualBodySystem _visualBody;
|
[SidedDependency(Side.Server)] private SharedVisualBodySystem _visualBody = default!;
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task EnsureValidLoading()
|
public async Task EnsureValidLoading()
|
||||||
@@ -36,17 +38,15 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
|
|
||||||
await server.WaitAssertion(() =>
|
await server.WaitAssertion(() =>
|
||||||
{
|
{
|
||||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
LoadDependencies(out var body, out var humanoidComponent);
|
||||||
var humanoidProfile = entityManager.System<HumanoidProfileSystem>();
|
|
||||||
var human = entityManager.Spawn(BaseSpecies);
|
_humanoidProfile.ApplyProfileTo(body,
|
||||||
humanoidProfile.ApplyProfileTo(human,
|
|
||||||
new HumanoidCharacterProfile()
|
new HumanoidCharacterProfile()
|
||||||
.WithSex(Sex.Female)
|
.WithSex(Sex.Female)
|
||||||
.WithAge(67)
|
.WithAge(67)
|
||||||
.WithGender(Gender.Neuter)
|
.WithGender(Gender.Neuter)
|
||||||
.WithSpecies(Vox));
|
.WithSpecies(Vox));
|
||||||
var humanoidComponent = entityManager.GetComponent<HumanoidProfileComponent>(human);
|
var voiceComponent = SEntMan.GetComponent<VocalComponent>(body);
|
||||||
var voiceComponent = entityManager.GetComponent<VocalComponent>(human);
|
|
||||||
|
|
||||||
Assert.That(humanoidComponent.Age, Is.EqualTo(67));
|
Assert.That(humanoidComponent.Age, Is.EqualTo(67));
|
||||||
Assert.That(humanoidComponent.Sex, Is.EqualTo(Sex.Female));
|
Assert.That(humanoidComponent.Sex, Is.EqualTo(Sex.Female));
|
||||||
@@ -71,6 +71,7 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
await server.WaitAssertion(() =>
|
await server.WaitAssertion(() =>
|
||||||
{
|
{
|
||||||
LoadDependencies(out var body, out var humanoidComponent);
|
LoadDependencies(out var body, out var humanoidComponent);
|
||||||
|
|
||||||
var profile = HumanoidCharacterProfile.Random();
|
var profile = HumanoidCharacterProfile.Random();
|
||||||
_humanoidProfile.ApplyProfileTo(body, profile);
|
_humanoidProfile.ApplyProfileTo(body, profile);
|
||||||
_visualBody.ApplyProfileTo(body, profile);
|
_visualBody.ApplyProfileTo(body, profile);
|
||||||
@@ -91,17 +92,17 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
{
|
{
|
||||||
LoadDependencies(out var body, out var humanoidComponent);
|
LoadDependencies(out var body, out var humanoidComponent);
|
||||||
|
|
||||||
var proto = Server.ProtoMan.Index<SpeciesPrototype>(species);
|
var proto = SProtoMan.Index<SpeciesPrototype>(species);
|
||||||
var profile = HumanoidCharacterProfile.RandomWithSpecies(species);
|
var profile = HumanoidCharacterProfile.RandomWithSpecies(species);
|
||||||
_humanoidProfile.ApplyProfileTo(body, profile);
|
_humanoidProfile.ApplyProfileTo(body, profile);
|
||||||
_visualBody.ApplyProfileTo(body, profile);
|
_visualBody.ApplyProfileTo(body, profile);
|
||||||
|
|
||||||
Assert.That(humanoidComponent.Age, Is.LessThanOrEqualTo(proto.MaxAge));
|
Assert.That(humanoidComponent.Age, Is.LessThanOrEqualTo(proto.MaxAge), $"Expected age is above the maximum age limit! Current: {humanoidComponent.Age} Max: {proto.MaxAge}");
|
||||||
Assert.That(humanoidComponent.Age, Is.GreaterThanOrEqualTo(proto.MinAge));
|
Assert.That(humanoidComponent.Age, Is.GreaterThanOrEqualTo(proto.MinAge), $"Expected age is below the minimum age limit! Current: {humanoidComponent.Age} Min: {proto.MinAge}");
|
||||||
Assert.That(proto.Sexes.Contains(humanoidComponent.Sex), Is.True);
|
Assert.That(proto.Sexes.Contains(humanoidComponent.Sex), Is.True, $"Character has sex not found in the species prototype! Current: {humanoidComponent.Sex}");
|
||||||
Assert.That(humanoidComponent.Species, Is.EqualTo(species));
|
Assert.That(humanoidComponent.Species, Is.EqualTo(species), $"Species does not match! Expected: {species} Current: {humanoidComponent.Species}");
|
||||||
var strategy = Server.ProtoMan.Index(proto.SkinColoration).Strategy;
|
var strategy = Server.ProtoMan.Index(proto.SkinColoration).Strategy;
|
||||||
Assert.That(strategy.VerifySkinColor(profile.Appearance.SkinColor), Is.True);
|
Assert.That(strategy.VerifySkinColor(profile.Appearance.SkinColor, out var reason), Is.True, $"Failed to verify the skin color from strategy {strategy}. Reason: {reason}");
|
||||||
|
|
||||||
AssertValidProfile((body, humanoidComponent), profile);
|
AssertValidProfile((body, humanoidComponent), profile);
|
||||||
});
|
});
|
||||||
@@ -109,29 +110,24 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
|
|
||||||
private void LoadDependencies(out EntityUid body, out HumanoidProfileComponent humanoidComponent)
|
private void LoadDependencies(out EntityUid body, out HumanoidProfileComponent humanoidComponent)
|
||||||
{
|
{
|
||||||
var entityManager = Server.ResolveDependency<IEntityManager>();
|
body = SEntMan.Spawn(BaseSpecies);
|
||||||
_humanoidProfile = entityManager.System<HumanoidProfileSystem>();
|
humanoidComponent = SEntMan.GetComponent<HumanoidProfileComponent>(body);
|
||||||
_markingManager = Server.ResolveDependency<MarkingManager>();
|
|
||||||
_visualBody = entityManager.System<SharedVisualBodySystem>();
|
|
||||||
_bodySystem = entityManager.System<BodySystem>();
|
|
||||||
body = entityManager.Spawn(BaseSpecies);
|
|
||||||
humanoidComponent = entityManager.GetComponent<HumanoidProfileComponent>(body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AssertValidProfile(Entity<HumanoidProfileComponent> body, HumanoidCharacterProfile profile)
|
private void AssertValidProfile(Entity<HumanoidProfileComponent> body, HumanoidCharacterProfile profile)
|
||||||
{
|
{
|
||||||
_bodySystem.TryGetOrgansWithComponent<VisualOrganComponent>(body.Owner, out var organs);
|
_bodySystem.TryGetOrgansWithComponent<VisualOrganComponent>(body.Owner, out var organs);
|
||||||
|
|
||||||
foreach (var (_, visualOrgan) in organs)
|
foreach (var (uid, visualOrgan) in organs)
|
||||||
{
|
{
|
||||||
Assert.That(visualOrgan.Profile.Sex, Is.EqualTo(profile.Sex));
|
Assert.That(visualOrgan.Profile.Sex, Is.EqualTo(profile.Sex), $"Organ {uid} has invalid sex appearance! Expected: {profile.Sex} Current: {visualOrgan.Profile.Sex}");
|
||||||
Assert.That(visualOrgan.Profile.EyeColor, Is.EqualTo(profile.Appearance.EyeColor));
|
Assert.That(visualOrgan.Profile.EyeColor, Is.EqualTo(profile.Appearance.EyeColor), $"Organ {uid} has invalid eye color! Expected: {profile.Appearance.EyeColor} Current: {visualOrgan.Profile.EyeColor}");
|
||||||
Assert.That(visualOrgan.Profile.SkinColor, Is.EqualTo(profile.Appearance.SkinColor));
|
Assert.That(visualOrgan.Profile.SkinColor, Is.EqualTo(profile.Appearance.SkinColor), $"Organ {uid} has invalid skin color! Expected: {profile.Appearance.SkinColor} Current: {visualOrgan.Profile.SkinColor}");
|
||||||
}
|
}
|
||||||
|
|
||||||
_bodySystem.TryGetOrgansWithComponent<VisualOrganMarkingsComponent>(body.Owner, out var markings);
|
_bodySystem.TryGetOrgansWithComponent<VisualOrganMarkingsComponent>(body.Owner, out var markings);
|
||||||
|
|
||||||
foreach (var (_, markingOrgan) in markings)
|
foreach (var (uid, markingOrgan) in markings)
|
||||||
{
|
{
|
||||||
// Needed to avoid access restrictions
|
// Needed to avoid access restrictions
|
||||||
var data = markingOrgan.MarkingData;
|
var data = markingOrgan.MarkingData;
|
||||||
@@ -143,9 +139,9 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
{
|
{
|
||||||
var markingProto = Server.ProtoMan.Index(marking.MarkingId);
|
var markingProto = Server.ProtoMan.Index(marking.MarkingId);
|
||||||
|
|
||||||
Assert.That(markingProto.Sprites.Count, Is.EqualTo(marking.MarkingColors.Count));
|
Assert.That(markingProto.Sprites.Count, Is.EqualTo(marking.MarkingColors.Count), $"Organ {uid} has invald amount of marking sprites! Expected: {marking.MarkingColors.Count} Current: {markingProto.Sprites.Count}");
|
||||||
Assert.That(_markingManager.CanBeApplied(data.Group, profile.Sex, markingProto), Is.True);
|
Assert.That(_markingManager.CanBeApplied(data.Group, profile.Sex, markingProto), Is.True, $"Marking {markingProto.ID} cannot be applied to group {data.Group.Id} with sex {profile.Sex}");
|
||||||
Assert.That(data.Layers.Contains(markingProto.BodyPart), Is.True);
|
Assert.That(data.Layers.Contains(markingProto.BodyPart), Is.True, $"Organ {uid} marking visual layers do not contain an entry for {markingProto.BodyPart}");
|
||||||
if (!markingProto.ForcedColoring && groupProto.Appearances.GetValueOrDefault(markingProto.BodyPart)?.MatchSkin != true)
|
if (!markingProto.ForcedColoring && groupProto.Appearances.GetValueOrDefault(markingProto.BodyPart)?.MatchSkin != true)
|
||||||
freeMarkings.Add(marking);
|
freeMarkings.Add(marking);
|
||||||
|
|
||||||
@@ -172,7 +168,7 @@ public sealed class HumanoidProfileTests : GameTest
|
|||||||
Is.EqualTo(MarkingColoring.GetMarkingLayerColors(markingProto, profile.Appearance.SkinColor, profile.Appearance.EyeColor, markingOrgan.AppliedMarkings)));
|
Is.EqualTo(MarkingColoring.GetMarkingLayerColors(markingProto, profile.Appearance.SkinColor, profile.Appearance.EyeColor, markingOrgan.AppliedMarkings)));
|
||||||
|
|
||||||
if (markingProto.SexRestriction != null)
|
if (markingProto.SexRestriction != null)
|
||||||
Assert.That(markingProto.SexRestriction, Is.EqualTo(profile.Sex));
|
Assert.That(markingProto.SexRestriction, Is.EqualTo(profile.Sex), $"Marking {markingProto.ID} has invalid sex restriction! Expected: {profile.Sex} Current: {markingProto.SexRestriction}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ public abstract partial class InteractionTest
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drops the currently held entity.
|
/// Drops the currently held entity.
|
||||||
|
/// Causes an error if no entity was held.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected async Task Drop()
|
protected async Task Drop()
|
||||||
{
|
{
|
||||||
@@ -277,6 +278,36 @@ public abstract partial class InteractionTest
|
|||||||
Assert.That(HandSys.GetActiveItem((ToServer(Player), Hands)), Is.Null);
|
Assert.That(HandSys.GetActiveItem((ToServer(Player), Hands)), Is.Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Drops all currently held entities.
|
||||||
|
/// Does nothing if no entity was held.
|
||||||
|
/// </summary>
|
||||||
|
protected async Task DropAll()
|
||||||
|
{
|
||||||
|
await Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
HandSys.DropAll((ToServer(Player), Hands));
|
||||||
|
});
|
||||||
|
|
||||||
|
await RunTicks(1);
|
||||||
|
|
||||||
|
// make sure that all hands are empty
|
||||||
|
Assert.That(HandSys.GetEmptyHandCount((ToServer(Player), Hands)), Is.EqualTo(HandSys.GetHandCount((ToServer(Player), Hands))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Swaps the current hand.
|
||||||
|
/// </summary>
|
||||||
|
protected async Task SwapHands(bool reverse = false)
|
||||||
|
{
|
||||||
|
await Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
HandSys.SwapHands((ToServer(Player), Hands), reverse: reverse);
|
||||||
|
});
|
||||||
|
|
||||||
|
await RunTicks(1);
|
||||||
|
}
|
||||||
|
|
||||||
#region Interact
|
#region Interact
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,55 +2,61 @@ using System.Linq;
|
|||||||
using Content.IntegrationTests.Fixtures;
|
using Content.IntegrationTests.Fixtures;
|
||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Tests.Utility
|
namespace Content.IntegrationTests.Tests.Utility
|
||||||
{
|
{
|
||||||
[TestFixture]
|
|
||||||
[TestOf(typeof(EntityWhitelist))]
|
[TestOf(typeof(EntityWhitelist))]
|
||||||
public sealed class EntityWhitelistTest : GameTest
|
public sealed class EntityWhitelistTest : GameTest
|
||||||
{
|
{
|
||||||
private const string InvalidComponent = "Sprite";
|
private const string InvalidComponent = "Sprite";
|
||||||
private const string ValidComponent = "Physics";
|
private const string ValidComponent = "Physics";
|
||||||
|
|
||||||
|
private const string WhitelistProtoId = "WhitelistDummy";
|
||||||
|
private const string ValidComponentProtoId = "ValidComponentDummy";
|
||||||
|
private const string WhitelistTestValidTagProtoId = "WhitelistTestValidTagDummy";
|
||||||
|
private const string InvalidComponentProtoId = "InvalidComponentDummy";
|
||||||
|
private const string WhitelistTestInvalidTagProtoId = "WhitelistTestInvalidTagDummy";
|
||||||
|
|
||||||
[TestPrototypes]
|
[TestPrototypes]
|
||||||
private const string Prototypes = $@"
|
private const string Prototypes = $@"
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: WhitelistTestValidTag
|
id: WhitelistTestValidTag
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: WhitelistTestInvalidTag
|
id: WhitelistTestInvalidTag
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: WhitelistDummy
|
id: {WhitelistProtoId}
|
||||||
components:
|
components:
|
||||||
- type: ItemSlots
|
- type: ItemSlots
|
||||||
slots:
|
slots:
|
||||||
slotName:
|
slotName:
|
||||||
whitelist:
|
whitelist:
|
||||||
prototypes:
|
|
||||||
- ValidPrototypeDummy
|
|
||||||
components:
|
components:
|
||||||
- {ValidComponent}
|
- {ValidComponent}
|
||||||
tags:
|
tags:
|
||||||
- WhitelistTestValidTag
|
- WhitelistTestValidTag
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: InvalidComponentDummy
|
id: {InvalidComponentProtoId}
|
||||||
components:
|
components:
|
||||||
- type: {InvalidComponent}
|
- type: {InvalidComponent}
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: WhitelistTestInvalidTagDummy
|
id: {WhitelistTestInvalidTagProtoId}
|
||||||
components:
|
components:
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- WhitelistTestInvalidTag
|
- WhitelistTestInvalidTag
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ValidComponentDummy
|
id: {ValidComponentProtoId}
|
||||||
components:
|
components:
|
||||||
- type: {ValidComponent}
|
- type: {ValidComponent}
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: WhitelistTestValidTagDummy
|
id: {WhitelistTestValidTagProtoId}
|
||||||
components:
|
components:
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
@@ -70,11 +76,17 @@ namespace Content.IntegrationTests.Tests.Utility
|
|||||||
|
|
||||||
await server.WaitAssertion(() =>
|
await server.WaitAssertion(() =>
|
||||||
{
|
{
|
||||||
var validComponent = sEntities.SpawnEntity("ValidComponentDummy", mapCoordinates);
|
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
|
||||||
var WhitelistTestValidTag = sEntities.SpawnEntity("WhitelistTestValidTagDummy", mapCoordinates);
|
|
||||||
|
|
||||||
var invalidComponent = sEntities.SpawnEntity("InvalidComponentDummy", mapCoordinates);
|
var validComponentProto = prototypeManager.Index(ValidComponentProtoId);
|
||||||
var WhitelistTestInvalidTag = sEntities.SpawnEntity("WhitelistTestInvalidTagDummy", mapCoordinates);
|
var whitelistTestValidTagProto = prototypeManager.Index(WhitelistTestValidTagProtoId);
|
||||||
|
var invalidComponentProto = prototypeManager.Index(InvalidComponentProtoId);
|
||||||
|
var whitelistTestInvalidTagProto = prototypeManager.Index(WhitelistTestInvalidTagProtoId);
|
||||||
|
|
||||||
|
var validComponentUid = sEntities.SpawnEntity(ValidComponentProtoId, mapCoordinates);
|
||||||
|
var whitelistTestValidTagUid = sEntities.SpawnEntity(WhitelistTestValidTagProtoId, mapCoordinates);
|
||||||
|
var invalidComponentUid = sEntities.SpawnEntity(InvalidComponentProtoId, mapCoordinates);
|
||||||
|
var whitelistTestInvalidTagUid = sEntities.SpawnEntity(WhitelistTestInvalidTagProtoId, mapCoordinates);
|
||||||
|
|
||||||
// Test instantiated on its own
|
// Test instantiated on its own
|
||||||
var whitelistInst = new EntityWhitelist
|
var whitelistInst = new EntityWhitelist
|
||||||
@@ -85,15 +97,25 @@ namespace Content.IntegrationTests.Tests.Utility
|
|||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(sys.IsValid(whitelistInst, validComponent), Is.True);
|
Assert.That(sys.IsValid(whitelistInst, validComponentUid), Is.True);
|
||||||
Assert.That(sys.IsValid(whitelistInst, WhitelistTestValidTag), Is.True);
|
Assert.That(sys.IsValid(whitelistInst, validComponentProto), Is.True);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, ValidComponentProtoId), Is.True);
|
||||||
|
|
||||||
Assert.That(sys.IsValid(whitelistInst, invalidComponent), Is.False);
|
Assert.That(sys.IsValid(whitelistInst, whitelistTestValidTagUid), Is.True);
|
||||||
Assert.That(sys.IsValid(whitelistInst, WhitelistTestInvalidTag), Is.False);
|
Assert.That(sys.IsValid(whitelistInst, whitelistTestValidTagProto), Is.True);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, WhitelistTestValidTagProtoId), Is.True);
|
||||||
|
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, invalidComponentUid), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, invalidComponentProto), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, InvalidComponentProtoId), Is.False);
|
||||||
|
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, whitelistTestInvalidTagUid), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, whitelistTestInvalidTagProto), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistInst, WhitelistTestInvalidTagProtoId), Is.False);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test from serialized
|
// Test from serialized
|
||||||
var dummy = sEntities.SpawnEntity("WhitelistDummy", mapCoordinates);
|
var dummy = sEntities.SpawnEntity(WhitelistProtoId, mapCoordinates);
|
||||||
var whitelistSer = sEntities.GetComponent<ItemSlotsComponent>(dummy).Slots.Values.First().Whitelist;
|
var whitelistSer = sEntities.GetComponent<ItemSlotsComponent>(dummy).Slots.Values.First().Whitelist;
|
||||||
Assert.That(whitelistSer, Is.Not.Null);
|
Assert.That(whitelistSer, Is.Not.Null);
|
||||||
|
|
||||||
@@ -105,11 +127,21 @@ namespace Content.IntegrationTests.Tests.Utility
|
|||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(sys.IsValid(whitelistSer, validComponent), Is.True);
|
Assert.That(sys.IsValid(whitelistSer, validComponentUid), Is.True);
|
||||||
Assert.That(sys.IsValid(whitelistSer, WhitelistTestValidTag), Is.True);
|
Assert.That(sys.IsValid(whitelistSer, validComponentProto), Is.True);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, ValidComponentProtoId), Is.True);
|
||||||
|
|
||||||
Assert.That(sys.IsValid(whitelistSer, invalidComponent), Is.False);
|
Assert.That(sys.IsValid(whitelistSer, whitelistTestValidTagUid), Is.True);
|
||||||
Assert.That(sys.IsValid(whitelistSer, WhitelistTestInvalidTag), Is.False);
|
Assert.That(sys.IsValid(whitelistSer, whitelistTestValidTagProto), Is.True);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, WhitelistTestValidTagProtoId), Is.True);
|
||||||
|
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, invalidComponentUid), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, invalidComponentProto), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, InvalidComponentProtoId), Is.False);
|
||||||
|
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, whitelistTestInvalidTagUid), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, whitelistTestInvalidTagProto), Is.False);
|
||||||
|
Assert.That(sys.IsValid(whitelistSer, WhitelistTestInvalidTagProtoId), Is.False);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.IntegrationTests.Fixtures;
|
using Content.IntegrationTests.Fixtures;
|
||||||
|
using Content.IntegrationTests.Fixtures.Attributes;
|
||||||
using Content.Shared.Xenoarchaeology.Artifact;
|
using Content.Shared.Xenoarchaeology.Artifact;
|
||||||
using Content.Shared.Xenoarchaeology.Artifact.Components;
|
using Content.Shared.Xenoarchaeology.Artifact.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -7,12 +8,21 @@ using Robust.Shared.GameObjects;
|
|||||||
namespace Content.IntegrationTests.Tests;
|
namespace Content.IntegrationTests.Tests;
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[TestOf(typeof(SharedXenoArtifactSystem))]
|
||||||
public sealed class XenoArtifactTest : GameTest
|
public sealed class XenoArtifactTest : GameTest
|
||||||
{
|
{
|
||||||
|
private const string TestArtifact = "TestArtifact";
|
||||||
|
private const string TestArtifactNode = "TestArtifactNode";
|
||||||
|
private const string TestGenArtifactFlat = "TestGenArtifactFlat";
|
||||||
|
private const string TestGenArtifactTall = "TestGenArtifactTall";
|
||||||
|
private const string TestGenArtifactFull = "TestGenArtifactFull";
|
||||||
|
|
||||||
|
[SidedDependency(Side.Server)] private SharedXenoArtifactSystem _sArtifactSystem = null!;
|
||||||
|
|
||||||
[TestPrototypes]
|
[TestPrototypes]
|
||||||
private const string Prototypes = @"
|
private const string Prototypes = $@"
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TestArtifact
|
id: {TestArtifact}
|
||||||
parent: BaseXenoArtifact
|
parent: BaseXenoArtifact
|
||||||
name: artifact
|
name: artifact
|
||||||
components:
|
components:
|
||||||
@@ -22,7 +32,7 @@ public sealed class XenoArtifactTest : GameTest
|
|||||||
tableId: XenoArtifactEffectsDefaultTable
|
tableId: XenoArtifactEffectsDefaultTable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TestGenArtifactFlat
|
id: {TestGenArtifactFlat}
|
||||||
parent: BaseXenoArtifact
|
parent: BaseXenoArtifact
|
||||||
name: artifact
|
name: artifact
|
||||||
components:
|
components:
|
||||||
@@ -41,7 +51,7 @@ public sealed class XenoArtifactTest : GameTest
|
|||||||
tableId: XenoArtifactEffectsDefaultTable
|
tableId: XenoArtifactEffectsDefaultTable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TestGenArtifactTall
|
id: {TestGenArtifactTall}
|
||||||
parent: BaseXenoArtifact
|
parent: BaseXenoArtifact
|
||||||
name: artifact
|
name: artifact
|
||||||
components:
|
components:
|
||||||
@@ -60,7 +70,7 @@ public sealed class XenoArtifactTest : GameTest
|
|||||||
tableId: XenoArtifactEffectsDefaultTable
|
tableId: XenoArtifactEffectsDefaultTable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TestGenArtifactFull
|
id: {TestGenArtifactFull}
|
||||||
name: artifact
|
name: artifact
|
||||||
components:
|
components:
|
||||||
- type: XenoArtifact
|
- type: XenoArtifact
|
||||||
@@ -78,7 +88,7 @@ public sealed class XenoArtifactTest : GameTest
|
|||||||
tableId: XenoArtifactEffectsDefaultTable
|
tableId: XenoArtifactEffectsDefaultTable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: TestArtifactNode
|
id: {TestArtifactNode}
|
||||||
name: artifact node
|
name: artifact node
|
||||||
components:
|
components:
|
||||||
- type: XenoArtifactNode
|
- type: XenoArtifactNode
|
||||||
@@ -89,314 +99,268 @@ public sealed class XenoArtifactTest : GameTest
|
|||||||
/// Checks that adding nodes and edges properly adds them into the adjacency matrix
|
/// Checks that adding nodes and edges properly adds them into the adjacency matrix
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
|
[Description("Checks that adding nodes and edges properly adds them into the adjacency matrix")]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactAddNodeTest()
|
public async Task XenoArtifactAddNodeTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifactUid = SSpawn(TestArtifact);
|
||||||
var server = pair.Server;
|
var artifactEnt = (artifactUid, comp: SComp<XenoArtifactComponent>(artifactUid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
// Create 3 nodes
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node1, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node2, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node3, false));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
Assert.That(_sArtifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(3));
|
||||||
{
|
|
||||||
var artifactUid = entManager.Spawn("TestArtifact");
|
|
||||||
var artifactEnt = (artifactUid, comp: entManager.GetComponent<XenoArtifactComponent>(artifactUid));
|
|
||||||
|
|
||||||
// Create 3 nodes
|
// Add connection from 1 -> 2 and 2-> 3
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3, false));
|
|
||||||
|
|
||||||
Assert.That(artifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(3));
|
// Assert that successors and direct successors are counted correctly for node 1.
|
||||||
|
Assert.That(_sArtifactSystem.GetDirectSuccessorNodes(artifactEnt, node1!.Value), Has.Count.EqualTo(1));
|
||||||
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node1!.Value), Has.Count.EqualTo(2));
|
||||||
|
// Assert that we didn't somehow get predecessors on node 1.
|
||||||
|
Assert.That(_sArtifactSystem.GetDirectPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);
|
||||||
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);
|
||||||
|
|
||||||
// Add connection from 1 -> 2 and 2-> 3
|
// Assert that successors and direct successors are counted correctly for node 2.
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
Assert.That(_sArtifactSystem.GetDirectSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
||||||
|
// Assert that predecessors and direct predecessors are counted correctly for node 2.
|
||||||
|
Assert.That(_sArtifactSystem.GetDirectPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
||||||
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
||||||
|
|
||||||
// Assert that successors and direct successors are counted correctly for node 1.
|
// Assert that successors and direct successors are counted correctly for node 3.
|
||||||
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node1!.Value).Count, Is.EqualTo(1));
|
Assert.That(_sArtifactSystem.GetDirectSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1!.Value).Count, Is.EqualTo(2));
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
|
||||||
// Assert that we didn't somehow get predecessors on node 1.
|
// Assert that predecessors and direct predecessors are counted correctly for node 3.
|
||||||
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);
|
Assert.That(_sArtifactSystem.GetDirectPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(1));
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(2));
|
||||||
|
|
||||||
// Assert that successors and direct successors are counted correctly for node 2.
|
|
||||||
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
|
||||||
// Assert that predecessors and direct predecessors are counted correctly for node 2.
|
|
||||||
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
|
|
||||||
|
|
||||||
// Assert that successors and direct successors are counted correctly for node 3.
|
|
||||||
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
|
|
||||||
// Assert that predecessors and direct predecessors are counted correctly for node 3.
|
|
||||||
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(1));
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(2));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks to make sure that removing nodes properly cleans up all connections.
|
/// Checks to make sure that removing nodes properly cleans up all connections.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
|
[Description("Checks to make sure that removing nodes properly cleans up all connections.")]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactRemoveNodeTest()
|
public async Task XenoArtifactRemoveNodeTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifactUid = SSpawn(TestArtifact);
|
||||||
var server = pair.Server;
|
var artifactEnt = (artifactUid, comp: SComp<XenoArtifactComponent>(artifactUid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
// Create 3 nodes
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node1, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node2, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node3, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node4, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node5, false));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
Assert.That(_sArtifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(5));
|
||||||
{
|
|
||||||
var artifactUid = entManager.Spawn("TestArtifact");
|
|
||||||
var artifactEnt = (artifactUid, comp: entManager.GetComponent<XenoArtifactComponent>(artifactUid));
|
|
||||||
|
|
||||||
// Create 3 nodes
|
// Add connection: 1 -> 2 -> 3 -> 4 -> 5
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node3!.Value, node4!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node4!.Value, node5!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node5, false));
|
|
||||||
|
|
||||||
Assert.That(artifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(5));
|
// Make sure we have a continuous connection between the two ends of the graph.
|
||||||
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Has.Count.EqualTo(4));
|
||||||
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node5.Value), Has.Count.EqualTo(4));
|
||||||
|
|
||||||
// Add connection: 1 -> 2 -> 3 -> 4 -> 5
|
// Remove the node and make sure it's no longer in the artifact.
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
Assert.That(_sArtifactSystem.RemoveNode(artifactEnt, node3!.Value, false));
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
Assert.That(_sArtifactSystem.TryGetIndex(artifactEnt, node3!.Value, out _), Is.False, "Node 3 still present in artifact.");
|
||||||
artifactSystem.AddEdge(artifactEnt, node3!.Value, node4!.Value, false);
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node4!.Value, node5!.Value, false);
|
|
||||||
|
|
||||||
// Make sure we have a continuous connection between the two ends of the graph.
|
// Check to make sure that we got rid of all the connections.
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Has.Count.EqualTo(4));
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Is.Empty);
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node5.Value), Has.Count.EqualTo(4));
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
||||||
|
|
||||||
// Remove the node and make sure it's no longer in the artifact.
|
|
||||||
Assert.That(artifactSystem.RemoveNode(artifactEnt, node3!.Value, false));
|
|
||||||
Assert.That(artifactSystem.TryGetIndex(artifactEnt, node3!.Value, out _), Is.False, "Node 3 still present in artifact.");
|
|
||||||
|
|
||||||
// Check to make sure that we got rid of all the connections.
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets up series of linked nodes and ensures that resizing the adjacency matrix doesn't disturb the connections
|
/// Sets up series of linked nodes and ensures that resizing the adjacency matrix doesn't disturb the connections
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
|
[Description("Sets up series of linked nodes and ensures that resizing the adjacency matrix doesn't disturb the connections")]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactResizeTest()
|
public async Task XenoArtifactResizeTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifactUid = SSpawn(TestArtifact);
|
||||||
var server = pair.Server;
|
var artifactEnt = (artifactUid, comp: SComp<XenoArtifactComponent>(artifactUid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
// Create 3 nodes
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node1, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node2, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node3, false));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
// Add connection: 1 -> 2 -> 3
|
||||||
{
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
||||||
var artifactUid = entManager.Spawn("TestArtifact");
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
||||||
var artifactEnt = (artifactUid, comp: entManager.GetComponent<XenoArtifactComponent>(artifactUid));
|
|
||||||
|
|
||||||
// Create 3 nodes
|
// Make sure our connection is set up
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1, false));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2, false));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3, false));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);
|
||||||
|
|
||||||
// Add connection: 1 -> 2 -> 3
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node1!.Value), Is.Zero);
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));
|
||||||
|
|
||||||
// Make sure our connection is set up
|
// Add a new node, resizing the original adjacency matrix and array.
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node4));
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);
|
|
||||||
|
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node1!.Value), Is.EqualTo(0));
|
// Check that our connections haven't changed.
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
|
||||||
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);
|
||||||
|
|
||||||
// Add a new node, resizing the original adjacency matrix and array.
|
// Has our array shifted any when we resized?
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4));
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node1!.Value), Is.Zero);
|
||||||
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
|
||||||
|
Assert.That(_sArtifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));
|
||||||
|
|
||||||
// Check that our connections haven't changed.
|
// Check that 4 didn't somehow end up with connections
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
|
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);
|
|
||||||
|
|
||||||
// Has our array shifted any when we resized?
|
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node1!.Value), Is.EqualTo(0));
|
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
|
|
||||||
Assert.That(artifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));
|
|
||||||
|
|
||||||
// Check that 4 didn't somehow end up with connections
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if removing a node and adding a new node into its place in the adjacency matrix doesn't accidentally retain extra data.
|
/// Checks if removing a node and adding a new node into its place in the adjacency matrix doesn't accidentally retain extra data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
|
[Description("Checks if removing a node and adding a new node into its place in the adjacency matrix doesn't accidentally retain extra data.")]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactReplaceTest()
|
public async Task XenoArtifactReplaceTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifactUid = SSpawn(TestArtifact);
|
||||||
var server = pair.Server;
|
var artifactEnt = (artifactUid, Comp: SComp<XenoArtifactComponent>(artifactUid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
// Create 3 nodes
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node1, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node2, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node3, false));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
// Add connection: 1 -> 2 -> 3
|
||||||
{
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
||||||
var artifactUid = entManager.Spawn("TestArtifact");
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
||||||
var artifactEnt = (artifactUid, comp: entManager.GetComponent<XenoArtifactComponent>(artifactUid));
|
|
||||||
|
|
||||||
// Create 3 nodes
|
// Make sure our connection is set up
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1, false));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2, false));
|
Assert.That(_sArtifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3, false));
|
|
||||||
|
|
||||||
// Add connection: 1 -> 2 -> 3
|
// Remove middle node, severing connections
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
_sArtifactSystem.RemoveNode(artifactEnt, node2!.Value, false);
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value, false);
|
|
||||||
|
|
||||||
// Make sure our connection is set up
|
// Make sure our connection are properly severed.
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
|
||||||
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);
|
||||||
|
|
||||||
// Remove middle node, severing connections
|
// Make sure our matrix is 3x3
|
||||||
artifactSystem.RemoveNode(artifactEnt, node2!.Value, false);
|
Assert.That(artifactEnt.Comp.NodeAdjacencyMatrixRows, Is.EqualTo(3));
|
||||||
|
Assert.That(artifactEnt.Comp.NodeAdjacencyMatrixColumns, Is.EqualTo(3));
|
||||||
|
|
||||||
// Make sure our connection are properly severed.
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node4, false));
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);
|
|
||||||
|
|
||||||
// Make sure our matrix is 3x3
|
// Make sure that adding in a new node didn't add a new slot but instead re-used the middle slot.
|
||||||
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixRows, Is.EqualTo(3));
|
Assert.That(artifactEnt.Comp.NodeAdjacencyMatrixRows, Is.EqualTo(3));
|
||||||
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixColumns, Is.EqualTo(3));
|
Assert.That(artifactEnt.Comp.NodeAdjacencyMatrixColumns, Is.EqualTo(3));
|
||||||
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4, false));
|
// Ensure that all connections are still severed
|
||||||
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
|
||||||
// Make sure that adding in a new node didn't add a new slot but instead re-used the middle slot.
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);
|
||||||
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixRows, Is.EqualTo(3));
|
Assert.That(_sArtifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
||||||
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixColumns, Is.EqualTo(3));
|
Assert.That(_sArtifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
||||||
|
|
||||||
// Ensure that all connections are still severed
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
|
||||||
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the active nodes are properly detected.
|
/// Checks if the active nodes are properly detected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
|
[Description("Checks if the active nodes are properly detected.")]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactBuildActiveNodesTest()
|
public async Task XenoArtifactBuildActiveNodesTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifactUid = SSpawn(TestArtifact);
|
||||||
var server = pair.Server;
|
Entity<XenoArtifactComponent> artifactEnt = (artifactUid, SComp<XenoArtifactComponent>(artifactUid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node1, false));
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node2, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node3, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node4, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node5, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node6, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node7, false));
|
||||||
|
Assert.That(_sArtifactSystem.AddNode(artifactEnt, TestArtifactNode, out var node8, false));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
// /----( 6 )
|
||||||
{
|
// /----[*3 ]-/----( 7 )----( 8 )
|
||||||
var artifactUid = entManager.Spawn("TestArtifact");
|
// /
|
||||||
Entity<XenoArtifactComponent> artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));
|
// / /----[*5 ]
|
||||||
|
// [ 1 ]--/----[ 2 ]--/----( 4 )
|
||||||
|
// Diagram of the example generation. Nodes in [brackets] are unlocked, nodes in (braces) are locked
|
||||||
|
// and nodes with an *asterisk are supposed to be active.
|
||||||
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
||||||
|
_sArtifactSystem.AddEdge(artifactEnt, node1!.Value, node3!.Value, false);
|
||||||
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node4!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2, false));
|
_sArtifactSystem.AddEdge(artifactEnt, node2!.Value, node5!.Value, false);
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3, false));
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4, false));
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node5, false));
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node6, false));
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node7, false));
|
|
||||||
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node8, false));
|
|
||||||
|
|
||||||
// /----( 6 )
|
_sArtifactSystem.AddEdge(artifactEnt, node3!.Value, node6!.Value, false);
|
||||||
// /----[*3 ]-/----( 7 )----( 8 )
|
_sArtifactSystem.AddEdge(artifactEnt, node3!.Value, node7!.Value, false);
|
||||||
// /
|
|
||||||
// / /----[*5 ]
|
|
||||||
// [ 1 ]--/----[ 2 ]--/----( 4 )
|
|
||||||
// Diagram of the example generation. Nodes in [brackets] are unlocked, nodes in (braces) are locked
|
|
||||||
// and nodes with an *asterisk are supposed to be active.
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value, false);
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node1!.Value, node3!.Value, false);
|
|
||||||
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node4!.Value, false);
|
_sArtifactSystem.AddEdge(artifactEnt, node7!.Value, node8!.Value, false);
|
||||||
artifactSystem.AddEdge(artifactEnt, node2!.Value, node5!.Value, false);
|
|
||||||
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node3!.Value, node6!.Value, false);
|
_sArtifactSystem.SetNodeUnlocked(node1!.Value);
|
||||||
artifactSystem.AddEdge(artifactEnt, node3!.Value, node7!.Value, false);
|
_sArtifactSystem.SetNodeUnlocked(node2!.Value);
|
||||||
|
_sArtifactSystem.SetNodeUnlocked(node3!.Value);
|
||||||
|
_sArtifactSystem.SetNodeUnlocked(node5!.Value);
|
||||||
|
|
||||||
artifactSystem.AddEdge(artifactEnt, node7!.Value, node8!.Value, false);
|
NetEntity[] expectedActiveNodes =
|
||||||
|
[
|
||||||
artifactSystem.SetNodeUnlocked(node1!.Value);
|
SEntMan.GetNetEntity(node3!.Value.Owner),
|
||||||
artifactSystem.SetNodeUnlocked(node2!.Value);
|
SEntMan.GetNetEntity(node5!.Value.Owner)
|
||||||
artifactSystem.SetNodeUnlocked(node3!.Value);
|
];
|
||||||
artifactSystem.SetNodeUnlocked(node5!.Value);
|
Assert.That(artifactEnt.Comp.CachedActiveNodes, Is.SupersetOf(expectedActiveNodes));
|
||||||
|
Assert.That(artifactEnt.Comp.CachedActiveNodes, Has.Count.EqualTo(expectedActiveNodes.Length));
|
||||||
NetEntity[] expectedActiveNodes =
|
|
||||||
[
|
|
||||||
entManager.GetNetEntity(node3!.Value.Owner),
|
|
||||||
entManager.GetNetEntity(node5!.Value.Owner)
|
|
||||||
];
|
|
||||||
Assert.That(artifactEnt.Comp.CachedActiveNodes, Is.SupersetOf(expectedActiveNodes));
|
|
||||||
Assert.That(artifactEnt.Comp.CachedActiveNodes, Has.Count.EqualTo(expectedActiveNodes.Length));
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
[RunOnSide(Side.Server)]
|
||||||
public async Task XenoArtifactGenerateSegmentsTest()
|
public async Task XenoArtifactGenerateSegmentsTest()
|
||||||
{
|
{
|
||||||
var pair = Pair;
|
var artifact1Uid = SSpawn(TestGenArtifactFlat);
|
||||||
var server = pair.Server;
|
Entity<XenoArtifactComponent> artifact1Ent = (artifact1Uid, SComp<XenoArtifactComponent>(artifact1Uid));
|
||||||
|
|
||||||
var entManager = server.ResolveDependency<IEntityManager>();
|
var segments1 = _sArtifactSystem.GetSegments(artifact1Ent);
|
||||||
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();
|
Assert.That(segments1, Has.Count.EqualTo(2));
|
||||||
|
Assert.That(segments1[0], Has.Count.EqualTo(1));
|
||||||
|
Assert.That(segments1[1], Has.Count.EqualTo(1));
|
||||||
|
|
||||||
await server.WaitPost(() =>
|
var artifact2Uid = SSpawn(TestGenArtifactTall);
|
||||||
{
|
Entity<XenoArtifactComponent> artifact2Ent = (artifact2Uid, SComp<XenoArtifactComponent>(artifact2Uid));
|
||||||
var artifact1Uid = entManager.Spawn("TestGenArtifactFlat");
|
|
||||||
Entity<XenoArtifactComponent> artifact1Ent = (artifact1Uid, entManager.GetComponent<XenoArtifactComponent>(artifact1Uid));
|
|
||||||
|
|
||||||
var segments1 = artifactSystem.GetSegments(artifact1Ent);
|
var segments2 = _sArtifactSystem.GetSegments(artifact2Ent);
|
||||||
Assert.That(segments1.Count, Is.EqualTo(2));
|
Assert.That(segments2, Has.Count.EqualTo(1));
|
||||||
Assert.That(segments1[0].Count, Is.EqualTo(1));
|
Assert.That(segments2[0], Has.Count.EqualTo(2));
|
||||||
Assert.That(segments1[1].Count, Is.EqualTo(1));
|
|
||||||
|
|
||||||
var artifact2Uid = entManager.Spawn("TestGenArtifactTall");
|
var artifact3Uid = SSpawn(TestGenArtifactFull);
|
||||||
Entity<XenoArtifactComponent> artifact2Ent = (artifact2Uid, entManager.GetComponent<XenoArtifactComponent>(artifact2Uid));
|
Entity<XenoArtifactComponent> artifact3Ent = (artifact3Uid, SComp<XenoArtifactComponent>(artifact3Uid));
|
||||||
|
|
||||||
var segments2 = artifactSystem.GetSegments(artifact2Ent);
|
var segments3 = _sArtifactSystem.GetSegments(artifact3Ent);
|
||||||
Assert.That(segments2.Count, Is.EqualTo(1));
|
Assert.That(segments3, Has.Count.EqualTo(1));
|
||||||
Assert.That(segments2[0].Count, Is.EqualTo(2));
|
Assert.That(segments3.Sum(x => x.Count), Is.EqualTo(6));
|
||||||
|
var nodesDepths = segments3[0].Select(x => x.Comp.Depth).ToArray();
|
||||||
var artifact3Uid = entManager.Spawn("TestGenArtifactFull");
|
Assert.That(nodesDepths.Distinct().Count(), Is.EqualTo(3));
|
||||||
Entity<XenoArtifactComponent> artifact3Ent = (artifact3Uid, entManager.GetComponent<XenoArtifactComponent>(artifact3Uid));
|
var grouped = nodesDepths.ToLookup(x => x);
|
||||||
|
Assert.That(grouped[0].Count(), Is.EqualTo(2));
|
||||||
var segments3 = artifactSystem.GetSegments(artifact3Ent);
|
Assert.That(grouped[1].Count(), Is.GreaterThanOrEqualTo(2)); // tree is attempting sometimes to get wider (so it will look like a tree)
|
||||||
Assert.That(segments3.Count, Is.EqualTo(1));
|
Assert.That(grouped[2].Count(), Is.LessThanOrEqualTo(2)); // maintain same width or, if we used 3 nodes on previous layer - we only have 1 left!
|
||||||
Assert.That(segments3.Sum(x => x.Count), Is.EqualTo(6));
|
|
||||||
var nodesDepths = segments3[0].Select(x => x.Comp.Depth).ToArray();
|
|
||||||
Assert.That(nodesDepths.Distinct().Count(), Is.EqualTo(3));
|
|
||||||
var grouped = nodesDepths.ToLookup(x => x);
|
|
||||||
Assert.That(grouped[0].Count(), Is.EqualTo(2));
|
|
||||||
Assert.That(grouped[1].Count(), Is.GreaterThanOrEqualTo(2)); // tree is attempting sometimes to get wider (so it will look like a tree)
|
|
||||||
Assert.That(grouped[2].Count(), Is.LessThanOrEqualTo(2)); // maintain same width or, if we used 3 nodes on previous layer - we only have 1 left!
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Content.Server.Ame.EntitySystems;
|
|||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.Explosion.EntitySystems;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.NodeContainer.NodeGroups;
|
using Content.Server.NodeContainer.NodeGroups;
|
||||||
using Content.Server.NodeContainer.Nodes;
|
|
||||||
using Content.Shared.NodeContainer;
|
using Content.Shared.NodeContainer;
|
||||||
using Content.Shared.NodeContainer.NodeGroups;
|
using Content.Shared.NodeContainer.NodeGroups;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public sealed partial class AnomalySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private SharedMapSystem _mapSystem = default!;
|
[Dependency] private SharedMapSystem _mapSystem = default!;
|
||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
|
||||||
private void InitializeGenerator()
|
private void InitializeGenerator()
|
||||||
{
|
{
|
||||||
@@ -106,13 +107,12 @@ public sealed partial class AnomalySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't spawn inside of solid objects
|
// don't spawn inside of solid objects
|
||||||
var physQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
var valid = true;
|
var valid = true;
|
||||||
|
|
||||||
// TODO: This should be using static lookup.
|
// TODO: This should be using static lookup.
|
||||||
foreach (var ent in _mapSystem.GetAnchoredEntities(grid, gridComp, tile))
|
foreach (var ent in _mapSystem.GetAnchoredEntities(grid, gridComp, tile))
|
||||||
{
|
{
|
||||||
if (!physQuery.TryGetComponent(ent, out var body))
|
if (!_physicsQuery.TryGetComponent(ent, out var body))
|
||||||
continue;
|
continue;
|
||||||
if (body.BodyType != BodyType.Static ||
|
if (body.BodyType != BodyType.Static ||
|
||||||
!body.Hard ||
|
!body.Hard ||
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ public sealed partial class BluespaceAnomalySystem : EntitySystem
|
|||||||
|
|
||||||
private void OnPulse(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalyPulseEvent args)
|
private void OnPulse(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||||
{
|
{
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
var xform = Transform(uid);
|
||||||
var xform = xformQuery.GetComponent(uid);
|
|
||||||
var range = component.MaxShuffleRadius * args.Severity * args.PowerModifier;
|
var range = component.MaxShuffleRadius * args.Severity * args.PowerModifier;
|
||||||
// get a list of all entities in range with the MobStateComponent
|
// get a list of all entities in range with the MobStateComponent
|
||||||
// we filter out those inside a container
|
// we filter out those inside a container
|
||||||
@@ -42,7 +41,7 @@ public sealed partial class BluespaceAnomalySystem : EntitySystem
|
|||||||
var coords = new ValueList<Vector2>();
|
var coords = new ValueList<Vector2>();
|
||||||
foreach (var ent in allEnts)
|
foreach (var ent in allEnts)
|
||||||
{
|
{
|
||||||
if (xformQuery.TryGetComponent(ent, out var allXform))
|
if (TryComp(ent, out TransformComponent? allXform))
|
||||||
coords.Add(_xform.GetWorldPosition(allXform));
|
coords.Add(_xform.GetWorldPosition(allXform));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Content.Shared.Anomaly.Components;
|
|||||||
using Content.Shared.Anomaly.Effects;
|
using Content.Shared.Anomaly.Effects;
|
||||||
using Content.Shared.Anomaly.Effects.Components;
|
using Content.Shared.Anomaly.Effects.Components;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Physics.Components;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.Anomaly.Effects;
|
namespace Content.Server.Anomaly.Effects;
|
||||||
@@ -14,13 +13,9 @@ public sealed partial class EntityAnomalySystem : SharedEntityAnomalySystem
|
|||||||
[Dependency] private IRobustRandom _random = default!;
|
[Dependency] private IRobustRandom _random = default!;
|
||||||
[Dependency] private SharedMapSystem _mapSystem = default!;
|
[Dependency] private SharedMapSystem _mapSystem = default!;
|
||||||
|
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||||
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
||||||
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalyStabilityChangedEvent>(OnStabilityChanged);
|
SubscribeLocalEvent<EntitySpawnAnomalyComponent, AnomalyStabilityChangedEvent>(OnStabilityChanged);
|
||||||
|
|||||||
@@ -18,15 +18,12 @@ public sealed partial class InjectionAnomalySystem : EntitySystem
|
|||||||
[Dependency] private EntityLookupSystem _lookup = default!;
|
[Dependency] private EntityLookupSystem _lookup = default!;
|
||||||
[Dependency] private SharedSolutionContainerSystem _solutionContainer = default!;
|
[Dependency] private SharedSolutionContainerSystem _solutionContainer = default!;
|
||||||
[Dependency] private TransformSystem _transform = default!;
|
[Dependency] private TransformSystem _transform = default!;
|
||||||
|
[Dependency] private EntityQuery<InjectableSolutionComponent> _injectableQuery = default!;
|
||||||
private EntityQuery<InjectableSolutionComponent> _injectableQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<InjectionAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
SubscribeLocalEvent<InjectionAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||||
SubscribeLocalEvent<InjectionAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical, before: new[] { typeof(SharedSolutionContainerSystem) });
|
SubscribeLocalEvent<InjectionAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical, before: new[] { typeof(SharedSolutionContainerSystem) });
|
||||||
|
|
||||||
_injectableQuery = GetEntityQuery<InjectableSolutionComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPulse(Entity<InjectionAnomalyComponent> entity, ref AnomalyPulseEvent args)
|
private void OnPulse(Entity<InjectionAnomalyComponent> entity, ref AnomalyPulseEvent args)
|
||||||
@@ -45,8 +42,7 @@ public sealed partial class InjectionAnomalySystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//We get all the entity in the radius into which the reagent will be injected.
|
//We get all the entity in the radius into which the reagent will be injected.
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
var xform = Transform(entity);
|
||||||
var xform = xformQuery.GetComponent(entity);
|
|
||||||
var allEnts = _lookup.GetEntitiesInRange<InjectableSolutionComponent>(_transform.GetMapCoordinates(entity, xform: xform), injectRadius)
|
var allEnts = _lookup.GetEntitiesInRange<InjectableSolutionComponent>(_transform.GetMapCoordinates(entity, xform: xform), injectRadius)
|
||||||
.Select(x => x.Owner).ToList();
|
.Select(x => x.Owner).ToList();
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ public sealed partial class ProjectileAnomalySystem : EntitySystem
|
|||||||
[Dependency] private IMapManager _mapManager = default!;
|
[Dependency] private IMapManager _mapManager = default!;
|
||||||
[Dependency] private GunSystem _gunSystem = default!;
|
[Dependency] private GunSystem _gunSystem = default!;
|
||||||
[Dependency] private SharedMapSystem _map = default!;
|
[Dependency] private SharedMapSystem _map = default!;
|
||||||
|
[Dependency] private EntityQuery<MobStateComponent> _mobStateQuery = default!;
|
||||||
private EntityQuery<TransformComponent> _xFormQuery;
|
|
||||||
private EntityQuery<MobStateComponent> _mobQuery;
|
|
||||||
|
|
||||||
/// <summary> Pre-allocated collection for calculating entities in range. </summary>
|
/// <summary> Pre-allocated collection for calculating entities in range. </summary>
|
||||||
private readonly HashSet<EntityUid> _inRange = new();
|
private readonly HashSet<EntityUid> _inRange = new();
|
||||||
@@ -32,9 +30,6 @@ public sealed partial class ProjectileAnomalySystem : EntitySystem
|
|||||||
{
|
{
|
||||||
SubscribeLocalEvent<ProjectileAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
SubscribeLocalEvent<ProjectileAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||||
SubscribeLocalEvent<ProjectileAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
SubscribeLocalEvent<ProjectileAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
||||||
|
|
||||||
_xFormQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
_mobQuery = GetEntityQuery<MobStateComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPulse(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalyPulseEvent args)
|
private void OnPulse(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||||
@@ -51,7 +46,7 @@ public sealed partial class ProjectileAnomalySystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var projectileCount = (int)MathF.Round(MathHelper.Lerp(component.MinProjectiles, component.MaxProjectiles, severity));
|
var projectileCount = (int)MathF.Round(MathHelper.Lerp(component.MinProjectiles, component.MaxProjectiles, severity));
|
||||||
|
|
||||||
var xform = _xFormQuery.GetComponent(uid);
|
var xform = Transform(uid);
|
||||||
|
|
||||||
_inRange.Clear();
|
_inRange.Clear();
|
||||||
_lookup.GetEntitiesInRange(uid, component.ProjectileRange * severity, _inRange, LookupFlags.Dynamic);
|
_lookup.GetEntitiesInRange(uid, component.ProjectileRange * severity, _inRange, LookupFlags.Dynamic);
|
||||||
@@ -62,7 +57,7 @@ public sealed partial class ProjectileAnomalySystem : EntitySystem
|
|||||||
var priority = new List<EntityUid>();
|
var priority = new List<EntityUid>();
|
||||||
foreach (var entity in _inRange)
|
foreach (var entity in _inRange)
|
||||||
{
|
{
|
||||||
if (_mobQuery.HasComponent(entity))
|
if (_mobStateQuery.HasComponent(entity))
|
||||||
priority.Add(entity);
|
priority.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +69,7 @@ public sealed partial class ProjectileAnomalySystem : EntitySystem
|
|||||||
? _random.PickAndTake(priority)
|
? _random.PickAndTake(priority)
|
||||||
: _random.Pick(_inRange);
|
: _random.Pick(_inRange);
|
||||||
|
|
||||||
var targetXForm= _xFormQuery.GetComponent(target);
|
var targetXForm = Transform(target);
|
||||||
var targetCoords = targetXForm.Coordinates.Offset(_random.NextVector2(0.5f));
|
var targetCoords = targetXForm.Coordinates.Offset(_random.NextVector2(0.5f));
|
||||||
|
|
||||||
ShootProjectile(
|
ShootProjectile(
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
public void InvalidatePosition(Entity<MapGridComponent?> grid, Vector2i pos)
|
public void InvalidatePosition(Entity<MapGridComponent?> grid, Vector2i pos)
|
||||||
{
|
{
|
||||||
var query = GetEntityQuery<AirtightComponent>();
|
|
||||||
_explosionSystem.UpdateAirtightMap(grid, pos, grid);
|
_explosionSystem.UpdateAirtightMap(grid, pos, grid);
|
||||||
_atmosphereSystem.InvalidateTile(grid.Owner, pos);
|
_atmosphereSystem.InvalidateTile(grid.Owner, pos);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Content.Shared.Atmos.EntitySystems;
|
|||||||
using Content.Shared.Atmos.Reactions;
|
using Content.Shared.Atmos.Reactions;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems;
|
namespace Content.Server.Atmos.EntitySystems;
|
||||||
@@ -29,7 +28,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool HasAtmosphere(EntityUid gridUid)
|
public bool HasAtmosphere(EntityUid gridUid)
|
||||||
{
|
{
|
||||||
return _atmosQuery.HasComponent(gridUid);
|
return _gridAtmosQuery.HasComponent(gridUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -95,7 +94,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public void InvalidateTile(Entity<GridAtmosphereComponent?> entity, Vector2i tile)
|
public void InvalidateTile(Entity<GridAtmosphereComponent?> entity, Vector2i tile)
|
||||||
{
|
{
|
||||||
if (_atmosQuery.Resolve(entity.Owner, ref entity.Comp, false))
|
if (_gridAtmosQuery.Resolve(entity.Owner, ref entity.Comp, false))
|
||||||
entity.Comp.InvalidatedCoords.Add(tile);
|
entity.Comp.InvalidatedCoords.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +180,7 @@ public partial class AtmosphereSystem
|
|||||||
var handled = false;
|
var handled = false;
|
||||||
|
|
||||||
// If we've been passed a grid, try to let it handle it.
|
// If we've been passed a grid, try to let it handle it.
|
||||||
if (grid is { } gridEnt && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp1))
|
if (grid is { } gridEnt && _gridAtmosQuery.Resolve(gridEnt, ref gridEnt.Comp1))
|
||||||
{
|
{
|
||||||
if (excite)
|
if (excite)
|
||||||
Resolve(gridEnt, ref gridEnt.Comp2);
|
Resolve(gridEnt, ref gridEnt.Comp2);
|
||||||
@@ -244,7 +243,7 @@ public partial class AtmosphereSystem
|
|||||||
{
|
{
|
||||||
// If we've been passed a grid, try to let it handle it.
|
// If we've been passed a grid, try to let it handle it.
|
||||||
if (grid is { } gridEnt
|
if (grid is { } gridEnt
|
||||||
&& _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp1, false)
|
&& _gridAtmosQuery.Resolve(gridEnt, ref gridEnt.Comp1, false)
|
||||||
&& gridEnt.Comp1.Tiles.TryGetValue(gridTile, out var tile))
|
&& gridEnt.Comp1.Tiles.TryGetValue(gridTile, out var tile))
|
||||||
{
|
{
|
||||||
if (excite)
|
if (excite)
|
||||||
@@ -440,7 +439,7 @@ public partial class AtmosphereSystem
|
|||||||
Vector2i tile,
|
Vector2i tile,
|
||||||
AtmosDirection directions = AtmosDirection.All)
|
AtmosDirection directions = AtmosDirection.All)
|
||||||
{
|
{
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
if (!grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
||||||
@@ -463,7 +462,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public AtmosDirection GetAirflowDirections(Entity<GridAtmosphereComponent?> grid, Vector2i tile)
|
public AtmosDirection GetAirflowDirections(Entity<GridAtmosphereComponent?> grid, Vector2i tile)
|
||||||
{
|
{
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return AtmosDirection.Invalid;
|
return AtmosDirection.Invalid;
|
||||||
|
|
||||||
if (!grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
if (!grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
||||||
@@ -486,7 +485,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool IsTileSpace(Entity<GridAtmosphereComponent?>? grid, Entity<MapAtmosphereComponent?>? map, Vector2i tile)
|
public bool IsTileSpace(Entity<GridAtmosphereComponent?>? grid, Entity<MapAtmosphereComponent?>? map, Vector2i tile)
|
||||||
{
|
{
|
||||||
if (grid is { } gridEnt && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp, false)
|
if (grid is { } gridEnt && _gridAtmosQuery.Resolve(gridEnt, ref gridEnt.Comp, false)
|
||||||
&& gridEnt.Comp.Tiles.TryGetValue(tile, out var tileAtmos))
|
&& gridEnt.Comp.Tiles.TryGetValue(tile, out var tileAtmos))
|
||||||
{
|
{
|
||||||
return tileAtmos.Space;
|
return tileAtmos.Space;
|
||||||
@@ -541,7 +540,7 @@ public partial class AtmosphereSystem
|
|||||||
public TileMixtureEnumerator GetAdjacentTileMixtures(Entity<GridAtmosphereComponent?> grid, Vector2i tile, bool includeBlocked = false, bool excite = false)
|
public TileMixtureEnumerator GetAdjacentTileMixtures(Entity<GridAtmosphereComponent?> grid, Vector2i tile, bool includeBlocked = false, bool excite = false)
|
||||||
{
|
{
|
||||||
// TODO ATMOS includeBlocked and excite parameters are unhandled currently.
|
// TODO ATMOS includeBlocked and excite parameters are unhandled currently.
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return TileMixtureEnumerator.Empty;
|
return TileMixtureEnumerator.Empty;
|
||||||
|
|
||||||
return !grid.Comp.Tiles.TryGetValue(tile, out var atmosTile)
|
return !grid.Comp.Tiles.TryGetValue(tile, out var atmosTile)
|
||||||
@@ -572,7 +571,7 @@ public partial class AtmosphereSystem
|
|||||||
EntityUid? sparkSourceUid = null,
|
EntityUid? sparkSourceUid = null,
|
||||||
bool soh = false)
|
bool soh = false)
|
||||||
{
|
{
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
if (grid.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
||||||
@@ -600,7 +599,7 @@ public partial class AtmosphereSystem
|
|||||||
EntityUid? sparkSourceUid = null,
|
EntityUid? sparkSourceUid = null,
|
||||||
bool soh = false)
|
bool soh = false)
|
||||||
{
|
{
|
||||||
if (!_atmosQuery.TryGetComponent(tile.GridIndex, out var atmos))
|
if (!_gridAtmosQuery.TryGetComponent(tile.GridIndex, out var atmos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DebugTools.Assert(atmos.Tiles.TryGetValue(tile.GridIndices, out var tmp) && tmp == tile);
|
DebugTools.Assert(atmos.Tiles.TryGetValue(tile.GridIndices, out var tmp) && tmp == tile);
|
||||||
@@ -644,7 +643,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool AddPipeNet(Entity<GridAtmosphereComponent?> grid, PipeNet pipeNet)
|
public bool AddPipeNet(Entity<GridAtmosphereComponent?> grid, PipeNet pipeNet)
|
||||||
{
|
{
|
||||||
return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Add(pipeNet);
|
return _gridAtmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Add(pipeNet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -664,7 +663,7 @@ public partial class AtmosphereSystem
|
|||||||
RaiseLocalEvent(ref ev);
|
RaiseLocalEvent(ref ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Remove(pipeNet);
|
return _gridAtmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Remove(pipeNet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -679,7 +678,7 @@ public partial class AtmosphereSystem
|
|||||||
DebugTools.Assert(device.Comp.JoinedGrid == null);
|
DebugTools.Assert(device.Comp.JoinedGrid == null);
|
||||||
DebugTools.Assert(Transform(device).GridUid == grid);
|
DebugTools.Assert(Transform(device).GridUid == grid);
|
||||||
|
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!grid.Comp.AtmosDevices.Add(device))
|
if (!grid.Comp.AtmosDevices.Add(device))
|
||||||
@@ -699,7 +698,7 @@ public partial class AtmosphereSystem
|
|||||||
{
|
{
|
||||||
DebugTools.Assert(device.Comp.JoinedGrid == grid);
|
DebugTools.Assert(device.Comp.JoinedGrid == grid);
|
||||||
|
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!grid.Comp.AtmosDevices.Remove(device))
|
if (!grid.Comp.AtmosDevices.Remove(device))
|
||||||
@@ -732,7 +731,7 @@ public partial class AtmosphereSystem
|
|||||||
// Entity should be on the grid it's being added to.
|
// Entity should be on the grid it's being added to.
|
||||||
Debug.Assert(xform.GridUid == grid.Owner);
|
Debug.Assert(xform.GridUid == grid.Owner);
|
||||||
|
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (grid.Comp.DeltaPressureEntityLookup.ContainsKey(ent.Owner))
|
if (grid.Comp.DeltaPressureEntityLookup.ContainsKey(ent.Owner))
|
||||||
@@ -759,7 +758,7 @@ public partial class AtmosphereSystem
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool TryRemoveDeltaPressureEntity(Entity<GridAtmosphereComponent?> grid, Entity<DeltaPressureComponent> ent)
|
public bool TryRemoveDeltaPressureEntity(Entity<GridAtmosphereComponent?> grid, Entity<DeltaPressureComponent> ent)
|
||||||
{
|
{
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!grid.Comp.DeltaPressureEntityLookup.TryGetValue(ent.Owner, out var index))
|
if (!grid.Comp.DeltaPressureEntityLookup.TryGetValue(ent.Owner, out var index))
|
||||||
@@ -797,7 +796,7 @@ public partial class AtmosphereSystem
|
|||||||
public bool IsDeltaPressureEntityInList(Entity<GridAtmosphereComponent?> grid, Entity<DeltaPressureComponent> ent)
|
public bool IsDeltaPressureEntityInList(Entity<GridAtmosphereComponent?> grid, Entity<DeltaPressureComponent> ent)
|
||||||
{
|
{
|
||||||
// Dict and list must be in sync - deep-fried if we aren't.
|
// Dict and list must be in sync - deep-fried if we aren't.
|
||||||
if (!_atmosQuery.Resolve(grid, ref grid.Comp, false))
|
if (!_gridAtmosQuery.Resolve(grid, ref grid.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var contains = grid.Comp.DeltaPressureEntityLookup.ContainsKey(ent.Owner);
|
var contains = grid.Comp.DeltaPressureEntityLookup.ContainsKey(ent.Owner);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace Content.Server.Atmos.EntitySystems;
|
|||||||
public sealed partial class AtmosphereSystem
|
public sealed partial class AtmosphereSystem
|
||||||
{
|
{
|
||||||
[Dependency] private IConsoleHost _consoleHost = default!;
|
[Dependency] private IConsoleHost _consoleHost = default!;
|
||||||
|
[Dependency] private EntityQuery<AtmosFixMarkerComponent> _atmosFixMarkerQuery = default!;
|
||||||
|
|
||||||
private void InitializeCommands()
|
private void InitializeCommands()
|
||||||
{
|
{
|
||||||
@@ -113,7 +114,6 @@ public sealed partial class AtmosphereSystem
|
|||||||
|
|
||||||
RebuildGridTiles(grid);
|
RebuildGridTiles(grid);
|
||||||
|
|
||||||
var query = GetEntityQuery<AtmosFixMarkerComponent>();
|
|
||||||
foreach (var (indices, tile) in ent.Comp1.Tiles.ToArray())
|
foreach (var (indices, tile) in ent.Comp1.Tiles.ToArray())
|
||||||
{
|
{
|
||||||
if (tile.Air is not {Immutable: false} air)
|
if (tile.Air is not {Immutable: false} air)
|
||||||
@@ -124,7 +124,7 @@ public sealed partial class AtmosphereSystem
|
|||||||
var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(grid, grid, indices);
|
var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(grid, grid, indices);
|
||||||
while (enumerator.MoveNext(out var entUid))
|
while (enumerator.MoveNext(out var entUid))
|
||||||
{
|
{
|
||||||
if (query.TryComp(entUid, out var marker))
|
if (_atmosFixMarkerQuery.TryComp(entUid, out var marker))
|
||||||
mixtureId = marker.Mode;
|
mixtureId = marker.Mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
public sealed partial class AtmosphereSystem
|
public sealed partial class AtmosphereSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<MovedByPressureComponent> _movedByPressureQuery = default!;
|
||||||
|
|
||||||
private static readonly ProtoId<SoundCollectionPrototype> DefaultSpaceWindSounds = "SpaceWind";
|
private static readonly ProtoId<SoundCollectionPrototype> DefaultSpaceWindSounds = "SpaceWind";
|
||||||
|
|
||||||
private const int SpaceWindSoundCooldownCycles = 75;
|
private const int SpaceWindSoundCooldownCycles = 75;
|
||||||
@@ -100,7 +103,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
_activePressures.Add((uid, component));
|
_activePressures.Add((uid, component));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HighPressureMovements(Entity<GridAtmosphereComponent> gridAtmosphere, TileAtmosphere tile, EntityQuery<PhysicsComponent> bodies, EntityQuery<TransformComponent> xforms, EntityQuery<MovedByPressureComponent> pressureQuery, EntityQuery<MetaDataComponent> metas)
|
private void HighPressureMovements(Entity<GridAtmosphereComponent> gridAtmosphere, TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
// TODO ATMOS finish this
|
// TODO ATMOS finish this
|
||||||
|
|
||||||
@@ -156,12 +159,12 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
// Ideally containers would have their own EntityQuery internally or something given recursively it may need to slam GetComp<T> anyway.
|
// Ideally containers would have their own EntityQuery internally or something given recursively it may need to slam GetComp<T> anyway.
|
||||||
// Also, don't care about static bodies (but also due to collisionwakestate can't query dynamic directly atm).
|
// Also, don't care about static bodies (but also due to collisionwakestate can't query dynamic directly atm).
|
||||||
if (!bodies.TryGetComponent(entity, out var body) ||
|
if (!_physicsQuery.TryGetComponent(entity, out var body) ||
|
||||||
!pressureQuery.TryGetComponent(entity, out var pressure) ||
|
!_movedByPressureQuery.TryGetComponent(entity, out var pressure) ||
|
||||||
!pressure.Enabled)
|
!pressure.Enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_containers.IsEntityInContainer(entity, metas.GetComponent(entity))) continue;
|
if (_containers.IsEntityInContainer(entity)) continue;
|
||||||
|
|
||||||
var pressureMovements = EnsureComp<MovedByPressureComponent>(entity);
|
var pressureMovements = EnsureComp<MovedByPressureComponent>(entity);
|
||||||
if (pressure.LastHighPressureMovementAirCycle < gridAtmosphere.Comp.UpdateCounter)
|
if (pressure.LastHighPressureMovementAirCycle < gridAtmosphere.Comp.UpdateCounter)
|
||||||
@@ -174,7 +177,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
tile.PressureDirection, 0,
|
tile.PressureDirection, 0,
|
||||||
tile.PressureSpecificTarget != null ? _mapSystem.ToCenterCoordinates(tile.GridIndex, tile.PressureSpecificTarget.GridIndices) : EntityCoordinates.Invalid,
|
tile.PressureSpecificTarget != null ? _mapSystem.ToCenterCoordinates(tile.GridIndex, tile.PressureSpecificTarget.GridIndices) : EntityCoordinates.Invalid,
|
||||||
gridWorldRotation,
|
gridWorldRotation,
|
||||||
xforms.GetComponent(entity),
|
Transform(entity),
|
||||||
body);
|
body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -395,14 +395,9 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
// Note: This is still processed even if space wind is turned off since this handles playing the sounds.
|
// Note: This is still processed even if space wind is turned off since this handles playing the sounds.
|
||||||
|
|
||||||
var number = 0;
|
var number = 0;
|
||||||
var bodies = GetEntityQuery<PhysicsComponent>();
|
|
||||||
var xforms = GetEntityQuery<TransformComponent>();
|
|
||||||
var metas = GetEntityQuery<MetaDataComponent>();
|
|
||||||
var pressureQuery = GetEntityQuery<MovedByPressureComponent>();
|
|
||||||
|
|
||||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||||
{
|
{
|
||||||
HighPressureMovements(ent, tile, bodies, xforms, pressureQuery, metas);
|
HighPressureMovements(ent, tile);
|
||||||
tile.PressureDifference = 0f;
|
tile.PressureDifference = 0f;
|
||||||
tile.LastPressureDirection = tile.PressureDirection;
|
tile.LastPressureDirection = tile.PressureDirection;
|
||||||
tile.PressureDirection = AtmosDirection.Invalid;
|
tile.PressureDirection = AtmosDirection.Invalid;
|
||||||
|
|||||||
@@ -42,13 +42,14 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
|
|||||||
[Dependency] public PuddleSystem Puddle = default!;
|
[Dependency] public PuddleSystem Puddle = default!;
|
||||||
[Dependency] private DamageableSystem _damage = default!;
|
[Dependency] private DamageableSystem _damage = default!;
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<GridAtmosphereComponent> _gridAtmosQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<MapAtmosphereComponent> _mapAtmosQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<AirtightComponent> _airtightQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<FirelockComponent> _firelockQuery = default!;
|
||||||
|
|
||||||
private const float ExposedUpdateDelay = 1f;
|
private const float ExposedUpdateDelay = 1f;
|
||||||
private float _exposedTimer = 0f;
|
private float _exposedTimer = 0f;
|
||||||
|
|
||||||
private EntityQuery<GridAtmosphereComponent> _atmosQuery;
|
|
||||||
private EntityQuery<MapAtmosphereComponent> _mapAtmosQuery;
|
|
||||||
private EntityQuery<AirtightComponent> _airtightQuery;
|
|
||||||
private EntityQuery<FirelockComponent> _firelockQuery;
|
|
||||||
private HashSet<EntityUid> _entSet = new();
|
private HashSet<EntityUid> _entSet = new();
|
||||||
|
|
||||||
private string[] _burntDecals = [];
|
private string[] _burntDecals = [];
|
||||||
@@ -65,11 +66,6 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
|
|||||||
InitializeGridAtmosphere();
|
InitializeGridAtmosphere();
|
||||||
InitializeMap();
|
InitializeMap();
|
||||||
|
|
||||||
_atmosQuery = GetEntityQuery<GridAtmosphereComponent>();
|
|
||||||
_mapAtmosQuery = GetEntityQuery<MapAtmosphereComponent>();
|
|
||||||
_airtightQuery = GetEntityQuery<AirtightComponent>();
|
|
||||||
_firelockQuery = GetEntityQuery<FirelockComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<TileChangedEvent>(OnTileChanged);
|
SubscribeLocalEvent<TileChangedEvent>(OnTileChanged);
|
||||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
||||||
|
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[Dependency] private IRobustRandom _random = default!;
|
[Dependency] private IRobustRandom _random = default!;
|
||||||
[Dependency] private IGameTiming _timing = default!;
|
[Dependency] private IGameTiming _timing = default!;
|
||||||
|
|
||||||
private EntityQuery<InventoryComponent> _inventoryQuery;
|
[Dependency] private EntityQuery<InventoryComponent> _inventoryQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
|
||||||
private static readonly TimeSpan UpdateTime = TimeSpan.FromSeconds(1);
|
private static readonly TimeSpan UpdateTime = TimeSpan.FromSeconds(1);
|
||||||
|
|
||||||
@@ -62,9 +62,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
UpdatesAfter.Add(typeof(AtmosphereSystem));
|
UpdatesAfter.Add(typeof(AtmosphereSystem));
|
||||||
|
|
||||||
_inventoryQuery = GetEntityQuery<InventoryComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<FlammableComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<FlammableComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsing);
|
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollide);
|
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollide);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Content.Server.Atmos.Components;
|
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Atmos.Components;
|
using Content.Shared.Atmos.Components;
|
||||||
using Content.Shared.Atmos.EntitySystems;
|
using Content.Shared.Atmos.EntitySystems;
|
||||||
@@ -33,6 +32,9 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[Robust.Shared.IoC.Dependency] private AtmosphereSystem _atmosphereSystem = default!;
|
[Robust.Shared.IoC.Dependency] private AtmosphereSystem _atmosphereSystem = default!;
|
||||||
[Robust.Shared.IoC.Dependency] private ChunkingSystem _chunkingSys = default!;
|
[Robust.Shared.IoC.Dependency] private ChunkingSystem _chunkingSys = default!;
|
||||||
|
|
||||||
|
[Robust.Shared.IoC.Dependency] private EntityQuery<MapGridComponent> _mapGridQuery = default!;
|
||||||
|
[Robust.Shared.IoC.Dependency] private EntityQuery<GasTileOverlayComponent> _gasTileOverlayQuery = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Per-tick cache of sessions.
|
/// Per-tick cache of sessions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -57,16 +59,11 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
private float _updateInterval;
|
private float _updateInterval;
|
||||||
|
|
||||||
private int _thresholds;
|
private int _thresholds;
|
||||||
private EntityQuery<MapGridComponent> _gridQuery;
|
|
||||||
private EntityQuery<GasTileOverlayComponent> _query;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_query = GetEntityQuery<GasTileOverlayComponent>();
|
|
||||||
_gridQuery = GetEntityQuery<MapGridComponent>();
|
|
||||||
|
|
||||||
_updateJob = new UpdatePlayerJob()
|
_updateJob = new UpdatePlayerJob()
|
||||||
{
|
{
|
||||||
EntManager = EntityManager,
|
EntManager = EntityManager,
|
||||||
@@ -77,7 +74,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
MapManager = _mapManager,
|
MapManager = _mapManager,
|
||||||
ChunkViewerPool = _chunkViewerPool,
|
ChunkViewerPool = _chunkViewerPool,
|
||||||
LastSentChunks = _lastSentChunks,
|
LastSentChunks = _lastSentChunks,
|
||||||
GridQuery = _gridQuery,
|
GridQuery = _mapGridQuery,
|
||||||
};
|
};
|
||||||
|
|
||||||
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||||
@@ -136,7 +133,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Invalidate(Entity<GasTileOverlayComponent?> grid, Vector2i index)
|
public void Invalidate(Entity<GasTileOverlayComponent?> grid, Vector2i index)
|
||||||
{
|
{
|
||||||
if (_query.Resolve(grid.Owner, ref grid.Comp))
|
if (_gasTileOverlayQuery.Resolve(grid.Owner, ref grid.Comp))
|
||||||
grid.Comp.InvalidTiles.Add(index);
|
grid.Comp.InvalidTiles.Add(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.NodeContainer;
|
|
||||||
using Content.Server.NodeContainer.Nodes;
|
using Content.Server.NodeContainer.Nodes;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
@@ -21,17 +20,15 @@ public sealed partial class PipeRestrictOverlapSystem : EntitySystem
|
|||||||
[Dependency] private MapSystem _map = default!;
|
[Dependency] private MapSystem _map = default!;
|
||||||
[Dependency] private PopupSystem _popup = default!;
|
[Dependency] private PopupSystem _popup = default!;
|
||||||
[Dependency] private TransformSystem _xform = default!;
|
[Dependency] private TransformSystem _xform = default!;
|
||||||
|
[Dependency] private EntityQuery<NodeContainerComponent> _nodeContainerQuery = default!;
|
||||||
|
|
||||||
private readonly List<EntityUid> _anchoredEntities = new();
|
private readonly List<EntityUid> _anchoredEntities = new();
|
||||||
private EntityQuery<NodeContainerComponent> _nodeContainerQuery;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<PipeRestrictOverlapComponent, AnchorStateChangedEvent>(OnAnchorStateChanged);
|
SubscribeLocalEvent<PipeRestrictOverlapComponent, AnchorStateChangedEvent>(OnAnchorStateChanged);
|
||||||
SubscribeLocalEvent<PipeRestrictOverlapComponent, AnchorAttemptEvent>(OnAnchorAttempt);
|
SubscribeLocalEvent<PipeRestrictOverlapComponent, AnchorAttemptEvent>(OnAnchorAttempt);
|
||||||
|
|
||||||
_nodeContainerQuery = GetEntityQuery<NodeContainerComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAnchorStateChanged(Entity<PipeRestrictOverlapComponent> ent, ref AnchorStateChangedEvent args)
|
private void OnAnchorStateChanged(Entity<PipeRestrictOverlapComponent> ent, ref AnchorStateChangedEvent args)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public sealed partial class AirAlarmSystem : EntitySystem
|
|||||||
[Dependency] private DeviceListSystem _deviceList = default!;
|
[Dependency] private DeviceListSystem _deviceList = default!;
|
||||||
[Dependency] private PopupSystem _popup = default!;
|
[Dependency] private PopupSystem _popup = default!;
|
||||||
[Dependency] private UserInterfaceSystem _ui = default!;
|
[Dependency] private UserInterfaceSystem _ui = default!;
|
||||||
|
[Dependency] private EntityQuery<DeviceNetworkComponent> _deviceNetworkQuery = default!;
|
||||||
|
|
||||||
#region Device Network API
|
#region Device Network API
|
||||||
|
|
||||||
@@ -193,10 +194,9 @@ public sealed partial class AirAlarmSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnDeviceListUpdate(EntityUid uid, AirAlarmComponent component, DeviceListUpdateEvent args)
|
private void OnDeviceListUpdate(EntityUid uid, AirAlarmComponent component, DeviceListUpdateEvent args)
|
||||||
{
|
{
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
foreach (var device in args.OldDevices)
|
foreach (var device in args.OldDevices)
|
||||||
{
|
{
|
||||||
if (!query.TryGetComponent(device, out var deviceNet))
|
if (!_deviceNetworkQuery.TryGetComponent(device, out var deviceNet))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public sealed partial class FireAlarmSystem : EntitySystem
|
|||||||
[Dependency] private SharedInteractionSystem _interactionSystem = default!;
|
[Dependency] private SharedInteractionSystem _interactionSystem = default!;
|
||||||
[Dependency] private AccessReaderSystem _access = default!;
|
[Dependency] private AccessReaderSystem _access = default!;
|
||||||
[Dependency] private IConfigurationManager _configManager = default!;
|
[Dependency] private IConfigurationManager _configManager = default!;
|
||||||
|
[Dependency] private EntityQuery<DeviceNetworkComponent> _deviceNetworkQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -29,10 +30,9 @@ public sealed partial class FireAlarmSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnDeviceListSync(EntityUid uid, FireAlarmComponent component, DeviceListUpdateEvent args)
|
private void OnDeviceListSync(EntityUid uid, FireAlarmComponent component, DeviceListUpdateEvent args)
|
||||||
{
|
{
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
foreach (var device in args.OldDevices)
|
foreach (var device in args.OldDevices)
|
||||||
{
|
{
|
||||||
if (!query.TryGetComponent(device, out var deviceNet))
|
if (!_deviceNetworkQuery.TryGetComponent(device, out var deviceNet))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
|
|
||||||
private void OnDeviceParentChanged(Entity<AtmosDeviceComponent> ent, ref EntParentChangedMessage args)
|
private void OnDeviceParentChanged(Entity<AtmosDeviceComponent> ent, ref EntParentChangedMessage args)
|
||||||
{
|
{
|
||||||
|
// Event is raised when a map is loaded in. Since this event mutates comp.Enabled,
|
||||||
|
// it will overwrite whatever saved value it had
|
||||||
|
// (so devices saved as enabled will just be disabled).
|
||||||
|
if (args.OldParent is null)
|
||||||
|
return;
|
||||||
|
|
||||||
RejoinAtmosphere(ent);
|
RejoinAtmosphere(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,9 @@ public sealed partial class InternalsSystem : SharedInternalsSystem
|
|||||||
[Dependency] private GasTankSystem _gasTank = default!;
|
[Dependency] private GasTankSystem _gasTank = default!;
|
||||||
[Dependency] private RespiratorSystem _respirator = default!;
|
[Dependency] private RespiratorSystem _respirator = default!;
|
||||||
|
|
||||||
private EntityQuery<InternalsComponent> _internalsQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_internalsQuery = GetEntityQuery<InternalsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<InternalsComponent, InhaleLocationEvent>(OnInhaleLocation);
|
SubscribeLocalEvent<InternalsComponent, InhaleLocationEvent>(OnInhaleLocation);
|
||||||
SubscribeLocalEvent<InternalsComponent, StartingGearEquippedEvent>(OnStartingGear);
|
SubscribeLocalEvent<InternalsComponent, StartingGearEquippedEvent>(OnStartingGear);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ using Robust.Server.Containers;
|
|||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems;
|
namespace Content.Server.Cargo.Systems;
|
||||||
@@ -28,11 +27,11 @@ public sealed partial class CargoSystem
|
|||||||
[Dependency] private NameIdentifierSystem _nameIdentifier = default!;
|
[Dependency] private NameIdentifierSystem _nameIdentifier = default!;
|
||||||
[Dependency] private EntityWhitelistSystem _whitelistSys = default!;
|
[Dependency] private EntityWhitelistSystem _whitelistSys = default!;
|
||||||
|
|
||||||
private static readonly ProtoId<NameIdentifierGroupPrototype> BountyNameIdentifierGroup = "Bounty";
|
[Dependency] private EntityQuery<StackComponent> _stackQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<ContainerManagerComponent> _containerManagerQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<CargoBountyLabelComponent> _cargoBountyLabelQuery = default!;
|
||||||
|
|
||||||
private EntityQuery<StackComponent> _stackQuery;
|
private static readonly ProtoId<NameIdentifierGroupPrototype> BountyNameIdentifierGroup = "Bounty";
|
||||||
private EntityQuery<ContainerManagerComponent> _containerQuery;
|
|
||||||
private EntityQuery<CargoBountyLabelComponent> _bountyLabelQuery;
|
|
||||||
|
|
||||||
private void InitializeBounty()
|
private void InitializeBounty()
|
||||||
{
|
{
|
||||||
@@ -42,10 +41,6 @@ public sealed partial class CargoSystem
|
|||||||
SubscribeLocalEvent<CargoBountyLabelComponent, PriceCalculationEvent>(OnGetBountyPrice);
|
SubscribeLocalEvent<CargoBountyLabelComponent, PriceCalculationEvent>(OnGetBountyPrice);
|
||||||
SubscribeLocalEvent<EntitySoldEvent>(OnSold);
|
SubscribeLocalEvent<EntitySoldEvent>(OnSold);
|
||||||
SubscribeLocalEvent<StationCargoBountyDatabaseComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<StationCargoBountyDatabaseComponent, MapInitEvent>(OnMapInit);
|
||||||
|
|
||||||
_stackQuery = GetEntityQuery<StackComponent>();
|
|
||||||
_containerQuery = GetEntityQuery<ContainerManagerComponent>();
|
|
||||||
_bountyLabelQuery = GetEntityQuery<CargoBountyLabelComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBountyConsoleOpened(EntityUid uid, CargoBountyConsoleComponent component, BoundUIOpenedEvent args)
|
private void OnBountyConsoleOpened(EntityUid uid, CargoBountyConsoleComponent component, BoundUIOpenedEvent args)
|
||||||
@@ -196,7 +191,7 @@ public sealed partial class CargoSystem
|
|||||||
{
|
{
|
||||||
labelEnt = null;
|
labelEnt = null;
|
||||||
labelComp = null;
|
labelComp = null;
|
||||||
if (!_containerQuery.TryGetComponent(uid, out var containerMan))
|
if (!_containerManagerQuery.TryGetComponent(uid, out var containerMan))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// make sure this label was actually applied to a crate.
|
// make sure this label was actually applied to a crate.
|
||||||
@@ -204,7 +199,7 @@ public sealed partial class CargoSystem
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (container.ContainedEntities.FirstOrNull() is not { } label ||
|
if (container.ContainedEntities.FirstOrNull() is not { } label ||
|
||||||
!_bountyLabelQuery.TryGetComponent(label, out var component))
|
!_cargoBountyLabelQuery.TryGetComponent(label, out var component))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
labelEnt = label;
|
labelEnt = label;
|
||||||
@@ -377,7 +372,7 @@ public sealed partial class CargoSystem
|
|||||||
{
|
{
|
||||||
foreach (var ent in container.ContainedEntities)
|
foreach (var ent in container.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (_bountyLabelQuery.HasComponent(ent))
|
if (_cargoBountyLabelQuery.HasComponent(ent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var children = GetBountyEntities(ent);
|
var children = GetBountyEntities(ent);
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
{
|
{
|
||||||
foreach (var gridUid in data.Grids)
|
foreach (var gridUid in data.Grids)
|
||||||
{
|
{
|
||||||
if (!_tradeQuery.HasComponent(gridUid))
|
if (!_tradeStationQuery.HasComponent(gridUid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ents.Add(gridUid);
|
ents.Add(gridUid);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Content.Shared.Cargo.Components;
|
|||||||
using Content.Shared.Cargo.Events;
|
using Content.Shared.Cargo.Events;
|
||||||
using Content.Shared.Cargo.Prototypes;
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.HijackBeacon;
|
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
@@ -169,13 +168,13 @@ public sealed partial class CargoSystem
|
|||||||
// - anything anchored (e.g. light fixtures)
|
// - anything anchored (e.g. light fixtures)
|
||||||
// - anything blacklisted (e.g. players).
|
// - anything blacklisted (e.g. players).
|
||||||
if (toSell.Contains(ent) ||
|
if (toSell.Contains(ent) ||
|
||||||
_xformQuery.TryGetComponent(ent, out var xform) &&
|
TryComp(ent, out TransformComponent? xform) &&
|
||||||
(xform.Anchored || !CanSell(ent, xform)))
|
(xform.Anchored || !CanSell(ent)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_blacklistQuery.HasComponent(ent))
|
if (_cargoSellBlacklistQuery.HasComponent(ent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var price = _pricing.GetPrice(ent);
|
var price = _pricing.GetPrice(ent);
|
||||||
@@ -187,9 +186,9 @@ public sealed partial class CargoSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanSell(EntityUid uid, TransformComponent xform)
|
private bool CanSell(EntityUid uid)
|
||||||
{
|
{
|
||||||
if (_mobQuery.HasComponent(uid))
|
if (_mobStateQuery.HasComponent(uid))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -197,13 +196,14 @@ public sealed partial class CargoSystem
|
|||||||
var complete = IsBountyComplete(uid, out var bountyEntities);
|
var complete = IsBountyComplete(uid, out var bountyEntities);
|
||||||
|
|
||||||
// Recursively check for mobs at any point.
|
// Recursively check for mobs at any point.
|
||||||
|
var xform = Transform(uid);
|
||||||
var children = xform.ChildEnumerator;
|
var children = xform.ChildEnumerator;
|
||||||
while (children.MoveNext(out var child))
|
while (children.MoveNext(out var child))
|
||||||
{
|
{
|
||||||
if (complete && bountyEntities.Contains(child))
|
if (complete && bountyEntities.Contains(child))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!CanSell(child, _xformQuery.GetComponent(child)))
|
if (!CanSell(child))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,10 +42,9 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
[Dependency] private RadioSystem _radio = default!;
|
[Dependency] private RadioSystem _radio = default!;
|
||||||
[Dependency] private IdentitySystem _identity = default!;
|
[Dependency] private IdentitySystem _identity = default!;
|
||||||
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
[Dependency] private EntityQuery<CargoSellBlacklistComponent> _cargoSellBlacklistQuery = default!;
|
||||||
private EntityQuery<CargoSellBlacklistComponent> _blacklistQuery;
|
[Dependency] private EntityQuery<MobStateComponent> _mobStateQuery = default!;
|
||||||
private EntityQuery<MobStateComponent> _mobQuery;
|
[Dependency] private EntityQuery<TradeStationComponent> _tradeStationQuery = default!;
|
||||||
private EntityQuery<TradeStationComponent> _tradeQuery;
|
|
||||||
|
|
||||||
private HashSet<EntityUid> _setEnts = new();
|
private HashSet<EntityUid> _setEnts = new();
|
||||||
private List<EntityUid> _listEnts = new();
|
private List<EntityUid> _listEnts = new();
|
||||||
@@ -54,12 +53,6 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
_blacklistQuery = GetEntityQuery<CargoSellBlacklistComponent>();
|
|
||||||
_mobQuery = GetEntityQuery<MobStateComponent>();
|
|
||||||
_tradeQuery = GetEntityQuery<TradeStationComponent>();
|
|
||||||
|
|
||||||
InitializeConsole();
|
InitializeConsole();
|
||||||
InitializeShuttle();
|
InitializeShuttle();
|
||||||
InitializeTelepad();
|
InitializeTelepad();
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public sealed partial class SuicideSystem : EntitySystem
|
|||||||
[Dependency] private SharedPopupSystem _popup = default!;
|
[Dependency] private SharedPopupSystem _popup = default!;
|
||||||
[Dependency] private GhostSystem _ghostSystem = default!;
|
[Dependency] private GhostSystem _ghostSystem = default!;
|
||||||
[Dependency] private SharedSuicideSystem _suicide = default!;
|
[Dependency] private SharedSuicideSystem _suicide = default!;
|
||||||
|
[Dependency] private EntityQuery<ItemComponent> _itemQuery = default!;
|
||||||
|
|
||||||
private static readonly ProtoId<TagPrototype> CannotSuicideTag = "CannotSuicide";
|
private static readonly ProtoId<TagPrototype> CannotSuicideTag = "CannotSuicide";
|
||||||
|
|
||||||
@@ -132,11 +133,10 @@ public sealed partial class SuicideSystem : EntitySystem
|
|||||||
|
|
||||||
// Try to suicide by nearby entities, like Microwaves or Crematoriums, by raising an event on it
|
// Try to suicide by nearby entities, like Microwaves or Crematoriums, by raising an event on it
|
||||||
// Returns upon being handled by any entity
|
// Returns upon being handled by any entity
|
||||||
var itemQuery = GetEntityQuery<ItemComponent>();
|
|
||||||
foreach (var entity in _entityLookupSystem.GetEntitiesInRange(victim, 1, LookupFlags.Approximate | LookupFlags.Static))
|
foreach (var entity in _entityLookupSystem.GetEntitiesInRange(victim, 1, LookupFlags.Approximate | LookupFlags.Static))
|
||||||
{
|
{
|
||||||
// Skip any nearby items that can be picked up, we already checked the active held item above
|
// Skip any nearby items that can be picked up, we already checked the active held item above
|
||||||
if (itemQuery.HasComponent(entity))
|
if (_itemQuery.HasComponent(entity))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RaiseLocalEvent(entity, suicideByEnvironmentEvent);
|
RaiseLocalEvent(entity, suicideByEnvironmentEvent);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ using Content.Shared.Players;
|
|||||||
using Content.Shared.Players.RateLimiting;
|
using Content.Shared.Players.RateLimiting;
|
||||||
using Content.Shared.Radio;
|
using Content.Shared.Radio;
|
||||||
using Content.Shared.Station.Components;
|
using Content.Shared.Station.Components;
|
||||||
using Content.Shared.Whitelist;
|
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
@@ -58,6 +57,7 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
[Dependency] private SharedAudioSystem _audio = default!;
|
[Dependency] private SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private ReplacementAccentSystem _wordreplacement = default!;
|
[Dependency] private ReplacementAccentSystem _wordreplacement = default!;
|
||||||
[Dependency] private ExamineSystemShared _examineSystem = default!;
|
[Dependency] private ExamineSystemShared _examineSystem = default!;
|
||||||
|
[Dependency] private EntityQuery<GhostHearingComponent> _ghostHearingQuery = default!;
|
||||||
|
|
||||||
// Corvax-TTS-Start: Moved from Server to Shared
|
// Corvax-TTS-Start: Moved from Server to Shared
|
||||||
// public const int VoiceRange = 10; // how far voice goes in world units
|
// public const int VoiceRange = 10; // how far voice goes in world units
|
||||||
@@ -801,10 +801,8 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
// TODO proper speech occlusion
|
// TODO proper speech occlusion
|
||||||
|
|
||||||
var recipients = new Dictionary<ICommonSession, ICChatRecipientData>();
|
var recipients = new Dictionary<ICommonSession, ICChatRecipientData>();
|
||||||
var ghostHearing = GetEntityQuery<GhostHearingComponent>();
|
|
||||||
var xforms = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
var transformSource = xforms.GetComponent(source);
|
var transformSource = Transform(source);
|
||||||
var sourceMapId = transformSource.MapID;
|
var sourceMapId = transformSource.MapID;
|
||||||
var sourceCoords = transformSource.Coordinates;
|
var sourceCoords = transformSource.Coordinates;
|
||||||
|
|
||||||
@@ -813,12 +811,12 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||||||
if (player.AttachedEntity is not { Valid: true } playerEntity)
|
if (player.AttachedEntity is not { Valid: true } playerEntity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var transformEntity = xforms.GetComponent(playerEntity);
|
var transformEntity = Transform(playerEntity);
|
||||||
|
|
||||||
if (transformEntity.MapID != sourceMapId)
|
if (transformEntity.MapID != sourceMapId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var observer = ghostHearing.HasComponent(playerEntity);
|
var observer = _ghostHearingQuery.HasComponent(playerEntity);
|
||||||
|
|
||||||
// even if they are a ghost hearer, in some situations we still need the range
|
// even if they are a ghost hearer, in some situations we still need the range
|
||||||
if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceGetRange)
|
if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceGetRange)
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ public sealed partial class CleanTileReaction : ITileReaction
|
|||||||
FixedPoint2 ITileReaction.TileReact(TileRef tile,
|
FixedPoint2 ITileReaction.TileReact(TileRef tile,
|
||||||
ReagentPrototype reagent,
|
ReagentPrototype reagent,
|
||||||
FixedPoint2 reactVolume,
|
FixedPoint2 reactVolume,
|
||||||
IEntityManager entityManager
|
IEntityManager entityManager,
|
||||||
, List<ReagentData>? data)
|
List<ReagentData>? data)
|
||||||
{
|
{
|
||||||
var entities = entityManager.System<EntityLookupSystem>().GetLocalEntitiesIntersecting(tile, 0f).ToArray();
|
var entities = entityManager.System<EntityLookupSystem>().GetLocalEntitiesIntersecting(tile, 0f).ToArray();
|
||||||
var puddleQuery = entityManager.GetEntityQuery<PuddleComponent>();
|
var puddleQuery = entityManager.GetEntityQuery<PuddleComponent>();
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.Linq;
|
|
||||||
using Content.Shared.Decals;
|
|
||||||
using Microsoft.Extensions.ObjectPool;
|
using Microsoft.Extensions.ObjectPool;
|
||||||
using Robust.Shared;
|
using Robust.Shared;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
@@ -22,14 +20,11 @@ public sealed partial class ChunkingSystem : EntitySystem
|
|||||||
[Dependency] private IMapManager _mapManager = default!;
|
[Dependency] private IMapManager _mapManager = default!;
|
||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
|
|
||||||
private Box2 _baseViewBounds;
|
private Box2 _baseViewBounds;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
Subs.CVar(_configurationManager, CVars.NetMaxUpdateRange, OnPvsRangeChanged, true);
|
Subs.CVar(_configurationManager, CVars.NetMaxUpdateRange, OnPvsRangeChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +62,7 @@ public sealed partial class ChunkingSystem : EntitySystem
|
|||||||
int chunkSize,
|
int chunkSize,
|
||||||
float viewEnlargement)
|
float viewEnlargement)
|
||||||
{
|
{
|
||||||
if (!_xformQuery.TryGetComponent(viewer, out var xform))
|
if (!TryComp(viewer, out TransformComponent? xform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var pos = _transform.GetWorldPosition(xform);
|
var pos = _transform.GetWorldPosition(xform);
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ namespace Content.Server.Construction.Conditions
|
|||||||
var examineName = constructionSys.GetExamineName(info);
|
var examineName = constructionSys.GetExamineName(info);
|
||||||
args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
|
args.PushMarkup(Loc.GetString("construction-condition-machine-frame-required-element-entry",
|
||||||
("amount", info.Amount),
|
("amount", info.Amount),
|
||||||
("elementName", examineName))
|
("elementName", examineName)));
|
||||||
+ "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Content.Server.DeviceLinking.Components;
|
using Content.Server.DeviceLinking.Components;
|
||||||
using Content.Server.NodeContainer;
|
|
||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.Power.Nodes;
|
using Content.Server.Power.Nodes;
|
||||||
using Content.Server.Power.NodeGroups;
|
using Content.Server.Power.NodeGroups;
|
||||||
@@ -26,16 +25,10 @@ public sealed partial class PowerSensorSystem : EntitySystem
|
|||||||
[Dependency] private SharedToolSystem _tool = default!;
|
[Dependency] private SharedToolSystem _tool = default!;
|
||||||
[Dependency] private UseDelaySystem _useDelay = default!;
|
[Dependency] private UseDelaySystem _useDelay = default!;
|
||||||
|
|
||||||
private EntityQuery<NodeContainerComponent> _nodeQuery;
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_nodeQuery = GetEntityQuery<NodeContainerComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<PowerSensorComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<PowerSensorComponent, ComponentInit>(OnInit);
|
||||||
SubscribeLocalEvent<PowerSensorComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<PowerSensorComponent, ExaminedEvent>(OnExamined);
|
||||||
SubscribeLocalEvent<PowerSensorComponent, InteractUsingEvent>(OnInteractUsing);
|
SubscribeLocalEvent<PowerSensorComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
@@ -99,7 +92,7 @@ public sealed partial class PowerSensorSystem : EntitySystem
|
|||||||
var deviceNode = (CableDeviceNode) nodeContainer.Nodes[cable.Node];
|
var deviceNode = (CableDeviceNode) nodeContainer.Nodes[cable.Node];
|
||||||
|
|
||||||
// update state based on the power stats retrieved from the selected power network
|
// update state based on the power stats retrieved from the selected power network
|
||||||
var xform = _xformQuery.GetComponent(uid);
|
var xform = Transform(uid);
|
||||||
if (!TryComp(xform.GridUid, out MapGridComponent? grid))
|
if (!TryComp(xform.GridUid, out MapGridComponent? grid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace Content.Server.DeviceNetwork.Systems;
|
|||||||
public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
||||||
{
|
{
|
||||||
[Dependency] private NetworkConfiguratorSystem _configurator = default!;
|
[Dependency] private NetworkConfiguratorSystem _configurator = default!;
|
||||||
|
[Dependency] private EntityQuery<DeviceNetworkComponent> _deviceNetworkQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -28,10 +29,9 @@ public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
|||||||
_configurator.OnDeviceListShutdown(conf, (uid, component));
|
_configurator.OnDeviceListShutdown(conf, (uid, component));
|
||||||
}
|
}
|
||||||
|
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
foreach (var device in component.Devices)
|
foreach (var device in component.Devices)
|
||||||
{
|
{
|
||||||
if (query.TryGetComponent(device, out var comp))
|
if (_deviceNetworkQuery.TryGetComponent(device, out var comp))
|
||||||
comp.DeviceLists.Remove(uid);
|
comp.DeviceLists.Remove(uid);
|
||||||
}
|
}
|
||||||
component.Devices.Clear();
|
component.Devices.Clear();
|
||||||
@@ -125,7 +125,6 @@ public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
|||||||
private void OnMapSave(BeforeSerializationEvent ev)
|
private void OnMapSave(BeforeSerializationEvent ev)
|
||||||
{
|
{
|
||||||
List<EntityUid> toRemove = new();
|
List<EntityUid> toRemove = new();
|
||||||
var query = GetEntityQuery<TransformComponent>();
|
|
||||||
var enumerator = AllEntityQuery<DeviceListComponent, TransformComponent>();
|
var enumerator = AllEntityQuery<DeviceListComponent, TransformComponent>();
|
||||||
while (enumerator.MoveNext(out var uid, out var device, out var xform))
|
while (enumerator.MoveNext(out var uid, out var device, out var xform))
|
||||||
{
|
{
|
||||||
@@ -134,7 +133,7 @@ public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
|||||||
|
|
||||||
foreach (var ent in device.Devices)
|
foreach (var ent in device.Devices)
|
||||||
{
|
{
|
||||||
if (!query.TryGetComponent(ent, out var linkedXform))
|
if (!TryComp(ent, out TransformComponent? linkedXform))
|
||||||
{
|
{
|
||||||
// Entity was deleted.
|
// Entity was deleted.
|
||||||
// TODO remove these on deletion instead of on-save.
|
// TODO remove these on deletion instead of on-save.
|
||||||
@@ -190,7 +189,6 @@ public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
|||||||
return DeviceListUpdateResult.TooManyDevices;
|
return DeviceListUpdateResult.TooManyDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
var oldDevices = deviceList.Devices.ToList();
|
var oldDevices = deviceList.Devices.ToList();
|
||||||
foreach (var device in oldDevices)
|
foreach (var device in oldDevices)
|
||||||
{
|
{
|
||||||
@@ -198,13 +196,13 @@ public sealed partial class DeviceListSystem : SharedDeviceListSystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
deviceList.Devices.Remove(device);
|
deviceList.Devices.Remove(device);
|
||||||
if (query.TryGetComponent(device, out var comp))
|
if (_deviceNetworkQuery.TryGetComponent(device, out var comp))
|
||||||
comp.DeviceLists.Remove(uid);
|
comp.DeviceLists.Remove(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var device in newDevices)
|
foreach (var device in newDevices)
|
||||||
{
|
{
|
||||||
if (!query.TryGetComponent(device, out var comp))
|
if (!_deviceNetworkQuery.TryGetComponent(device, out var comp))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!deviceList.Devices.Add(device))
|
if (!deviceList.Devices.Add(device))
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public sealed partial class NetworkConfiguratorSystem : SharedNetworkConfigurato
|
|||||||
[Dependency] private SharedAppearanceSystem _appearanceSystem = default!;
|
[Dependency] private SharedAppearanceSystem _appearanceSystem = default!;
|
||||||
[Dependency] private IGameTiming _gameTiming = default!;
|
[Dependency] private IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private IAdminLogManager _adminLogger = default!;
|
[Dependency] private IAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private EntityQuery<DeviceNetworkComponent> _deviceNetworkQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -632,10 +633,9 @@ public sealed partial class NetworkConfiguratorSystem : SharedNetworkConfigurato
|
|||||||
|
|
||||||
private void ClearDevices(EntityUid uid, NetworkConfiguratorComponent component)
|
private void ClearDevices(EntityUid uid, NetworkConfiguratorComponent component)
|
||||||
{
|
{
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
foreach (var device in component.Devices.Values)
|
foreach (var device in component.Devices.Values)
|
||||||
{
|
{
|
||||||
if (query.TryGetComponent(device, out var comp))
|
if (_deviceNetworkQuery.TryGetComponent(device, out var comp))
|
||||||
comp.Configurators.Remove(uid);
|
comp.Configurators.Remove(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,10 +794,9 @@ public sealed partial class NetworkConfiguratorSystem : SharedNetworkConfigurato
|
|||||||
|
|
||||||
ClearDevices(uid, component);
|
ClearDevices(uid, component);
|
||||||
|
|
||||||
var query = GetEntityQuery<DeviceNetworkComponent>();
|
|
||||||
foreach (var (addr, device) in _deviceListSystem.GetDeviceList(component.ActiveDeviceList.Value))
|
foreach (var (addr, device) in _deviceListSystem.GetDeviceList(component.ActiveDeviceList.Value))
|
||||||
{
|
{
|
||||||
if (query.TryGetComponent(device, out var comp))
|
if (_deviceNetworkQuery.TryGetComponent(device, out var comp))
|
||||||
{
|
{
|
||||||
component.Devices.Add(addr, device);
|
component.Devices.Add(addr, device);
|
||||||
comp.Configurators.Add(uid);
|
comp.Configurators.Add(uid);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Content.Server.Atmos.Components;
|
|||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Atmos.Monitor.Components;
|
using Content.Server.Atmos.Monitor.Components;
|
||||||
using Content.Server.Atmos.Monitor.Systems;
|
using Content.Server.Atmos.Monitor.Systems;
|
||||||
using Content.Server.Power.Components;
|
|
||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.Shuttles.Components;
|
using Content.Server.Shuttles.Components;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
@@ -24,7 +23,10 @@ namespace Content.Server.Doors.Systems
|
|||||||
[Dependency] private SharedMapSystem _mapping = default!;
|
[Dependency] private SharedMapSystem _mapping = default!;
|
||||||
[Dependency] private PointLightSystem _pointLight = default!;
|
[Dependency] private PointLightSystem _pointLight = default!;
|
||||||
|
|
||||||
private EntityQuery<AtmosAlarmableComponent> _atmosAlarmQuery;
|
[Dependency] private EntityQuery<AtmosAlarmableComponent> _atmosAlarmQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<AirtightComponent> _airtightQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<AppearanceComponent> _appearanceQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<PointLightComponent> _pointLightQuery = default!;
|
||||||
|
|
||||||
private const int UpdateInterval = 30;
|
private const int UpdateInterval = 30;
|
||||||
private int _accumulatedTicks;
|
private int _accumulatedTicks;
|
||||||
@@ -35,8 +37,6 @@ namespace Content.Server.Doors.Systems
|
|||||||
|
|
||||||
SubscribeLocalEvent<FirelockComponent, AtmosAlarmEvent>(OnAtmosAlarm);
|
SubscribeLocalEvent<FirelockComponent, AtmosAlarmEvent>(OnAtmosAlarm);
|
||||||
SubscribeLocalEvent<FirelockComponent, PowerChangedEvent>(PowerChanged);
|
SubscribeLocalEvent<FirelockComponent, PowerChangedEvent>(PowerChanged);
|
||||||
|
|
||||||
_atmosAlarmQuery = GetEntityQuery<AtmosAlarmableComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PowerChanged(EntityUid uid, FirelockComponent component, ref PowerChangedEvent args)
|
private void PowerChanged(EntityUid uid, FirelockComponent component, ref PowerChangedEvent args)
|
||||||
@@ -53,10 +53,6 @@ namespace Content.Server.Doors.Systems
|
|||||||
|
|
||||||
_accumulatedTicks = 0;
|
_accumulatedTicks = 0;
|
||||||
|
|
||||||
var airtightQuery = GetEntityQuery<AirtightComponent>();
|
|
||||||
var appearanceQuery = GetEntityQuery<AppearanceComponent>();
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
var pointLightQuery = GetEntityQuery<PointLightComponent>();
|
|
||||||
|
|
||||||
var query = EntityQueryEnumerator<FirelockComponent, DoorComponent>();
|
var query = EntityQueryEnumerator<FirelockComponent, DoorComponent>();
|
||||||
while (query.MoveNext(out var uid, out var firelock, out var door))
|
while (query.MoveNext(out var uid, out var firelock, out var door))
|
||||||
@@ -77,11 +73,10 @@ namespace Content.Server.Doors.Systems
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (airtightQuery.TryGetComponent(uid, out var airtight)
|
if (_airtightQuery.TryGetComponent(uid, out var airtight)
|
||||||
&& xformQuery.TryGetComponent(uid, out var xform)
|
&& _appearanceQuery.TryGetComponent(uid, out var appearance))
|
||||||
&& appearanceQuery.TryGetComponent(uid, out var appearance))
|
|
||||||
{
|
{
|
||||||
var (pressure, fire) = CheckPressureAndFire(uid, firelock, xform, airtight, airtightQuery);
|
var (pressure, fire) = CheckPressureAndFire(uid, firelock, airtight);
|
||||||
_appearance.SetData(uid, DoorVisuals.ClosedLights, fire || pressure, appearance);
|
_appearance.SetData(uid, DoorVisuals.ClosedLights, fire || pressure, appearance);
|
||||||
firelock.Temperature = fire;
|
firelock.Temperature = fire;
|
||||||
firelock.Pressure = pressure;
|
firelock.Pressure = pressure;
|
||||||
@@ -89,7 +84,7 @@ namespace Content.Server.Doors.Systems
|
|||||||
_appearance.SetData(uid, FirelockVisuals.TemperatureWarning, fire, appearance);
|
_appearance.SetData(uid, FirelockVisuals.TemperatureWarning, fire, appearance);
|
||||||
Dirty(uid, firelock);
|
Dirty(uid, firelock);
|
||||||
|
|
||||||
if (pointLightQuery.TryComp(uid, out var pointLight))
|
if (_pointLightQuery.TryComp(uid, out var pointLight))
|
||||||
{
|
{
|
||||||
_pointLight.SetEnabled(uid, fire | pressure, pointLight);
|
_pointLight.SetEnabled(uid, fire | pressure, pointLight);
|
||||||
}
|
}
|
||||||
@@ -118,18 +113,15 @@ namespace Content.Server.Doors.Systems
|
|||||||
|
|
||||||
public (bool Pressure, bool Fire) CheckPressureAndFire(EntityUid uid, FirelockComponent firelock)
|
public (bool Pressure, bool Fire) CheckPressureAndFire(EntityUid uid, FirelockComponent firelock)
|
||||||
{
|
{
|
||||||
var query = GetEntityQuery<AirtightComponent>();
|
if (_airtightQuery.TryGetComponent(uid, out AirtightComponent? airtight))
|
||||||
if (query.TryGetComponent(uid, out AirtightComponent? airtight))
|
return CheckPressureAndFire(uid, firelock, airtight);
|
||||||
return CheckPressureAndFire(uid, firelock, Transform(uid), airtight, query);
|
|
||||||
return (false, false);
|
return (false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public (bool Pressure, bool Fire) CheckPressureAndFire(
|
public (bool Pressure, bool Fire) CheckPressureAndFire(
|
||||||
EntityUid uid,
|
EntityUid uid,
|
||||||
FirelockComponent firelock,
|
FirelockComponent firelock,
|
||||||
TransformComponent xform,
|
AirtightComponent airtight)
|
||||||
AirtightComponent airtight,
|
|
||||||
EntityQuery<AirtightComponent> airtightQuery)
|
|
||||||
{
|
{
|
||||||
if (!airtight.AirBlocked)
|
if (!airtight.AirBlocked)
|
||||||
return (false, false);
|
return (false, false);
|
||||||
@@ -140,6 +132,7 @@ namespace Content.Server.Doors.Systems
|
|||||||
return (false, false);
|
return (false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xform = Transform(uid);
|
||||||
if (!HasComp<GridAtmosphereComponent>(xform.ParentUid))
|
if (!HasComp<GridAtmosphereComponent>(xform.ParentUid))
|
||||||
return (false, false);
|
return (false, false);
|
||||||
|
|
||||||
@@ -190,7 +183,7 @@ namespace Content.Server.Doors.Systems
|
|||||||
{
|
{
|
||||||
// Is there some airtight entity blocking this direction? If yes, don't include this direction in the
|
// Is there some airtight entity blocking this direction? If yes, don't include this direction in the
|
||||||
// pressure differential
|
// pressure differential
|
||||||
if (HasAirtightBlocker(_mapping.GetAnchoredEntities(xform.ParentUid, grid, adjacentPos), dir.GetOpposite(), airtightQuery))
|
if (HasAirtightBlocker(_mapping.GetAnchoredEntities(xform.ParentUid, grid, adjacentPos), dir.GetOpposite()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var p = gas.Pressure;
|
var p = gas.Pressure;
|
||||||
@@ -233,11 +226,11 @@ namespace Content.Server.Doors.Systems
|
|||||||
return (holdingPressure, holdingFire);
|
return (holdingPressure, holdingFire);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasAirtightBlocker(IEnumerable<EntityUid> enumerable, AtmosDirection dir, EntityQuery<AirtightComponent> airtightQuery)
|
private bool HasAirtightBlocker(IEnumerable<EntityUid> enumerable, AtmosDirection dir)
|
||||||
{
|
{
|
||||||
foreach (var ent in enumerable)
|
foreach (var ent in enumerable)
|
||||||
{
|
{
|
||||||
if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked)
|
if (!_airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((airtight.AirBlockedDirection & dir) == dir)
|
if ((airtight.AirBlockedDirection & dir) == dir)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using Content.Shared.Dragon;
|
|||||||
using Content.Shared.Gibbing;
|
using Content.Shared.Gibbing;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
using Content.Shared.Mind;
|
using Content.Shared.Mind;
|
||||||
using Content.Shared.Mind.Components;
|
|
||||||
using Content.Shared.Mobs;
|
using Content.Shared.Mobs;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
@@ -36,7 +35,7 @@ public sealed partial class DragonSystem : EntitySystem
|
|||||||
[Dependency] private GibbingSystem _gibbing = default!;
|
[Dependency] private GibbingSystem _gibbing = default!;
|
||||||
[Dependency] private SmokeSystem _smoke = default!;
|
[Dependency] private SmokeSystem _smoke = default!;
|
||||||
|
|
||||||
private EntityQuery<CarpRiftsConditionComponent> _objQuery;
|
[Dependency] private EntityQuery<CarpRiftsConditionComponent> _carpRiftsConditionQuery = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum distance between 2 rifts allowed.
|
/// Minimum distance between 2 rifts allowed.
|
||||||
@@ -54,8 +53,6 @@ public sealed partial class DragonSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_objQuery = GetEntityQuery<CarpRiftsConditionComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<DragonComponent, MapInitEvent>(OnInit);
|
SubscribeLocalEvent<DragonComponent, MapInitEvent>(OnInit);
|
||||||
SubscribeLocalEvent<DragonComponent, ComponentShutdown>(OnShutdown);
|
SubscribeLocalEvent<DragonComponent, ComponentShutdown>(OnShutdown);
|
||||||
SubscribeLocalEvent<DragonComponent, DragonSpawnRiftActionEvent>(OnSpawnRift);
|
SubscribeLocalEvent<DragonComponent, DragonSpawnRiftActionEvent>(OnSpawnRift);
|
||||||
@@ -244,7 +241,7 @@ public sealed partial class DragonSystem : EntitySystem
|
|||||||
|
|
||||||
foreach (var objId in mind.Objectives)
|
foreach (var objId in mind.Objectives)
|
||||||
{
|
{
|
||||||
if (_objQuery.TryGetComponent(objId, out var obj))
|
if (_carpRiftsConditionQuery.TryGetComponent(objId, out var obj))
|
||||||
{
|
{
|
||||||
_carpRifts.ResetRifts(objId, obj);
|
_carpRifts.ResetRifts(objId, obj);
|
||||||
break;
|
break;
|
||||||
@@ -265,7 +262,7 @@ public sealed partial class DragonSystem : EntitySystem
|
|||||||
|
|
||||||
foreach (var objId in mind.Objectives)
|
foreach (var objId in mind.Objectives)
|
||||||
{
|
{
|
||||||
if (_objQuery.TryGetComponent(objId, out var obj))
|
if (_carpRiftsConditionQuery.TryGetComponent(objId, out var obj))
|
||||||
{
|
{
|
||||||
_carpRifts.RiftCharged(objId, obj);
|
_carpRifts.RiftCharged(objId, obj);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Explosion;
|
|
||||||
using Content.Shared.Explosion.Components;
|
using Content.Shared.Explosion.Components;
|
||||||
using Content.Shared.Explosion.EntitySystems;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
|
|
||||||
@@ -102,9 +100,8 @@ public sealed partial class ExplosionSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xforms = GetEntityQuery<TransformComponent>();
|
var xform = Transform(gridToTransform);
|
||||||
var xform = xforms.GetComponent(gridToTransform);
|
var (_, gridWorldRotation, gridWorldMatrix, invGridWorldMatrid) = _transformSystem.GetWorldPositionRotationMatrixWithInv(xform);
|
||||||
var (_, gridWorldRotation, gridWorldMatrix, invGridWorldMatrid) = _transformSystem.GetWorldPositionRotationMatrixWithInv(xform, xforms);
|
|
||||||
|
|
||||||
var localEpicentre = (Vector2i) Vector2.Transform(epicentre.Position, invGridWorldMatrid);
|
var localEpicentre = (Vector2i) Vector2.Transform(epicentre.Position, invGridWorldMatrid);
|
||||||
var matrix = offsetMatrix * gridWorldMatrix * targetMatrix;
|
var matrix = offsetMatrix * gridWorldMatrix * targetMatrix;
|
||||||
|
|||||||
@@ -681,13 +681,6 @@ sealed class Explosion
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<Entity<MapGridComponent>, List<(Vector2i, Tile)>> _tileUpdateDict = new();
|
private readonly Dictionary<Entity<MapGridComponent>, List<(Vector2i, Tile)>> _tileUpdateDict = new();
|
||||||
|
|
||||||
// Entity Queries
|
|
||||||
private readonly EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
private readonly EntityQuery<PhysicsComponent> _physicsQuery;
|
|
||||||
private readonly EntityQuery<DamageableComponent> _damageQuery;
|
|
||||||
private readonly EntityQuery<ProjectileComponent> _projectileQuery;
|
|
||||||
private readonly EntityQuery<TagComponent> _tagQuery;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total area that the explosion covers.
|
/// Total area that the explosion covers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -753,12 +746,6 @@ sealed class Explosion
|
|||||||
_entMan = entMan;
|
_entMan = entMan;
|
||||||
_damageable = damageable;
|
_damageable = damageable;
|
||||||
|
|
||||||
_xformQuery = entMan.GetEntityQuery<TransformComponent>();
|
|
||||||
_physicsQuery = entMan.GetEntityQuery<PhysicsComponent>();
|
|
||||||
_damageQuery = entMan.GetEntityQuery<DamageableComponent>();
|
|
||||||
_tagQuery = entMan.GetEntityQuery<TagComponent>();
|
|
||||||
_projectileQuery = entMan.GetEntityQuery<ProjectileComponent>();
|
|
||||||
|
|
||||||
if (spaceData != null)
|
if (spaceData != null)
|
||||||
{
|
{
|
||||||
var mapUid = mapSystem.GetMap(epicenter.MapId);
|
var mapUid = mapSystem.GetMap(epicenter.MapId);
|
||||||
|
|||||||
@@ -59,15 +59,14 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||||||
[Dependency] private DestructibleSystem _destructibleSystem = default!;
|
[Dependency] private DestructibleSystem _destructibleSystem = default!;
|
||||||
[Dependency] private AtmosphereSystem _atmosphere = default!;
|
[Dependency] private AtmosphereSystem _atmosphere = default!;
|
||||||
|
|
||||||
private EntityQuery<FlammableComponent> _flammableQuery;
|
[Dependency] private EntityQuery<FlammableComponent> _flammableQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
private EntityQuery<ProjectileComponent> _projectileQuery;
|
[Dependency] private EntityQuery<ActorComponent> _actorQuery = default!;
|
||||||
private EntityQuery<ActorComponent> _actorQuery;
|
[Dependency] private EntityQuery<DestructibleComponent> _destructibleQuery = default!;
|
||||||
private EntityQuery<DestructibleComponent> _destructibleQuery;
|
[Dependency] private EntityQuery<DamageableComponent> _damageableQuery = default!;
|
||||||
private EntityQuery<DamageableComponent> _damageableQuery;
|
|
||||||
[Dependency] private EntityQuery<InjurableComponent> _injurableQuery = default!;
|
[Dependency] private EntityQuery<InjurableComponent> _injurableQuery = default!;
|
||||||
private EntityQuery<AirtightComponent> _airtightQuery;
|
[Dependency] private EntityQuery<AirtightComponent> _airtightQuery = default!;
|
||||||
private EntityQuery<TileHistoryComponent> _tileHistoryQuery;
|
[Dependency] private EntityQuery<TileHistoryComponent> _tileHistoryQuery = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Tile-size" for space when there are no nearby grids to use as a reference.
|
/// "Tile-size" for space when there are no nearby grids to use as a reference.
|
||||||
@@ -103,15 +102,6 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||||||
InitAirtightMap();
|
InitAirtightMap();
|
||||||
InitVisuals();
|
InitVisuals();
|
||||||
|
|
||||||
_flammableQuery = GetEntityQuery<FlammableComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
_projectileQuery = GetEntityQuery<ProjectileComponent>();
|
|
||||||
_actorQuery = GetEntityQuery<ActorComponent>();
|
|
||||||
_destructibleQuery = GetEntityQuery<DestructibleComponent>();
|
|
||||||
_damageableQuery = GetEntityQuery<DamageableComponent>();
|
|
||||||
_airtightQuery = GetEntityQuery<AirtightComponent>();
|
|
||||||
_tileHistoryQuery = GetEntityQuery<TileHistoryComponent>();
|
|
||||||
|
|
||||||
_prototypeManager.PrototypesReloaded += ReloadExplosionPrototypes;
|
_prototypeManager.PrototypesReloaded += ReloadExplosionPrototypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
|||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
[Dependency] private TurfSystem _turf = default!;
|
[Dependency] private TurfSystem _turf = default!;
|
||||||
|
|
||||||
private EntityQuery<PuddleComponent> _puddleQuery;
|
[Dependency] private EntityQuery<PuddleComponent> _puddleQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<EvaporationSparkleComponent> _evaporationSparklesQuery = default!;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Need some sort of way to do blood slash / vomit solution spill on its own
|
* TODO: Need some sort of way to do blood slash / vomit solution spill on its own
|
||||||
@@ -49,8 +50,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_puddleQuery = GetEntityQuery<PuddleComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<PuddleComponent, SpreadNeighborsEvent>(OnPuddleSpread);
|
SubscribeLocalEvent<PuddleComponent, SpreadNeighborsEvent>(OnPuddleSpread);
|
||||||
SubscribeLocalEvent<PuddleComponent, SlipEvent>(OnPuddleSlip);
|
SubscribeLocalEvent<PuddleComponent, SlipEvent>(OnPuddleSlip);
|
||||||
}
|
}
|
||||||
@@ -151,7 +150,7 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is nothing left to overflow from our tile, then we'll stop this tile being a active spreader
|
// If there is nothing left to overflow from our tile, then we'll stop this tile being an active spreader
|
||||||
if (overflow.Volume == FixedPoint2.Zero)
|
if (overflow.Volume == FixedPoint2.Zero)
|
||||||
{
|
{
|
||||||
RemCompDeferred<ActiveEdgeSpreaderComponent>(entity);
|
RemCompDeferred<ActiveEdgeSpreaderComponent>(entity);
|
||||||
@@ -517,19 +516,17 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
|||||||
// Get normalized co-ordinate for spill location and spill it in the centre
|
// Get normalized co-ordinate for spill location and spill it in the centre
|
||||||
// TODO: Does SnapGrid or something else already do this?
|
// TODO: Does SnapGrid or something else already do this?
|
||||||
var anchored = _map.GetAnchoredEntitiesEnumerator(gridId, mapGrid, tileRef.GridIndices);
|
var anchored = _map.GetAnchoredEntitiesEnumerator(gridId, mapGrid, tileRef.GridIndices);
|
||||||
var puddleQuery = GetEntityQuery<PuddleComponent>();
|
|
||||||
var sparklesQuery = GetEntityQuery<EvaporationSparkleComponent>();
|
|
||||||
|
|
||||||
while (anchored.MoveNext(out var ent))
|
while (anchored.MoveNext(out var ent))
|
||||||
{
|
{
|
||||||
// If there's existing sparkles then delete it
|
// If there's existing sparkles then delete it
|
||||||
if (sparklesQuery.TryGetComponent(ent, out var sparkles))
|
if (_evaporationSparklesQuery.TryGetComponent(ent, out var sparkles))
|
||||||
{
|
{
|
||||||
QueueDel(ent.Value);
|
QueueDel(ent.Value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!puddleQuery.TryGetComponent(ent, out var puddle))
|
if (!_puddleQuery.TryGetComponent(ent, out var puddle))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TryAddSolution(ent.Value, solution, sound, puddleComponent: puddle))
|
if (TryAddSolution(ent.Value, solution, sound, puddleComponent: puddle))
|
||||||
@@ -565,11 +562,9 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var anc = _map.GetAnchoredEntitiesEnumerator(tile.GridUid, grid, tile.GridIndices);
|
var anc = _map.GetAnchoredEntitiesEnumerator(tile.GridUid, grid, tile.GridIndices);
|
||||||
var puddleQuery = GetEntityQuery<PuddleComponent>();
|
|
||||||
|
|
||||||
while (anc.MoveNext(out var ent))
|
while (anc.MoveNext(out var ent))
|
||||||
{
|
{
|
||||||
if (!puddleQuery.HasComponent(ent.Value))
|
if (!_puddleQuery.HasComponent(ent.Value))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
puddleUid = ent.Value;
|
puddleUid = ent.Value;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Body.Systems;
|
using Content.Server.Body.Systems;
|
||||||
using Content.Shared.EntityEffects.Effects;
|
|
||||||
using Content.Server.Spreader;
|
using Content.Server.Spreader;
|
||||||
using Content.Shared.Body.Components;
|
using Content.Shared.Body.Components;
|
||||||
using Content.Shared.Chemistry;
|
using Content.Shared.Chemistry;
|
||||||
@@ -45,17 +44,14 @@ public sealed partial class SmokeSystem : EntitySystem
|
|||||||
[Dependency] private SharedPhysicsSystem _physics = default!;
|
[Dependency] private SharedPhysicsSystem _physics = default!;
|
||||||
[Dependency] private SharedSolutionContainerSystem _solutionContainerSystem = default!;
|
[Dependency] private SharedSolutionContainerSystem _solutionContainerSystem = default!;
|
||||||
|
|
||||||
private EntityQuery<SmokeComponent> _smokeQuery;
|
[Dependency] private EntityQuery<SmokeComponent> _smokeQuery = default!;
|
||||||
private EntityQuery<SmokeAffectedComponent> _smokeAffectedQuery;
|
[Dependency] private EntityQuery<SmokeAffectedComponent> _smokeAffectedQuery = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_smokeQuery = GetEntityQuery<SmokeComponent>();
|
|
||||||
_smokeAffectedQuery = GetEntityQuery<SmokeAffectedComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<SmokeComponent, StartCollideEvent>(OnStartCollide);
|
SubscribeLocalEvent<SmokeComponent, StartCollideEvent>(OnStartCollide);
|
||||||
SubscribeLocalEvent<SmokeComponent, EndCollideEvent>(OnEndCollide);
|
SubscribeLocalEvent<SmokeComponent, EndCollideEvent>(OnEndCollide);
|
||||||
SubscribeLocalEvent<SmokeComponent, ReactionAttemptEvent>(OnReactionAttempt);
|
SubscribeLocalEvent<SmokeComponent, ReactionAttemptEvent>(OnReactionAttempt);
|
||||||
@@ -165,12 +161,10 @@ public sealed partial class SmokeSystem : EntitySystem
|
|||||||
|
|
||||||
// We have no more neighbours to spread to. So instead we will randomly distribute our volume to neighbouring smoke tiles.
|
// We have no more neighbours to spread to. So instead we will randomly distribute our volume to neighbouring smoke tiles.
|
||||||
|
|
||||||
var smokeQuery = GetEntityQuery<SmokeComponent>();
|
|
||||||
|
|
||||||
_random.Shuffle(args.Neighbors);
|
_random.Shuffle(args.Neighbors);
|
||||||
foreach (var neighbor in args.Neighbors)
|
foreach (var neighbor in args.Neighbors)
|
||||||
{
|
{
|
||||||
if (!smokeQuery.TryGetComponent(neighbor, out var smoke))
|
if (!_smokeQuery.TryGetComponent(neighbor, out var smoke))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
smoke.SpreadAmount++;
|
smoke.SpreadAmount++;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public sealed partial class SpraySystem : SharedSpraySystem
|
|||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|
||||||
var targetMapPos = _transform.GetMapCoordinates(GetEntityQuery<TransformComponent>().GetComponent(args.Target));
|
var targetMapPos = _transform.GetMapCoordinates(Transform(args.Target));
|
||||||
|
|
||||||
Spray(entity, targetMapPos, args.User);
|
Spray(entity, targetMapPos, args.User);
|
||||||
}
|
}
|
||||||
@@ -104,8 +104,7 @@ public sealed partial class SpraySystem : SharedSpraySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
var sprayerXform = Transform(entity);
|
||||||
var sprayerXform = xformQuery.GetComponent(entity);
|
|
||||||
|
|
||||||
var sprayerMapPos = _transform.GetMapCoordinates(sprayerXform);
|
var sprayerMapPos = _transform.GetMapCoordinates(sprayerXform);
|
||||||
var clickMapPos = mapcoord;
|
var clickMapPos = mapcoord;
|
||||||
@@ -149,7 +148,7 @@ public sealed partial class SpraySystem : SharedSpraySystem
|
|||||||
// Spawn the vapor cloud onto the grid/map the user is present on. Offset the start position based on how far the target destination is.
|
// Spawn the vapor cloud onto the grid/map the user is present on. Offset the start position based on how far the target destination is.
|
||||||
var vaporPos = sprayerMapPos.Offset(distance < 1 ? quarter : threeQuarters);
|
var vaporPos = sprayerMapPos.Offset(distance < 1 ? quarter : threeQuarters);
|
||||||
var vapor = Spawn(entity.Comp.SprayedPrototype, vaporPos);
|
var vapor = Spawn(entity.Comp.SprayedPrototype, vaporPos);
|
||||||
var vaporXform = xformQuery.GetComponent(vapor);
|
var vaporXform = Transform(vapor);
|
||||||
|
|
||||||
_transform.SetWorldRotation(vaporXform, rotation);
|
_transform.SetWorldRotation(vaporXform, rotation);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Numerics;
|
|||||||
using Content.Server.Administration.Managers;
|
using Content.Server.Administration.Managers;
|
||||||
using Content.Server.Administration.Systems;
|
using Content.Server.Administration.Systems;
|
||||||
using Content.Server.GameTicking.Events;
|
using Content.Server.GameTicking.Events;
|
||||||
using Content.Server.Ghost;
|
|
||||||
using Content.Server.Spawners.Components;
|
using Content.Server.Spawners.Components;
|
||||||
using Content.Server.Speech.Components;
|
using Content.Server.Speech.Components;
|
||||||
using Content.Server.Station.Components;
|
using Content.Server.Station.Components;
|
||||||
@@ -460,15 +459,13 @@ namespace Content.Server.GameTicking
|
|||||||
_possiblePositions.Add(transform.Coordinates);
|
_possiblePositions.Add(transform.Coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
|
||||||
|
|
||||||
// Fallback to a random grid.
|
// Fallback to a random grid.
|
||||||
if (_possiblePositions.Count == 0)
|
if (_possiblePositions.Count == 0)
|
||||||
{
|
{
|
||||||
var query = AllEntityQuery<MapGridComponent>();
|
var query = AllEntityQuery<MapGridComponent>();
|
||||||
while (query.MoveNext(out var uid, out var grid))
|
while (query.MoveNext(out var uid, out var grid))
|
||||||
{
|
{
|
||||||
if (!metaQuery.TryGetComponent(uid, out var meta) || meta.EntityPaused || TerminatingOrDeleted(uid))
|
if (!TryComp(uid, out MetaDataComponent? meta) || meta.EntityPaused || TerminatingOrDeleted(uid))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -507,7 +504,7 @@ namespace Content.Server.GameTicking
|
|||||||
{
|
{
|
||||||
var mapUid = _map.GetMapOrInvalid(map);
|
var mapUid = _map.GetMapOrInvalid(map);
|
||||||
|
|
||||||
if (!metaQuery.TryGetComponent(mapUid, out var meta)
|
if (!TryComp(mapUid, out MetaDataComponent? meta)
|
||||||
|| meta.EntityPaused
|
|| meta.EntityPaused
|
||||||
|| TerminatingOrDeleted(mapUid))
|
|| TerminatingOrDeleted(mapUid))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,16 +17,15 @@ using Content.Shared.GameTicking.Components;
|
|||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Mind.Components;
|
using Content.Shared.Mind.Components;
|
||||||
using Content.Shared.Mindshield.Components;
|
|
||||||
using Content.Shared.Mobs;
|
using Content.Shared.Mobs;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
using Content.Shared.NPC.Prototypes;
|
using Content.Shared.NPC.Prototypes;
|
||||||
using Content.Shared.NPC.Systems;
|
using Content.Shared.NPC.Systems;
|
||||||
|
using Content.Shared.Revolutionary;
|
||||||
using Content.Shared.Revolutionary.Components;
|
using Content.Shared.Revolutionary.Components;
|
||||||
using Content.Shared.Roles.Components;
|
using Content.Shared.Roles.Components;
|
||||||
using Content.Shared.Stunnable;
|
using Content.Shared.Stunnable;
|
||||||
using Content.Shared.Zombies;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Content.Shared.Cuffs.Components;
|
using Content.Shared.Cuffs.Components;
|
||||||
@@ -142,17 +141,20 @@ public sealed partial class RevolutionaryRuleSystem : GameRuleSystem<Revolutiona
|
|||||||
if (!_mind.TryGetMind(ev.Target, out var mindId, out var mind) && !alwaysConvertible)
|
if (!_mind.TryGetMind(ev.Target, out var mindId, out var mind) && !alwaysConvertible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HasComp<RevolutionaryComponent>(ev.Target) ||
|
if (!HasComp<HumanoidProfileComponent>(ev.Target) &&
|
||||||
HasComp<MindShieldComponent>(ev.Target) ||
|
|
||||||
!HasComp<HumanoidProfileComponent>(ev.Target) &&
|
|
||||||
!alwaysConvertible ||
|
!alwaysConvertible ||
|
||||||
!_mobState.IsAlive(ev.Target) ||
|
!_mobState.IsAlive(ev.Target) ||
|
||||||
HasComp<ZombieComponent>(ev.Target) ||
|
|
||||||
!HasComp<RevolutionaryConverterComponent>(ev.Used))
|
!HasComp<RevolutionaryConverterComponent>(ev.Used))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var attemptConvertEv = new AttemptConvertRevolutionaryEvent();
|
||||||
|
RaiseLocalEvent(ev.Target, ref attemptConvertEv);
|
||||||
|
|
||||||
|
if (attemptConvertEv.Cancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
_npcFaction.AddFaction(ev.Target, RevolutionaryNpcFaction);
|
_npcFaction.AddFaction(ev.Target, RevolutionaryNpcFaction);
|
||||||
var revComp = EnsureComp<RevolutionaryComponent>(ev.Target);
|
var revComp = EnsureComp<RevolutionaryComponent>(ev.Target);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public sealed partial class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponen
|
|||||||
[Dependency] private SharedRoleSystem _roles = default!;
|
[Dependency] private SharedRoleSystem _roles = default!;
|
||||||
[Dependency] private StationSystem _station = default!;
|
[Dependency] private StationSystem _station = default!;
|
||||||
[Dependency] private ZombieSystem _zombie = default!;
|
[Dependency] private ZombieSystem _zombie = default!;
|
||||||
|
[Dependency] private EntityQuery<ZombieComponent> _zombieQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -198,13 +199,12 @@ public sealed partial class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponen
|
|||||||
}
|
}
|
||||||
|
|
||||||
var players = AllEntityQuery<HumanoidProfileComponent, ActorComponent, MobStateComponent, TransformComponent>();
|
var players = AllEntityQuery<HumanoidProfileComponent, ActorComponent, MobStateComponent, TransformComponent>();
|
||||||
var zombers = GetEntityQuery<ZombieComponent>();
|
|
||||||
while (players.MoveNext(out var uid, out _, out _, out var mob, out var xform))
|
while (players.MoveNext(out var uid, out _, out _, out var mob, out var xform))
|
||||||
{
|
{
|
||||||
if (!_mobState.IsAlive(uid, mob))
|
if (!_mobState.IsAlive(uid, mob))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (zombers.HasComponent(uid))
|
if (_zombieQuery.HasComponent(uid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!includeOffStation && !stationGrids.Contains(xform.GridUid ?? EntityUid.Invalid))
|
if (!includeOffStation && !stationGrids.Contains(xform.GridUid ?? EntityUid.Invalid))
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ namespace Content.Server.Ghost
|
|||||||
[Dependency] private NameModifierSystem _nameMod = default!;
|
[Dependency] private NameModifierSystem _nameMod = default!;
|
||||||
[Dependency] private GhostSpriteStateSystem _ghostState = default!;
|
[Dependency] private GhostSpriteStateSystem _ghostState = default!;
|
||||||
|
|
||||||
private EntityQuery<GhostComponent> _ghostQuery;
|
[Dependency] private EntityQuery<GhostComponent> _ghostQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
|
||||||
private static readonly ProtoId<TagPrototype> AllowGhostShownByEventTag = "AllowGhostShownByEvent";
|
private static readonly ProtoId<TagPrototype> AllowGhostShownByEventTag = "AllowGhostShownByEvent";
|
||||||
private static readonly ProtoId<DamageTypePrototype> AsphyxiationDamageType = "Asphyxiation";
|
private static readonly ProtoId<DamageTypePrototype> AsphyxiationDamageType = "Asphyxiation";
|
||||||
@@ -78,9 +78,6 @@ namespace Content.Server.Ghost
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_ghostQuery = GetEntityQuery<GhostComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<GhostComponent, ComponentStartup>(OnGhostStartup);
|
SubscribeLocalEvent<GhostComponent, ComponentStartup>(OnGhostStartup);
|
||||||
SubscribeLocalEvent<GhostComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<GhostComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<GhostComponent, ComponentShutdown>(OnGhostShutdown);
|
SubscribeLocalEvent<GhostComponent, ComponentShutdown>(OnGhostShutdown);
|
||||||
|
|||||||
@@ -622,8 +622,7 @@ public sealed partial class GhostRoleSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int GetGhostRoleCount()
|
public int GetGhostRoleCount()
|
||||||
{
|
{
|
||||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
return _ghostRoles.Count(pair => MetaData(pair.Value.Owner).EntityPaused == false);
|
||||||
return _ghostRoles.Count(pair => metaQuery.GetComponent(pair.Value.Owner).EntityPaused == false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -635,11 +634,10 @@ public sealed partial class GhostRoleSystem : EntitySystem
|
|||||||
public GhostRoleInfo[] GetGhostRolesInfo(ICommonSession? player)
|
public GhostRoleInfo[] GetGhostRolesInfo(ICommonSession? player)
|
||||||
{
|
{
|
||||||
var roles = new List<GhostRoleInfo>();
|
var roles = new List<GhostRoleInfo>();
|
||||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
|
||||||
|
|
||||||
foreach (var (id, (uid, role)) in _ghostRoles)
|
foreach (var (id, (uid, role)) in _ghostRoles)
|
||||||
{
|
{
|
||||||
if (metaQuery.GetComponent(uid).EntityPaused)
|
if (MetaData(uid).EntityPaused)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ namespace Content.Server.Hands.Systems
|
|||||||
[Dependency] private SharedTransformSystem _transformSystem = default!;
|
[Dependency] private SharedTransformSystem _transformSystem = default!;
|
||||||
[Dependency] private PullingSystem _pullingSystem = default!;
|
[Dependency] private PullingSystem _pullingSystem = default!;
|
||||||
[Dependency] private ThrowingSystem _throwingSystem = default!;
|
[Dependency] private ThrowingSystem _throwingSystem = default!;
|
||||||
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Items dropped when the holder falls down will be launched in
|
/// Items dropped when the holder falls down will be launched in
|
||||||
@@ -57,8 +56,6 @@ namespace Content.Server.Hands.Systems
|
|||||||
CommandBinds.Builder
|
CommandBinds.Builder
|
||||||
.Bind(ContentKeyFunctions.ThrowItemInHand, new PointerInputCmdHandler(HandleThrowItem))
|
.Bind(ContentKeyFunctions.ThrowItemInHand, new PointerInputCmdHandler(HandleThrowItem))
|
||||||
.Register<HandsSystem>();
|
.Register<HandsSystem>();
|
||||||
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
|
|||||||
@@ -42,9 +42,7 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
[Dependency] private IGameTiming _timing = default!;
|
[Dependency] private IGameTiming _timing = default!;
|
||||||
[Dependency] private PvsOverrideSystem _pvs = default!;
|
[Dependency] private PvsOverrideSystem _pvs = default!;
|
||||||
[Dependency] private SharedPowerStateSystem _powerState = default!;
|
[Dependency] private SharedPowerStateSystem _powerState = default!;
|
||||||
|
[Dependency] private MetaDataSystem _meta = default!;
|
||||||
private float _updateTimer = 1.0f;
|
|
||||||
private const float UpdateTime = 1.0f;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -79,10 +77,10 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
SubscribeLocalEvent<HolopadUserComponent, JumpToCoreEvent>(OnJumpToCore);
|
SubscribeLocalEvent<HolopadUserComponent, JumpToCoreEvent>(OnJumpToCore);
|
||||||
SubscribeLocalEvent<HolopadComponent, GetVerbsEvent<AlternativeVerb>>(AddToggleProjectorVerb);
|
SubscribeLocalEvent<HolopadComponent, GetVerbsEvent<AlternativeVerb>>(AddToggleProjectorVerb);
|
||||||
SubscribeLocalEvent<HolopadComponent, EntRemovedFromContainerMessage>(OnAiRemove);
|
SubscribeLocalEvent<HolopadComponent, EntRemovedFromContainerMessage>(OnAiRemove);
|
||||||
SubscribeLocalEvent<HolopadComponent, EntParentChangedMessage>(OnParentChanged);
|
SubscribeLocalEvent<HolopadComponent, MapUidChangedEvent>(OnMapUidChanged);
|
||||||
SubscribeLocalEvent<HolopadComponent, PowerChangedEvent>(OnPowerChanged);
|
SubscribeLocalEvent<HolopadComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
|
SubscribeLocalEvent<HolopadComponent, AnchorStateChangedEvent>(OnAnchorChanged);
|
||||||
SubscribeLocalEvent<HolopadUserComponent, MobStateChangedEvent>(OnMobStateChanged);
|
SubscribeLocalEvent<HolopadUserComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region: Holopad UI bound user interface messages
|
#region: Holopad UI bound user interface messages
|
||||||
@@ -263,6 +261,8 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
SetHolopadAmbientState(holopad, this.IsPowered(holopad, EntityManager));
|
SetHolopadAmbientState(holopad, this.IsPowered(holopad, EntityManager));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateUIState(holopad);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnHoloCallCommenced(Entity<HolopadComponent> source, ref TelephoneCallCommencedEvent args)
|
private void OnHoloCallCommenced(Entity<HolopadComponent> source, ref TelephoneCallCommencedEvent args)
|
||||||
@@ -315,7 +315,7 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
if (receiverHolopad.Comp.Hologram == null)
|
if (receiverHolopad.Comp.Hologram == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_appearanceSystem.SetData(receiverHolopad.Comp.Hologram.Value.Owner, TypingIndicatorVisuals.State, ev.State);
|
_appearanceSystem.SetData(receiverHolopad.Comp.Hologram.Value, TypingIndicatorVisuals.State, ev.State);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +328,8 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
{
|
{
|
||||||
if (entity.Comp.User != null)
|
if (entity.Comp.User != null)
|
||||||
LinkHolopadToUser(entity, entity.Comp.User.Value);
|
LinkHolopadToUser(entity, entity.Comp.User.Value);
|
||||||
|
|
||||||
|
_meta.AddFlag(entity, MetaDataFlags.ExtraTransformEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnHolopadUserInit(Entity<HolopadUserComponent> entity, ref ComponentInit args)
|
private void OnHolopadUserInit(Entity<HolopadUserComponent> entity, ref ComponentInit args)
|
||||||
@@ -343,6 +345,7 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
|
|
||||||
ShutDownHolopad(entity);
|
ShutDownHolopad(entity);
|
||||||
SetHolopadAmbientState(entity, false);
|
SetHolopadAmbientState(entity, false);
|
||||||
|
UpdateAllUIStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnHolopadUserShutdown(Entity<HolopadUserComponent> entity, ref ComponentShutdown args)
|
private void OnHolopadUserShutdown(Entity<HolopadUserComponent> entity, ref ComponentShutdown args)
|
||||||
@@ -444,15 +447,25 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
_telephoneSystem.EndTelephoneCalls((entity, entityTelephone));
|
_telephoneSystem.EndTelephoneCalls((entity, entityTelephone));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnParentChanged(Entity<HolopadComponent> entity, ref EntParentChangedMessage args)
|
private void OnMapUidChanged(Entity<HolopadComponent> entity, ref MapUidChangedEvent args)
|
||||||
{
|
{
|
||||||
UpdateHolopadControlLockoutStartTime(entity);
|
UpdateHolopadControlLockoutStartTime(entity);
|
||||||
|
UpdateAllUIStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChanged(Entity<HolopadComponent> entity, ref PowerChangedEvent args)
|
private void OnPowerChanged(Entity<HolopadComponent> entity, ref PowerChangedEvent args)
|
||||||
{
|
{
|
||||||
if (args.Powered)
|
if (args.Powered)
|
||||||
|
{
|
||||||
UpdateHolopadControlLockoutStartTime(entity);
|
UpdateHolopadControlLockoutStartTime(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAllUIStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAnchorChanged(Entity<HolopadComponent> entity, ref AnchorStateChangedEvent args)
|
||||||
|
{
|
||||||
|
UpdateAllUIStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMobStateChanged(Entity<HolopadUserComponent> ent, ref MobStateChangedEvent args)
|
private void OnMobStateChanged(Entity<HolopadUserComponent> ent, ref MobStateChangedEvent args)
|
||||||
@@ -472,27 +485,37 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
_updateTimer += frameTime;
|
var query = AllEntityQuery<HolopadUserComponent, TransformComponent>();
|
||||||
|
while (query.MoveNext(out var uid, out var holopadUser, out var xform))
|
||||||
if (_updateTimer >= UpdateTime)
|
|
||||||
{
|
{
|
||||||
_updateTimer -= UpdateTime;
|
if (HasComp<IgnoreUIRangeComponent>(uid))
|
||||||
|
continue;
|
||||||
|
|
||||||
var query = AllEntityQuery<HolopadComponent, TelephoneComponent, TransformComponent>();
|
foreach (var holopad in holopadUser.LinkedHolopads)
|
||||||
while (query.MoveNext(out var uid, out var holopad, out var telephone, out var xform))
|
|
||||||
{
|
{
|
||||||
UpdateUIState((uid, holopad), telephone);
|
if (TryComp<TelephoneComponent>(holopad, out var telephone) &&
|
||||||
|
!_xformSystem.InRange((holopad.Owner, Transform(holopad)), (uid, xform), telephone.ListeningRange))
|
||||||
if (holopad.User != null &&
|
|
||||||
!HasComp<IgnoreUIRangeComponent>(holopad.User) &&
|
|
||||||
!_xformSystem.InRange((holopad.User.Value, Transform(holopad.User.Value)), (uid, xform), telephone.ListeningRange))
|
|
||||||
{
|
{
|
||||||
UnlinkHolopadFromUser((uid, holopad), holopad.User.Value);
|
UnlinkHolopadFromUser(holopad, (uid, holopadUser));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateAllUIStates()
|
||||||
|
{
|
||||||
|
var querySources = AllEntityQuery<HolopadComponent, TelephoneComponent, UserInterfaceComponent>();
|
||||||
|
while (querySources.MoveNext(out var uid, out var holopad, out var telephone, out var ui))
|
||||||
|
{
|
||||||
|
var uiKey = HasComp<StationAiCoreComponent>(uid) ? HolopadUiKey.AiActionWindow : HolopadUiKey.InteractionWindow;
|
||||||
|
|
||||||
|
if (!_userInterfaceSystem.IsUiOpen((uid, ui), uiKey))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UpdateUIState((uid, holopad), telephone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateUIState(Entity<HolopadComponent> entity, TelephoneComponent? telephone = null)
|
public void UpdateUIState(Entity<HolopadComponent> entity, TelephoneComponent? telephone = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(entity.Owner, ref telephone, false))
|
if (!Resolve(entity.Owner, ref telephone, false))
|
||||||
@@ -571,23 +594,26 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryComp<HolopadUserComponent>(user, out var holopadUser))
|
var holopadUser = EnsureComp<HolopadUserComponent>(user.Value);
|
||||||
holopadUser = AddComp<HolopadUserComponent>(user.Value);
|
var userEnt = (user.Value, holopadUser);
|
||||||
|
|
||||||
if (user != entity.Comp.User?.Owner)
|
if (user != entity.Comp.User)
|
||||||
{
|
{
|
||||||
// Removes the old user from the holopad
|
// Removes the old user from the holopad
|
||||||
UnlinkHolopadFromUser(entity, entity.Comp.User);
|
if (TryComp<HolopadUserComponent>(entity.Comp.User, out var oldHolopadUser))
|
||||||
|
{
|
||||||
|
UnlinkHolopadFromUser(entity, (entity.Comp.User.Value, oldHolopadUser));
|
||||||
|
}
|
||||||
|
|
||||||
// Assigns the new user in their place
|
// Assigns the new user in their place
|
||||||
holopadUser.LinkedHolopads.Add(entity);
|
holopadUser?.LinkedHolopads.Add(entity);
|
||||||
entity.Comp.User = (user.Value, holopadUser);
|
entity.Comp.User = user.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new user to PVS and sync their appearance with any
|
// Add the new user to PVS and sync their appearance with any
|
||||||
// holopads connected to the one they are using
|
// holopads connected to the one they are using
|
||||||
_pvs.AddGlobalOverride(user.Value);
|
_pvs.AddGlobalOverride(user.Value);
|
||||||
SyncHolopadHologramAppearanceWithTarget(entity, entity.Comp.User);
|
SyncHolopadHologramAppearanceWithTarget(entity, userEnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlinkHolopadFromUser(Entity<HolopadComponent> entity, Entity<HolopadUserComponent>? user)
|
private void UnlinkHolopadFromUser(Entity<HolopadComponent> entity, Entity<HolopadUserComponent>? user)
|
||||||
@@ -611,14 +637,14 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
{
|
{
|
||||||
foreach (var linkedHolopad in GetLinkedHolopads(entity))
|
foreach (var linkedHolopad in GetLinkedHolopads(entity))
|
||||||
{
|
{
|
||||||
if (linkedHolopad.Comp.Hologram == null)
|
if (!TryComp<HolopadHologramComponent>(linkedHolopad.Comp.Hologram, out var holopadHologram))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (user == null)
|
if (user == null)
|
||||||
_appearanceSystem.SetData(linkedHolopad.Comp.Hologram.Value.Owner, TypingIndicatorVisuals.State, false);
|
_appearanceSystem.SetData(linkedHolopad.Comp.Hologram.Value, TypingIndicatorVisuals.State, false);
|
||||||
|
|
||||||
linkedHolopad.Comp.Hologram.Value.Comp.LinkedEntity = user;
|
holopadHologram.LinkedEntity = user;
|
||||||
Dirty(linkedHolopad.Comp.Hologram.Value);
|
Dirty(linkedHolopad.Comp.Hologram.Value, holopadHologram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,8 +652,8 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
{
|
{
|
||||||
entity.Comp.ControlLockoutOwner = null;
|
entity.Comp.ControlLockoutOwner = null;
|
||||||
|
|
||||||
if (entity.Comp.Hologram != null)
|
if (TryComp<HolopadHologramComponent>(entity.Comp.Hologram, out var holopadHologram))
|
||||||
DeleteHologram(entity.Comp.Hologram.Value, entity);
|
DeleteHologram((entity.Comp.Hologram.Value, holopadHologram), entity);
|
||||||
|
|
||||||
// Check if the associated holopad user is an AI
|
// Check if the associated holopad user is an AI
|
||||||
if (HasComp<StationAiHeldComponent>(entity.Comp.User) &&
|
if (HasComp<StationAiHeldComponent>(entity.Comp.User) &&
|
||||||
@@ -643,9 +669,9 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
_telephoneSystem.EndTelephoneCalls((stationAiCore.Owner, stationAiCoreTelephone));
|
_telephoneSystem.EndTelephoneCalls((stationAiCore.Owner, stationAiCoreTelephone));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (TryComp<HolopadUserComponent>(entity.Comp.User, out var holopadUser))
|
||||||
{
|
{
|
||||||
UnlinkHolopadFromUser(entity, entity.Comp.User);
|
UnlinkHolopadFromUser(entity, (entity.Comp.User.Value, holopadUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
Dirty(entity);
|
Dirty(entity);
|
||||||
@@ -749,14 +775,16 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
|
|
||||||
// Lock out the controls of all involved holopads for a set duration
|
// Lock out the controls of all involved holopads for a set duration
|
||||||
source.Comp.ControlLockoutOwner = user;
|
source.Comp.ControlLockoutOwner = user;
|
||||||
source.Comp.ControlLockoutStartTime = _timing.CurTime;
|
source.Comp.ControlLockoutEndTime = _timing.CurTime + source.Comp.ControlLockoutDuration;
|
||||||
|
source.Comp.ControlLockoutCoolDownEndTime = _timing.CurTime + source.Comp.ControlLockoutCoolDown;
|
||||||
|
|
||||||
Dirty(source);
|
Dirty(source);
|
||||||
|
|
||||||
foreach (var receiver in GetLinkedHolopads(source))
|
foreach (var receiver in GetLinkedHolopads(source))
|
||||||
{
|
{
|
||||||
receiver.Comp.ControlLockoutOwner = user;
|
receiver.Comp.ControlLockoutOwner = user;
|
||||||
receiver.Comp.ControlLockoutStartTime = _timing.CurTime;
|
receiver.Comp.ControlLockoutEndTime = _timing.CurTime + source.Comp.ControlLockoutDuration;
|
||||||
|
receiver.Comp.ControlLockoutCoolDownEndTime = _timing.CurTime + source.Comp.ControlLockoutCoolDown;
|
||||||
|
|
||||||
Dirty(receiver);
|
Dirty(receiver);
|
||||||
}
|
}
|
||||||
@@ -796,15 +824,20 @@ public sealed partial class HolopadSystem : SharedHolopadSystem
|
|||||||
if (!_telephoneSystem.IsSourceInRangeOfReceiver(sourceTelephoneEntity, receiverTelephoneEntity))
|
if (!_telephoneSystem.IsSourceInRangeOfReceiver(sourceTelephoneEntity, receiverTelephoneEntity))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (receiverHolopad.ControlLockoutStartTime > source.Comp.ControlLockoutStartTime)
|
if (receiverHolopad.ControlLockoutEndTime > source.Comp.ControlLockoutEndTime ||
|
||||||
|
receiverHolopad.ControlLockoutCoolDownEndTime > source.Comp.ControlLockoutCoolDownEndTime)
|
||||||
{
|
{
|
||||||
source.Comp.ControlLockoutStartTime = receiverHolopad.ControlLockoutStartTime;
|
source.Comp.ControlLockoutEndTime = receiverHolopad.ControlLockoutEndTime;
|
||||||
|
source.Comp.ControlLockoutCoolDownEndTime = receiverHolopad.ControlLockoutCoolDownEndTime;
|
||||||
|
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDirty)
|
if (isDirty)
|
||||||
|
{
|
||||||
Dirty(source);
|
Dirty(source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetHolopadAmbientState(Entity<HolopadComponent> entity, bool isEnabled)
|
private void SetHolopadAmbientState(Entity<HolopadComponent> entity, bool isEnabled)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Administration;
|
using Content.Server.Administration;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Interaction;
|
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.Stunnable;
|
using Content.Server.Stunnable;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
@@ -10,7 +9,6 @@ using Content.Shared.Database;
|
|||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Instruments;
|
using Content.Shared.Instruments;
|
||||||
using Content.Shared.Instruments.UI;
|
using Content.Shared.Instruments.UI;
|
||||||
using Content.Shared.Physics;
|
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -19,9 +17,7 @@ using Robust.Shared.Collections;
|
|||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Server.Instruments;
|
namespace Content.Server.Instruments;
|
||||||
|
|
||||||
@@ -36,7 +32,10 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
[Dependency] private PopupSystem _popup = default!;
|
[Dependency] private PopupSystem _popup = default!;
|
||||||
[Dependency] private TransformSystem _transform = default!;
|
[Dependency] private TransformSystem _transform = default!;
|
||||||
[Dependency] private ExamineSystemShared _examineSystem = default!;
|
[Dependency] private ExamineSystemShared _examineSystem = default!;
|
||||||
[Dependency] private IAdminLogManager _admingLogSystem = default!;
|
[Dependency] private IAdminLogManager _adminLogSystem = default!;
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<InstrumentComponent> _instrumentQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<ActiveInstrumentComponent> _activeInstrumentQuery = default!;
|
||||||
|
|
||||||
private const float MaxInstrumentBandRange = 10f;
|
private const float MaxInstrumentBandRange = 10f;
|
||||||
|
|
||||||
@@ -170,7 +169,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
.Where(t => t != null)
|
.Where(t => t != null)
|
||||||
.Select(t => t!.ToString()));
|
.Select(t => t!.ToString()));
|
||||||
|
|
||||||
_admingLogSystem.Add(
|
_adminLogSystem.Add(
|
||||||
LogType.Instrument,
|
LogType.Instrument,
|
||||||
LogImpact.Low,
|
LogImpact.Low,
|
||||||
$"{ToPrettyString(args.SenderSession.AttachedEntity)} set the midi channels for {ToPrettyString(uid)} to {tracksString}");
|
$"{ToPrettyString(args.SenderSession.AttachedEntity)} set the midi channels for {ToPrettyString(uid)} to {tracksString}");
|
||||||
@@ -271,13 +270,10 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
|
|
||||||
public (NetEntity, string)[] GetBands(EntityUid uid)
|
public (NetEntity, string)[] GetBands(EntityUid uid)
|
||||||
{
|
{
|
||||||
var metadataQuery = GetEntityQuery<MetaDataComponent>();
|
|
||||||
|
|
||||||
if (Deleted(uid))
|
if (Deleted(uid))
|
||||||
return Array.Empty<(NetEntity, string)>();
|
return Array.Empty<(NetEntity, string)>();
|
||||||
|
|
||||||
var list = new ValueList<(NetEntity, string)>();
|
var list = new ValueList<(NetEntity, string)>();
|
||||||
var instrumentQuery = GetEntityQuery<InstrumentComponent>();
|
|
||||||
|
|
||||||
if (!TryComp(uid, out InstrumentComponent? originInstrument)
|
if (!TryComp(uid, out InstrumentComponent? originInstrument)
|
||||||
|| originInstrument.InstrumentPlayer is not {} originPlayer)
|
|| originInstrument.InstrumentPlayer is not {} originPlayer)
|
||||||
@@ -291,7 +287,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't grab puppet instruments.
|
// Don't grab puppet instruments.
|
||||||
if (!instrumentQuery.TryGetComponent(entity, out var instrument) || instrument.Master != null)
|
if (!_instrumentQuery.TryGetComponent(entity, out var instrument) || instrument.Master != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// We want to use the instrument player's name.
|
// We want to use the instrument player's name.
|
||||||
@@ -303,8 +299,8 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
if (!_examineSystem.InRangeUnOccluded(uid, entity, MaxInstrumentBandRange, e => e == playerUid || e == originPlayer))
|
if (!_examineSystem.InRangeUnOccluded(uid, entity, MaxInstrumentBandRange, e => e == playerUid || e == originPlayer))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!metadataQuery.TryGetComponent(playerUid, out var playerMetadata)
|
if (!TryComp(playerUid, out MetaDataComponent? playerMetadata)
|
||||||
|| !metadataQuery.TryGetComponent(entity, out var metadata))
|
|| !TryComp(entity, out MetaDataComponent? metadata))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
list.Add((GetNetEntity(entity), $"{playerMetadata.EntityName} - {metadata.EntityName}"));
|
list.Add((GetNetEntity(entity), $"{playerMetadata.EntityName} - {metadata.EntityName}"));
|
||||||
@@ -427,9 +423,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
_bandRequestQueue.Clear();
|
_bandRequestQueue.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeQuery = GetEntityQuery<ActiveInstrumentComponent>();
|
|
||||||
var transformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
var query = AllEntityQuery<ActiveInstrumentComponent, InstrumentComponent>();
|
var query = AllEntityQuery<ActiveInstrumentComponent, InstrumentComponent>();
|
||||||
while (query.MoveNext(out var uid, out _, out var instrument))
|
while (query.MoveNext(out var uid, out _, out var instrument))
|
||||||
{
|
{
|
||||||
@@ -441,15 +434,15 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var masterActive = activeQuery.CompOrNull(master);
|
_activeInstrumentQuery.TryComp(master, out var masterActive);
|
||||||
if (masterActive == null)
|
if (masterActive == null)
|
||||||
{
|
{
|
||||||
Clean(uid, instrument);
|
Clean(uid, instrument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var trans = transformQuery.GetComponent(uid);
|
var trans = Transform(uid);
|
||||||
var masterTrans = transformQuery.GetComponent(master);
|
var masterTrans = Transform(master);
|
||||||
if (!_transform.InRange(masterTrans.Coordinates, trans.Coordinates, 10f))
|
if (!_transform.InRange(masterTrans.Coordinates, trans.Coordinates, 10f))
|
||||||
{
|
{
|
||||||
Clean(uid, instrument);
|
Clean(uid, instrument);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Light.Components;
|
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Light.EntitySystems;
|
using Content.Shared.Light.EntitySystems;
|
||||||
@@ -7,7 +6,6 @@ using Content.Shared.Light.Components;
|
|||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Storage;
|
using Content.Shared.Storage;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
|
|
||||||
@@ -44,10 +42,9 @@ public sealed partial class LightReplacerSystem : SharedLightReplacerSystem
|
|||||||
|
|
||||||
args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
args.PushMarkup(Loc.GetString("comp-light-replacer-has-lights"));
|
||||||
var groups = new Dictionary<string, int>();
|
var groups = new Dictionary<string, int>();
|
||||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
|
||||||
foreach (var bulb in component.InsertedBulbs.ContainedEntities)
|
foreach (var bulb in component.InsertedBulbs.ContainedEntities)
|
||||||
{
|
{
|
||||||
var metaData = metaQuery.GetComponent(bulb);
|
var metaData = MetaData(bulb);
|
||||||
groups[metaData.EntityName] = groups.GetValueOrDefault(metaData.EntityName) + 1;
|
groups[metaData.EntityName] = groups.GetValueOrDefault(metaData.EntityName) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,11 @@ namespace Content.Server.Light.EntitySystems;
|
|||||||
public sealed partial class RoofSystem : SharedRoofSystem
|
public sealed partial class RoofSystem : SharedRoofSystem
|
||||||
{
|
{
|
||||||
[Dependency] private SharedMapSystem _maps = default!;
|
[Dependency] private SharedMapSystem _maps = default!;
|
||||||
|
[Dependency] private EntityQuery<MapGridComponent> _mapGridQuery = default!;
|
||||||
private EntityQuery<MapGridComponent> _gridQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_gridQuery = GetEntityQuery<MapGridComponent>();
|
|
||||||
SubscribeLocalEvent<SetRoofComponent, ComponentStartup>(OnFlagStartup);
|
SubscribeLocalEvent<SetRoofComponent, ComponentStartup>(OnFlagStartup);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ public sealed partial class RoofSystem : SharedRoofSystem
|
|||||||
{
|
{
|
||||||
var xform = Transform(ent.Owner);
|
var xform = Transform(ent.Owner);
|
||||||
|
|
||||||
if (_gridQuery.TryComp(xform.GridUid, out var grid))
|
if (_mapGridQuery.TryComp(xform.GridUid, out var grid))
|
||||||
{
|
{
|
||||||
var index = _maps.LocalToTile(xform.GridUid.Value, grid, xform.Coordinates);
|
var index = _maps.LocalToTile(xform.GridUid.Value, grid, xform.Coordinates);
|
||||||
SetRoof((xform.GridUid.Value, grid, null), index, ent.Comp.Value);
|
SetRoof((xform.GridUid.Value, grid, null), index, ent.Comp.Value);
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
using Content.Shared.Hands;
|
|
||||||
using Content.Shared.Hands.EntitySystems;
|
|
||||||
using Content.Shared.IdentityManagement;
|
|
||||||
using Content.Shared.Item;
|
|
||||||
using Content.Shared.Lube;
|
|
||||||
using Content.Shared.NameModifier.EntitySystems;
|
|
||||||
using Content.Shared.Popups;
|
|
||||||
using Content.Shared.Throwing;
|
|
||||||
using Robust.Shared.Random;
|
|
||||||
|
|
||||||
namespace Content.Server.Lube;
|
|
||||||
|
|
||||||
public sealed partial class LubedSystem : EntitySystem
|
|
||||||
{
|
|
||||||
[Dependency] private ThrowingSystem _throwing = default!;
|
|
||||||
[Dependency] private IRobustRandom _random = default!;
|
|
||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
|
||||||
[Dependency] private SharedPopupSystem _popup = default!;
|
|
||||||
[Dependency] private NameModifierSystem _nameMod = default!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<LubedComponent, ComponentInit>(OnInit);
|
|
||||||
SubscribeLocalEvent<LubedComponent, BeforeGettingEquippedHandEvent>(OnHandPickUp);
|
|
||||||
SubscribeLocalEvent<LubedComponent, RefreshNameModifiersEvent>(OnRefreshNameModifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, LubedComponent component, ComponentInit args)
|
|
||||||
{
|
|
||||||
_nameMod.RefreshNameModifiers(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <remarks>
|
|
||||||
/// Note to whoever makes this predicted—there is a mispredict here that
|
|
||||||
/// would be nice to keep! If this is in shared, the client will predict
|
|
||||||
/// this and not run the pickup animation in <see cref="SharedHandsSystem"/>
|
|
||||||
/// which would (probably) make this effect look less funny. You will
|
|
||||||
/// probably want to either tweak <see cref="BeforeGettingEquippedHandEvent"/>
|
|
||||||
/// to be able to cancel but still run the animation or something—we do want
|
|
||||||
/// the event to run before the animation for stuff like
|
|
||||||
/// <see cref="MultiHandedItemSystem.OnBeforeEquipped"/>.
|
|
||||||
/// </remarks>
|
|
||||||
private void OnHandPickUp(Entity<LubedComponent> ent, ref BeforeGettingEquippedHandEvent args)
|
|
||||||
{
|
|
||||||
if (args.Cancelled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ent.Comp.SlipsLeft <= 0)
|
|
||||||
{
|
|
||||||
RemComp<LubedComponent>(ent);
|
|
||||||
_nameMod.RefreshNameModifiers(ent.Owner);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent.Comp.SlipsLeft--;
|
|
||||||
args.Cancelled = true;
|
|
||||||
|
|
||||||
_transform.SetCoordinates(ent, Transform(args.User).Coordinates);
|
|
||||||
_transform.AttachToGridOrMap(ent);
|
|
||||||
_throwing.TryThrow(ent, _random.NextVector2(), ent.Comp.SlipStrength);
|
|
||||||
_popup.PopupEntity(Loc.GetString("lube-slip", ("target", Identity.Entity(ent, EntityManager))),
|
|
||||||
args.User,
|
|
||||||
args.User,
|
|
||||||
PopupType.MediumCaution);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnRefreshNameModifiers(Entity<LubedComponent> entity, ref RefreshNameModifiersEvent args)
|
|
||||||
{
|
|
||||||
args.AddModifier("lubed-name-prefix");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@ using Content.Server.Roles;
|
|||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Implants;
|
using Content.Shared.Implants;
|
||||||
using Content.Shared.Mindshield.Components;
|
using Content.Shared.Mindshield.Components;
|
||||||
|
using Content.Shared.Revolutionary;
|
||||||
using Content.Shared.Revolutionary.Components;
|
using Content.Shared.Revolutionary.Components;
|
||||||
using Content.Shared.Roles.Components;
|
using Content.Shared.Roles.Components;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
@@ -28,6 +29,7 @@ public sealed partial class MindShieldSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<MindShieldImplantComponent, ImplantImplantedEvent>(OnImplantImplanted);
|
SubscribeLocalEvent<MindShieldImplantComponent, ImplantImplantedEvent>(OnImplantImplanted);
|
||||||
SubscribeLocalEvent<MindShieldImplantComponent, ImplantRemovedEvent>(OnImplantRemoved);
|
SubscribeLocalEvent<MindShieldImplantComponent, ImplantRemovedEvent>(OnImplantRemoved);
|
||||||
|
SubscribeLocalEvent<MindShieldComponent, AttemptConvertRevolutionaryEvent>(OnAttemptConvert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnImplantImplanted(Entity<MindShieldImplantComponent> ent, ref ImplantImplantedEvent ev)
|
private void OnImplantImplanted(Entity<MindShieldImplantComponent> ent, ref ImplantImplantedEvent ev)
|
||||||
@@ -59,5 +61,10 @@ public sealed partial class MindShieldSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
RemComp<MindShieldComponent>(args.Implanted);
|
RemComp<MindShieldComponent>(args.Implanted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnAttemptConvert(Entity<MindShieldComponent> ent, ref AttemptConvertRevolutionaryEvent args)
|
||||||
|
{
|
||||||
|
args.Cancelled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,13 @@ using Robust.Shared.Player;
|
|||||||
|
|
||||||
namespace Content.Server.Movement.Systems;
|
namespace Content.Server.Movement.Systems;
|
||||||
|
|
||||||
public sealed class MobCollisionSystem : SharedMobCollisionSystem
|
public sealed partial class MobCollisionSystem : SharedMobCollisionSystem
|
||||||
{
|
{
|
||||||
private EntityQuery<ActorComponent> _actorQuery;
|
[Dependency] private EntityQuery<ActorComponent> _actorQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_actorQuery = GetEntityQuery<ActorComponent>();
|
|
||||||
SubscribeLocalEvent<MobCollisionComponent, MobCollisionMessage>(OnServerMobCollision);
|
SubscribeLocalEvent<MobCollisionComponent, MobCollisionMessage>(OnServerMobCollision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ using Content.Shared.Gravity;
|
|||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Movement.Pulling.Components;
|
using Content.Shared.Movement.Pulling.Components;
|
||||||
using Content.Shared.Movement.Pulling.Events;
|
using Content.Shared.Movement.Pulling.Events;
|
||||||
using Content.Shared.Movement.Pulling.Systems;
|
|
||||||
using Content.Shared.Rotatable;
|
using Content.Shared.Rotatable;
|
||||||
using Robust.Server.Physics;
|
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
@@ -61,6 +59,10 @@ public sealed partial class PullController : VirtualController
|
|||||||
[Dependency] private SharedGravitySystem _gravity = default!;
|
[Dependency] private SharedGravitySystem _gravity = default!;
|
||||||
[Dependency] private SharedTransformSystem _transformSystem = default!;
|
[Dependency] private SharedTransformSystem _transformSystem = default!;
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<PullableComponent> _pullableQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<PullerComponent> _pullerQuery = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If distance between puller and pulled entity lower that this threshold,
|
/// If distance between puller and pulled entity lower that this threshold,
|
||||||
/// pulled entity will not change its rotation.
|
/// pulled entity will not change its rotation.
|
||||||
@@ -76,22 +78,12 @@ public sealed partial class PullController : VirtualController
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float ThresholdRotAngle = 22.5f;
|
private const float ThresholdRotAngle = 22.5f;
|
||||||
|
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
|
||||||
private EntityQuery<PullableComponent> _pullableQuery;
|
|
||||||
private EntityQuery<PullerComponent> _pullerQuery;
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
CommandBinds.Builder
|
CommandBinds.Builder
|
||||||
.Bind(ContentKeyFunctions.MovePulledObject, new PointerInputCmdHandler(OnRequestMovePulledObject))
|
.Bind(ContentKeyFunctions.MovePulledObject, new PointerInputCmdHandler(OnRequestMovePulledObject))
|
||||||
.Register<PullController>();
|
.Register<PullController>();
|
||||||
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
_pullableQuery = GetEntityQuery<PullableComponent>();
|
|
||||||
_pullerQuery = GetEntityQuery<PullerComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
UpdatesAfter.Add(typeof(MoverController));
|
UpdatesAfter.Add(typeof(MoverController));
|
||||||
SubscribeLocalEvent<PullMovingComponent, PullStoppedMessage>(OnPullStop);
|
SubscribeLocalEvent<PullMovingComponent, PullStoppedMessage>(OnPullStop);
|
||||||
SubscribeLocalEvent<ActivePullerComponent, MoveEvent>(OnPullerMove);
|
SubscribeLocalEvent<ActivePullerComponent, MoveEvent>(OnPullerMove);
|
||||||
@@ -202,8 +194,8 @@ public sealed partial class PullController : VirtualController
|
|||||||
if (!rotatable.RotateWhilePulling)
|
if (!rotatable.RotateWhilePulling)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var pulledXform = _xformQuery.GetComponent(pulled);
|
var pulledXform = Transform(pulled);
|
||||||
var pullerXform = _xformQuery.GetComponent(puller);
|
var pullerXform = Transform(puller);
|
||||||
|
|
||||||
var pullerData = TransformSystem.GetWorldPositionRotation(pullerXform);
|
var pullerData = TransformSystem.GetWorldPositionRotation(pullerXform);
|
||||||
var pulledData = TransformSystem.GetWorldPositionRotation(pulledXform);
|
var pulledData = TransformSystem.GetWorldPositionRotation(pulledXform);
|
||||||
@@ -245,7 +237,7 @@ public sealed partial class PullController : VirtualController
|
|||||||
if (pullable.Puller is not {Valid: true} puller)
|
if (pullable.Puller is not {Valid: true} puller)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var pullerXform = _xformQuery.Get(puller);
|
var pullerXform = Transform(puller);
|
||||||
var pullerPosition = TransformSystem.GetMapCoordinates(pullerXform);
|
var pullerPosition = TransformSystem.GetMapCoordinates(pullerXform);
|
||||||
|
|
||||||
var movingTo = TransformSystem.ToMapCoordinates(mover.MovingTo);
|
var movingTo = TransformSystem.ToMapCoordinates(mover.MovingTo);
|
||||||
@@ -305,7 +297,7 @@ public sealed partial class PullController : VirtualController
|
|||||||
// if the puller is weightless or can't move, then we apply the inverse impulse (Newton's third law).
|
// if the puller is weightless or can't move, then we apply the inverse impulse (Newton's third law).
|
||||||
// doing it under gravity produces an unsatisfying wiggling when pulling.
|
// doing it under gravity produces an unsatisfying wiggling when pulling.
|
||||||
// If player can't move, assume they are on a chair and we need to prevent pull-moving.
|
// If player can't move, assume they are on a chair and we need to prevent pull-moving.
|
||||||
if (_gravity.IsWeightless(puller) && pullerXform.Comp.GridUid == null || !_actionBlockerSystem.CanMove(puller))
|
if (_gravity.IsWeightless(puller) && pullerXform.GridUid == null || !_actionBlockerSystem.CanMove(puller))
|
||||||
{
|
{
|
||||||
PhysicsSystem.WakeBody(puller);
|
PhysicsSystem.WakeBody(puller);
|
||||||
PhysicsSystem.ApplyLinearImpulse(puller, -impulse);
|
PhysicsSystem.ApplyLinearImpulse(puller, -impulse);
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ public sealed partial class WieldedPrecondition : HTNPrecondition
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var wieldableSystem = _entManager.System<SharedWieldableSystem>();
|
var wieldableSystem = _entManager.System<SharedWieldableSystem>();
|
||||||
return wieldableSystem.CanWield(heldEntity.Value, wieldable, owner, quiet: true);
|
return wieldableSystem.CanWield((heldEntity.Value, wieldable), owner, quiet: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public sealed partial class WieldOperator : HTNOperator
|
|||||||
if (wieldable.Wielded)
|
if (wieldable.Wielded)
|
||||||
return HTNOperatorStatus.Failed;
|
return HTNOperatorStatus.Failed;
|
||||||
|
|
||||||
return wieldableSystem.TryWield(weaponUid.Value, wieldable, owner)
|
return wieldableSystem.TryWield((weaponUid.Value, wieldable), owner)
|
||||||
? HTNOperatorStatus.Finished
|
? HTNOperatorStatus.Finished
|
||||||
: HTNOperatorStatus.Failed;
|
: HTNOperatorStatus.Failed;
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ public sealed partial class WieldOperator : HTNOperator
|
|||||||
if (!wieldable.Wielded)
|
if (!wieldable.Wielded)
|
||||||
return HTNOperatorStatus.Failed;
|
return HTNOperatorStatus.Failed;
|
||||||
|
|
||||||
return wieldableSystem.TryUnwield(weaponUid.Value, wieldable, owner)
|
return wieldableSystem.TryUnwield((weaponUid.Value, wieldable), owner)
|
||||||
? HTNOperatorStatus.Finished
|
? HTNOperatorStatus.Finished
|
||||||
: HTNOperatorStatus.Failed;
|
: HTNOperatorStatus.Failed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public sealed partial class PathfindingSystem
|
|||||||
// TODO: Dump all this shit and just do it live it's probably fast enough.
|
// TODO: Dump all this shit and just do it live it's probably fast enough.
|
||||||
if (comp.DirtyChunks.Count == 0 ||
|
if (comp.DirtyChunks.Count == 0 ||
|
||||||
curTime < comp.NextUpdate ||
|
curTime < comp.NextUpdate ||
|
||||||
!_gridQuery.TryGetComponent(uid, out var mapGridComp))
|
!_mapGridQuery.TryGetComponent(uid, out var mapGridComp))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,7 @@ public sealed partial class PathfindingSystem
|
|||||||
{
|
{
|
||||||
if (!_fixturesQuery.TryGetComponent(ev.Sender, out var fixtures) ||
|
if (!_fixturesQuery.TryGetComponent(ev.Sender, out var fixtures) ||
|
||||||
!IsBodyRelevant(fixtures) ||
|
!IsBodyRelevant(fixtures) ||
|
||||||
_gridQuery.HasComponent(ev.Sender))
|
_mapGridQuery.HasComponent(ev.Sender))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ public sealed partial class PathfindingSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xform = _xformQuery.GetComponent(ent);
|
var xform = Transform(ent);
|
||||||
|
|
||||||
if (xform.ParentUid != grid.Owner ||
|
if (xform.ParentUid != grid.Owner ||
|
||||||
_maps.LocalToTile(grid.Owner, grid.Comp, xform.Coordinates) != tilePos)
|
_maps.LocalToTile(grid.Owner, grid.Comp, xform.Coordinates) != tilePos)
|
||||||
@@ -494,7 +494,7 @@ public sealed partial class PathfindingSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!intersects ||
|
if (!intersects ||
|
||||||
!_xformQuery.TryGetComponent(ent, out var xform))
|
!TryComp(ent, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -513,7 +513,7 @@ public sealed partial class PathfindingSystem
|
|||||||
if (!colliding)
|
if (!colliding)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_accessQuery.HasComponent(ent))
|
if (_accessReaderQuery.HasComponent(ent))
|
||||||
{
|
{
|
||||||
flags |= PathfindingBreadcrumbFlag.Access;
|
flags |= PathfindingBreadcrumbFlag.Access;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
[Dependency] private SharedPhysicsSystem _physics = default!;
|
[Dependency] private SharedPhysicsSystem _physics = default!;
|
||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<AccessReaderComponent> _accessReaderQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<DestructibleComponent> _destructibleQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<DoorComponent> _doorQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<ClimbableComponent> _climbableQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<FixturesComponent> _fixturesQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<MapGridComponent> _mapGridQuery = default!;
|
||||||
|
|
||||||
private readonly Dictionary<ICommonSession, PathfindingDebugMode> _subscribedSessions = new();
|
private readonly Dictionary<ICommonSession, PathfindingDebugMode> _subscribedSessions = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
@@ -68,26 +75,9 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
private int _portalIndex;
|
private int _portalIndex;
|
||||||
private readonly Dictionary<int, PathPortal> _portals = new();
|
private readonly Dictionary<int, PathPortal> _portals = new();
|
||||||
|
|
||||||
private EntityQuery<AccessReaderComponent> _accessQuery;
|
|
||||||
private EntityQuery<DestructibleComponent> _destructibleQuery;
|
|
||||||
private EntityQuery<DoorComponent> _doorQuery;
|
|
||||||
private EntityQuery<ClimbableComponent> _climbableQuery;
|
|
||||||
private EntityQuery<FixturesComponent> _fixturesQuery;
|
|
||||||
private EntityQuery<MapGridComponent> _gridQuery;
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_accessQuery = GetEntityQuery<AccessReaderComponent>();
|
|
||||||
_destructibleQuery = GetEntityQuery<DestructibleComponent>();
|
|
||||||
_doorQuery = GetEntityQuery<DoorComponent>();
|
|
||||||
_climbableQuery = GetEntityQuery<ClimbableComponent>();
|
|
||||||
_fixturesQuery = GetEntityQuery<FixturesComponent>();
|
|
||||||
_gridQuery = GetEntityQuery<MapGridComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
_playerManager.PlayerStatusChanged += OnPlayerChange;
|
_playerManager.PlayerStatusChanged += OnPlayerChange;
|
||||||
InitializeGrid();
|
InitializeGrid();
|
||||||
SubscribeNetworkEvent<RequestPathfindingDebugMessage>(OnBreadcrumbs);
|
SubscribeNetworkEvent<RequestPathfindingDebugMessage>(OnBreadcrumbs);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Content.Server.NPC.Components;
|
|||||||
using Content.Shared.CombatMode;
|
using Content.Shared.CombatMode;
|
||||||
using Content.Shared.NPC;
|
using Content.Shared.NPC;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Physics.Components;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.NPC.Systems;
|
namespace Content.Server.NPC.Systems;
|
||||||
@@ -38,25 +37,22 @@ public sealed partial class NPCCombatSystem
|
|||||||
|
|
||||||
private void UpdateMelee(float frameTime)
|
private void UpdateMelee(float frameTime)
|
||||||
{
|
{
|
||||||
var combatQuery = GetEntityQuery<CombatModeComponent>();
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
var physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
var curTime = _timing.CurTime;
|
var curTime = _timing.CurTime;
|
||||||
var query = EntityQueryEnumerator<NPCMeleeCombatComponent, ActiveNPCComponent>();
|
var query = EntityQueryEnumerator<NPCMeleeCombatComponent, ActiveNPCComponent>();
|
||||||
|
|
||||||
while (query.MoveNext(out var uid, out var comp, out _))
|
while (query.MoveNext(out var uid, out var comp, out _))
|
||||||
{
|
{
|
||||||
if (!combatQuery.TryGetComponent(uid, out var combat) || !combat.IsInCombatMode)
|
if (!_combatQuery.TryGetComponent(uid, out var combat) || !combat.IsInCombatMode)
|
||||||
{
|
{
|
||||||
RemComp<NPCMeleeCombatComponent>(uid);
|
RemComp<NPCMeleeCombatComponent>(uid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Attack(uid, comp, curTime, physicsQuery, xformQuery);
|
Attack(uid, comp, curTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Attack(EntityUid uid, NPCMeleeCombatComponent component, TimeSpan curTime, EntityQuery<PhysicsComponent> physicsQuery, EntityQuery<TransformComponent> xformQuery)
|
private void Attack(EntityUid uid, NPCMeleeCombatComponent component, TimeSpan curTime)
|
||||||
{
|
{
|
||||||
component.Status = CombatStatus.Normal;
|
component.Status = CombatStatus.Normal;
|
||||||
|
|
||||||
@@ -66,8 +62,8 @@ public sealed partial class NPCCombatSystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!xformQuery.TryGetComponent(uid, out var xform) ||
|
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||||
!xformQuery.TryGetComponent(component.Target, out var targetXform))
|
!TryComp(component.Target, out TransformComponent? targetXform))
|
||||||
{
|
{
|
||||||
component.Status = CombatStatus.TargetUnreachable;
|
component.Status = CombatStatus.TargetUnreachable;
|
||||||
return;
|
return;
|
||||||
@@ -105,7 +101,7 @@ public sealed partial class NPCCombatSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (_random.Prob(component.MissChance) &&
|
if (_random.Prob(component.MissChance) &&
|
||||||
physicsQuery.TryGetComponent(component.Target, out var targetPhysics) &&
|
_physicsQuery.TryGetComponent(component.Target, out var targetPhysics) &&
|
||||||
targetPhysics.LinearVelocity.LengthSquared() != 0f)
|
targetPhysics.LinearVelocity.LengthSquared() != 0f)
|
||||||
{
|
{
|
||||||
_melee.AttemptLightAttackMiss(uid, weaponUid, weapon, targetXform.Coordinates.Offset(_random.NextVector2(0.5f)));
|
_melee.AttemptLightAttackMiss(uid, weaponUid, weapon, targetXform.Coordinates.Offset(_random.NextVector2(0.5f)));
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ public sealed partial class NPCCombatSystem
|
|||||||
[Dependency] private SharedCombatModeSystem _combat = default!;
|
[Dependency] private SharedCombatModeSystem _combat = default!;
|
||||||
[Dependency] private RotateToFaceSystem _rotate = default!;
|
[Dependency] private RotateToFaceSystem _rotate = default!;
|
||||||
|
|
||||||
private EntityQuery<CombatModeComponent> _combatQuery;
|
[Dependency] private EntityQuery<CombatModeComponent> _combatQuery = default!;
|
||||||
private EntityQuery<NPCSteeringComponent> _steeringQuery;
|
[Dependency] private EntityQuery<NPCSteeringComponent> _steeringQuery = default!;
|
||||||
private EntityQuery<RechargeBasicEntityAmmoComponent> _rechargeQuery;
|
[Dependency] private EntityQuery<RechargeBasicEntityAmmoComponent> _rechargeQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
[Dependency] private EntityQuery<TransformComponent> _xformQuery = default!;
|
||||||
|
|
||||||
// TODO: Don't predict for hitscan
|
// TODO: Don't predict for hitscan
|
||||||
private const float ShootSpeed = 20f;
|
private const float ShootSpeed = 20f;
|
||||||
@@ -30,12 +30,6 @@ public sealed partial class NPCCombatSystem
|
|||||||
|
|
||||||
private void InitializeRanged()
|
private void InitializeRanged()
|
||||||
{
|
{
|
||||||
_combatQuery = GetEntityQuery<CombatModeComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
_rechargeQuery = GetEntityQuery<RechargeBasicEntityAmmoComponent>();
|
|
||||||
_steeringQuery = GetEntityQuery<NPCSteeringComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentStartup>(OnRangedStartup);
|
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentStartup>(OnRangedStartup);
|
||||||
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentShutdown>(OnRangedShutdown);
|
SubscribeLocalEvent<NPCRangedCombatComponent, ComponentShutdown>(OnRangedShutdown);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Server.NPC.Components;
|
using Content.Server.NPC.Components;
|
||||||
using Content.Server.NPC.Events;
|
using Content.Server.NPC.Events;
|
||||||
using Content.Server.NPC.HTN.PrimitiveTasks.Operators.Combat;
|
|
||||||
using Content.Server.Weapons.Melee;
|
using Content.Server.Weapons.Melee;
|
||||||
using Content.Shared.NPC;
|
using Content.Shared.NPC;
|
||||||
using Content.Shared.Weapons.Melee;
|
|
||||||
using Robust.Shared.Collections;
|
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Physics.Components;
|
using Robust.Shared.Physics.Components;
|
||||||
using Robust.Shared.Physics.Systems;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -23,17 +19,13 @@ public sealed partial class NPCJukeSystem : EntitySystem
|
|||||||
[Dependency] private SharedMapSystem _mapSystem = default!;
|
[Dependency] private SharedMapSystem _mapSystem = default!;
|
||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
private EntityQuery<NPCMeleeCombatComponent> _npcMeleeQuery;
|
[Dependency] private EntityQuery<NPCMeleeCombatComponent> _npcMeleeQuery = default!;
|
||||||
private EntityQuery<NPCRangedCombatComponent> _npcRangedQuery;
|
[Dependency] private EntityQuery<NPCRangedCombatComponent> _npcRangedQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_npcMeleeQuery = GetEntityQuery<NPCMeleeCombatComponent>();
|
|
||||||
_npcRangedQuery = GetEntityQuery<NPCRangedCombatComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<NPCJukeComponent, NPCSteeringEvent>(OnJukeSteering);
|
SubscribeLocalEvent<NPCJukeComponent, NPCSteeringEvent>(OnJukeSteering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
using Content.Server.Destructible;
|
using Content.Server.Destructible;
|
||||||
using Content.Server.NPC.Components;
|
using Content.Server.NPC.Components;
|
||||||
using Content.Server.NPC.Pathfinding;
|
using Content.Server.NPC.Pathfinding;
|
||||||
using Content.Shared.Climbing;
|
|
||||||
using Content.Shared.CombatMode;
|
using Content.Shared.CombatMode;
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.Doors.Components;
|
using Content.Shared.Doors.Components;
|
||||||
using Content.Shared.NPC;
|
using Content.Shared.NPC;
|
||||||
using Robust.Shared.Map.Components;
|
using Robust.Shared.Map.Components;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Physics.Components;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using ClimbableComponent = Content.Shared.Climbing.Components.ClimbableComponent;
|
using ClimbableComponent = Content.Shared.Climbing.Components.ClimbableComponent;
|
||||||
using ClimbingComponent = Content.Shared.Climbing.Components.ClimbingComponent;
|
using ClimbingComponent = Content.Shared.Climbing.Components.ClimbingComponent;
|
||||||
using Robust.Shared.Random;
|
|
||||||
|
|
||||||
namespace Content.Server.NPC.Systems;
|
namespace Content.Server.NPC.Systems;
|
||||||
|
|
||||||
@@ -37,6 +34,9 @@ public sealed partial class NPCSteeringSystem
|
|||||||
* Also need to make sure it picks nearest obstacle path so it starts smashing in front of it.
|
* Also need to make sure it picks nearest obstacle path so it starts smashing in front of it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<DoorComponent> _doorQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<ClimbableComponent> _climbableQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<DestructibleComponent> _destructibleQuery = default!;
|
||||||
|
|
||||||
private SteeringObstacleStatus TryHandleFlags(EntityUid uid, NPCSteeringComponent component, PathPoly poly)
|
private SteeringObstacleStatus TryHandleFlags(EntityUid uid, NPCSteeringComponent component, PathPoly poly)
|
||||||
{
|
{
|
||||||
@@ -84,12 +84,10 @@ public sealed partial class NPCSteeringSystem
|
|||||||
// Just walk into it stupid
|
// Just walk into it stupid
|
||||||
if (isDoor && !isAccessRequired)
|
if (isDoor && !isAccessRequired)
|
||||||
{
|
{
|
||||||
var doorQuery = GetEntityQuery<DoorComponent>();
|
|
||||||
|
|
||||||
// ... At least if it's not a bump open.
|
// ... At least if it's not a bump open.
|
||||||
foreach (var ent in obstacleEnts)
|
foreach (var ent in obstacleEnts)
|
||||||
{
|
{
|
||||||
if (!doorQuery.TryGetComponent(ent, out var door))
|
if (!_doorQuery.TryGetComponent(ent, out var door))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!door.BumpOpen && (component.Flags & PathFlags.Interact) != 0x0)
|
if (!door.BumpOpen && (component.Flags & PathFlags.Interact) != 0x0)
|
||||||
@@ -107,12 +105,10 @@ public sealed partial class NPCSteeringSystem
|
|||||||
|
|
||||||
if ((component.Flags & PathFlags.Prying) != 0x0 && isDoor)
|
if ((component.Flags & PathFlags.Prying) != 0x0 && isDoor)
|
||||||
{
|
{
|
||||||
var doorQuery = GetEntityQuery<DoorComponent>();
|
|
||||||
|
|
||||||
// Get the relevant obstacle
|
// Get the relevant obstacle
|
||||||
foreach (var ent in obstacleEnts)
|
foreach (var ent in obstacleEnts)
|
||||||
{
|
{
|
||||||
if (doorQuery.TryGetComponent(ent, out var door) && door.State != DoorState.Open)
|
if (_doorQuery.TryGetComponent(ent, out var door) && door.State != DoorState.Open)
|
||||||
{
|
{
|
||||||
// TODO: Use the verb.
|
// TODO: Use the verb.
|
||||||
|
|
||||||
@@ -141,12 +137,10 @@ public sealed partial class NPCSteeringSystem
|
|||||||
return SteeringObstacleStatus.Continuing;
|
return SteeringObstacleStatus.Continuing;
|
||||||
}
|
}
|
||||||
|
|
||||||
var climbableQuery = GetEntityQuery<ClimbableComponent>();
|
|
||||||
|
|
||||||
// Get the relevant obstacle
|
// Get the relevant obstacle
|
||||||
foreach (var ent in obstacleEnts)
|
foreach (var ent in obstacleEnts)
|
||||||
{
|
{
|
||||||
if (climbableQuery.TryGetComponent(ent, out var table) &&
|
if (_climbableQuery.TryGetComponent(ent, out var table) &&
|
||||||
_climb.CanVault(table, uid, uid, out _) &&
|
_climb.CanVault(table, uid, uid, out _) &&
|
||||||
_climb.TryClimb(uid, uid, ent, out id, table, climbing))
|
_climb.TryClimb(uid, uid, ent, out id, table, climbing))
|
||||||
{
|
{
|
||||||
@@ -165,8 +159,6 @@ public sealed partial class NPCSteeringSystem
|
|||||||
if (_melee.TryGetWeapon(uid, out _, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp<CombatModeComponent>(uid, out var combatMode))
|
if (_melee.TryGetWeapon(uid, out _, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp<CombatModeComponent>(uid, out var combatMode))
|
||||||
{
|
{
|
||||||
_combat.SetInCombatMode(uid, true, combatMode);
|
_combat.SetInCombatMode(uid, true, combatMode);
|
||||||
var destructibleQuery = GetEntityQuery<DestructibleComponent>();
|
|
||||||
|
|
||||||
// TODO: This is a hack around grilles and windows.
|
// TODO: This is a hack around grilles and windows.
|
||||||
_random.Shuffle(obstacleEnts);
|
_random.Shuffle(obstacleEnts);
|
||||||
var attackResult = false;
|
var attackResult = false;
|
||||||
@@ -174,7 +166,7 @@ public sealed partial class NPCSteeringSystem
|
|||||||
foreach (var ent in obstacleEnts)
|
foreach (var ent in obstacleEnts)
|
||||||
{
|
{
|
||||||
// TODO: Validate we can damage it
|
// TODO: Validate we can damage it
|
||||||
if (destructibleQuery.HasComponent(ent))
|
if (_destructibleQuery.HasComponent(ent))
|
||||||
{
|
{
|
||||||
attackResult = _melee.AttemptLightAttack(uid, uid, meleeWeapon, ent);
|
attackResult = _melee.AttemptLightAttack(uid, uid, meleeWeapon, ent);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -68,11 +68,11 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem
|
|||||||
[Dependency] private SharedTransformSystem _transform = default!;
|
[Dependency] private SharedTransformSystem _transform = default!;
|
||||||
[Dependency] private SharedCombatModeSystem _combat = default!;
|
[Dependency] private SharedCombatModeSystem _combat = default!;
|
||||||
|
|
||||||
private EntityQuery<FixturesComponent> _fixturesQuery;
|
[Dependency] private EntityQuery<FixturesComponent> _fixturesQuery = default!;
|
||||||
private EntityQuery<MovementSpeedModifierComponent> _modifierQuery;
|
[Dependency] private EntityQuery<MovementSpeedModifierComponent> _modifierQuery = default!;
|
||||||
private EntityQuery<NpcFactionMemberComponent> _factionQuery;
|
[Dependency] private EntityQuery<NpcFactionMemberComponent> _factionQuery = default!;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
[Dependency] private EntityQuery<PhysicsComponent> _physicsQuery = default!;
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
[Dependency] private EntityQuery<TransformComponent> _xformQuery = default!;
|
||||||
|
|
||||||
private ObjectPool<HashSet<EntityUid>> _entSetPool =
|
private ObjectPool<HashSet<EntityUid>> _entSetPool =
|
||||||
new DefaultObjectPool<HashSet<EntityUid>>(new SetPolicy<EntityUid>());
|
new DefaultObjectPool<HashSet<EntityUid>>(new SetPolicy<EntityUid>());
|
||||||
@@ -99,11 +99,6 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
Log.Level = LogLevel.Info;
|
Log.Level = LogLevel.Info;
|
||||||
_fixturesQuery = GetEntityQuery<FixturesComponent>();
|
|
||||||
_modifierQuery = GetEntityQuery<MovementSpeedModifierComponent>();
|
|
||||||
_factionQuery = GetEntityQuery<NpcFactionMemberComponent>();
|
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
for (var i = 0; i < InterestDirections; i++)
|
for (var i = 0; i < InterestDirections; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,9 +60,7 @@ public sealed partial class NPCUtilitySystem : EntitySystem
|
|||||||
[Dependency] private TurretTargetSettingsSystem _turretTargetSettings = default!;
|
[Dependency] private TurretTargetSettingsSystem _turretTargetSettings = default!;
|
||||||
[Dependency] private DamageableSystem _damageable = default!;
|
[Dependency] private DamageableSystem _damageable = default!;
|
||||||
[Dependency] private SharedStealthSystem _stealth = default!;
|
[Dependency] private SharedStealthSystem _stealth = default!;
|
||||||
|
[Dependency] private EntityQuery<PuddleComponent> _puddleQuery = default!;
|
||||||
private EntityQuery<PuddleComponent> _puddleQuery;
|
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
|
||||||
|
|
||||||
private ObjectPool<HashSet<EntityUid>> _entPool =
|
private ObjectPool<HashSet<EntityUid>> _entPool =
|
||||||
new DefaultObjectPool<HashSet<EntityUid>>(new SetPolicy<EntityUid>(), 256);
|
new DefaultObjectPool<HashSet<EntityUid>>(new SetPolicy<EntityUid>(), 256);
|
||||||
@@ -72,13 +70,6 @@ public sealed partial class NPCUtilitySystem : EntitySystem
|
|||||||
private HashSet<Entity<IComponent>> _entitySet = new();
|
private HashSet<Entity<IComponent>> _entitySet = new();
|
||||||
private List<EntityPrototype.ComponentRegistryEntry> _compTypes = new();
|
private List<EntityPrototype.ComponentRegistryEntry> _compTypes = new();
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
_puddleQuery = GetEntityQuery<PuddleComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs the UtilityQueryPrototype and returns the best-matching entities.
|
/// Runs the UtilityQueryPrototype and returns the best-matching entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -429,7 +420,7 @@ public sealed partial class NPCUtilitySystem : EntitySystem
|
|||||||
if (compQuery.Components.Count == 0)
|
if (compQuery.Components.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var mapPos = _transform.GetMapCoordinates(owner, xform: _xformQuery.GetComponent(owner));
|
var mapPos = _transform.GetMapCoordinates(owner, xform: Transform(owner));
|
||||||
_compTypes.Clear();
|
_compTypes.Clear();
|
||||||
var i = -1;
|
var i = -1;
|
||||||
EntityPrototype.ComponentRegistryEntry compZero = default!;
|
EntityPrototype.ComponentRegistryEntry compZero = default!;
|
||||||
@@ -507,7 +498,7 @@ public sealed partial class NPCUtilitySystem : EntitySystem
|
|||||||
private void RecursiveAdd(EntityUid uid, HashSet<EntityUid> entities)
|
private void RecursiveAdd(EntityUid uid, HashSet<EntityUid> entities)
|
||||||
{
|
{
|
||||||
// TODO: Probably need a recursive struct enumerator on engine.
|
// TODO: Probably need a recursive struct enumerator on engine.
|
||||||
var xform = _xformQuery.GetComponent(uid);
|
var xform = Transform(uid);
|
||||||
var enumerator = xform.ChildEnumerator;
|
var enumerator = xform.ChildEnumerator;
|
||||||
entities.Add(uid);
|
entities.Add(uid);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ public sealed partial class SpaceNinjaSystem : SharedSpaceNinjaSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<SpaceNinjaComponent, EmaggedSomethingEvent>(OnDoorjack);
|
|
||||||
SubscribeLocalEvent<SpaceNinjaComponent, ResearchStolenEvent>(OnResearchStolen);
|
SubscribeLocalEvent<SpaceNinjaComponent, ResearchStolenEvent>(OnResearchStolen);
|
||||||
SubscribeLocalEvent<SpaceNinjaComponent, ThreatCalledInEvent>(OnThreatCalledIn);
|
SubscribeLocalEvent<SpaceNinjaComponent, ThreatCalledInEvent>(OnThreatCalledIn);
|
||||||
SubscribeLocalEvent<SpaceNinjaComponent, CriminalRecordsHackedEvent>(OnCriminalRecordsHacked);
|
SubscribeLocalEvent<SpaceNinjaComponent, CriminalRecordsHackedEvent>(OnCriminalRecordsHacked);
|
||||||
@@ -113,23 +112,6 @@ public sealed partial class SpaceNinjaSystem : SharedSpaceNinjaSystem
|
|||||||
return GetNinjaBattery(user, out var uid, out var battery) && _battery.TryUseCharge((uid.Value, battery), charge);
|
return GetNinjaBattery(user, out var uid, out var battery) && _battery.TryUseCharge((uid.Value, battery), charge);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Increment greentext when emagging a door.
|
|
||||||
/// </summary>
|
|
||||||
private void OnDoorjack(EntityUid uid, SpaceNinjaComponent comp, ref EmaggedSomethingEvent args)
|
|
||||||
{
|
|
||||||
// incase someone lets ninja emag non-doors double check it here
|
|
||||||
if (!HasComp<DoorComponent>(args.Target))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// this popup is serverside since door emag logic is serverside (power funnies)
|
|
||||||
Popup.PopupEntity(Loc.GetString("ninja-doorjack-success", ("target", Identity.Entity(args.Target, EntityManager))), uid, uid, PopupType.Medium);
|
|
||||||
|
|
||||||
// handle greentext
|
|
||||||
if (_mind.TryGetObjectiveComp<DoorjackConditionComponent>(uid, out var obj))
|
|
||||||
obj.DoorsJacked++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add to greentext when stealing technologies.
|
/// Add to greentext when stealing technologies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
public sealed partial class NodeContainerSystem : SharedNodeContainerSystem
|
public sealed partial class NodeContainerSystem : SharedNodeContainerSystem
|
||||||
{
|
{
|
||||||
[Dependency] private NodeGroupSystem _nodeGroupSystem = default!;
|
[Dependency] private NodeGroupSystem _nodeGroupSystem = default!;
|
||||||
private EntityQuery<NodeContainerComponent> _query;
|
[Dependency] private EntityQuery<NodeContainerComponent> _nodeContainerQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -29,8 +29,6 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
SubscribeLocalEvent<NodeContainerComponent, ReAnchorEvent>(OnReAnchor);
|
SubscribeLocalEvent<NodeContainerComponent, ReAnchorEvent>(OnReAnchor);
|
||||||
SubscribeLocalEvent<NodeContainerComponent, MoveEvent>(OnMoveEvent);
|
SubscribeLocalEvent<NodeContainerComponent, MoveEvent>(OnMoveEvent);
|
||||||
SubscribeLocalEvent<NodeContainerComponent, ExaminedEvent>(OnExamine);
|
SubscribeLocalEvent<NodeContainerComponent, ExaminedEvent>(OnExamine);
|
||||||
|
|
||||||
_query = GetEntityQuery<NodeContainerComponent>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetNode<T>(NodeContainerComponent component, string? identifier, [NotNullWhen(true)] out T? node) where T : Node
|
public bool TryGetNode<T>(NodeContainerComponent component, string? identifier, [NotNullWhen(true)] out T? node) where T : Node
|
||||||
@@ -53,7 +51,7 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
|
|
||||||
public bool TryGetNode<T>(Entity<NodeContainerComponent?> ent, string identifier, [NotNullWhen(true)] out T? node) where T : Node
|
public bool TryGetNode<T>(Entity<NodeContainerComponent?> ent, string identifier, [NotNullWhen(true)] out T? node) where T : Node
|
||||||
{
|
{
|
||||||
if (_query.Resolve(ent, ref ent.Comp, false)
|
if (_nodeContainerQuery.Resolve(ent, ref ent.Comp, false)
|
||||||
&& ent.Comp.Nodes.TryGetValue(identifier, out var n)
|
&& ent.Comp.Nodes.TryGetValue(identifier, out var n)
|
||||||
&& n is T t)
|
&& n is T t)
|
||||||
{
|
{
|
||||||
@@ -74,7 +72,7 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
where T1 : Node
|
where T1 : Node
|
||||||
where T2 : Node
|
where T2 : Node
|
||||||
{
|
{
|
||||||
if (_query.Resolve(ent, ref ent.Comp, false)
|
if (_nodeContainerQuery.Resolve(ent, ref ent.Comp, false)
|
||||||
&& ent.Comp.Nodes.TryGetValue(id1, out var n1)
|
&& ent.Comp.Nodes.TryGetValue(id1, out var n1)
|
||||||
&& n1 is T1 t1
|
&& n1 is T1 t1
|
||||||
&& ent.Comp.Nodes.TryGetValue(id2, out var n2)
|
&& ent.Comp.Nodes.TryGetValue(id2, out var n2)
|
||||||
@@ -102,7 +100,7 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
where T2 : Node
|
where T2 : Node
|
||||||
where T3 : Node
|
where T3 : Node
|
||||||
{
|
{
|
||||||
if (_query.Resolve(ent, ref ent.Comp, false)
|
if (_nodeContainerQuery.Resolve(ent, ref ent.Comp, false)
|
||||||
&& ent.Comp.Nodes.TryGetValue(id1, out var n1)
|
&& ent.Comp.Nodes.TryGetValue(id1, out var n1)
|
||||||
&& n1 is T1 t1
|
&& n1 is T1 t1
|
||||||
&& ent.Comp.Nodes.TryGetValue(id2, out var n2)
|
&& ent.Comp.Nodes.TryGetValue(id2, out var n2)
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
[Dependency] private IAdminManager _adminManager = default!;
|
[Dependency] private IAdminManager _adminManager = default!;
|
||||||
[Dependency] private INodeGroupFactory _nodeGroupFactory = default!;
|
[Dependency] private INodeGroupFactory _nodeGroupFactory = default!;
|
||||||
[Dependency] private ILogManager _logManager = default!;
|
[Dependency] private ILogManager _logManager = default!;
|
||||||
|
[Dependency] private EntityQuery<NodeContainerComponent> _nodeContainerQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<TransformComponent> _xformQuery = default!;
|
||||||
|
|
||||||
private readonly List<int> _visDeletes = new();
|
private readonly List<int> _visDeletes = new();
|
||||||
private readonly List<BaseNodeGroup> _visSends = new();
|
private readonly List<BaseNodeGroup> _visSends = new();
|
||||||
@@ -166,9 +168,6 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
var nodeQuery = GetEntityQuery<NodeContainerComponent>();
|
|
||||||
|
|
||||||
foreach (var toRemove in _toRemove)
|
foreach (var toRemove in _toRemove)
|
||||||
{
|
{
|
||||||
if (toRemove.NodeGroup == null)
|
if (toRemove.NodeGroup == null)
|
||||||
@@ -214,7 +213,7 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
// based on position & anchored neighbours However, here more than one node could be attached to the
|
// based on position & anchored neighbours However, here more than one node could be attached to the
|
||||||
// same parent. So there is probably a better way of doing this.
|
// same parent. So there is probably a better way of doing this.
|
||||||
|
|
||||||
foreach (var compatible in GetCompatibleNodes(node, xformQuery, nodeQuery))
|
foreach (var compatible in GetCompatibleNodes(node))
|
||||||
{
|
{
|
||||||
ClearReachableIfNecessary(compatible);
|
ClearReachableIfNecessary(compatible);
|
||||||
|
|
||||||
@@ -346,20 +345,20 @@ namespace Content.Server.NodeContainer.EntitySystems
|
|||||||
return allNodes;
|
return allNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<Node> GetCompatibleNodes(Node node, EntityQuery<TransformComponent> xformQuery, EntityQuery<NodeContainerComponent> nodeQuery)
|
private IEnumerable<Node> GetCompatibleNodes(Node node)
|
||||||
{
|
{
|
||||||
var xform = xformQuery.GetComponent(node.Owner);
|
var xform = Transform(node.Owner);
|
||||||
Entity<MapGridComponent>? gridEnt = TryComp<MapGridComponent>(xform.GridUid, out var grid) ? (xform.GridUid.Value, grid) : null;
|
Entity<MapGridComponent>? gridEnt = TryComp<MapGridComponent>(xform.GridUid, out var grid) ? (xform.GridUid.Value, grid) : null;
|
||||||
|
|
||||||
if (!node.Connectable(EntityManager, xform))
|
if (!node.Connectable(EntityManager, xform))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
foreach (var reachable in node.GetReachableNodes((node.Owner, xform), nodeQuery, xformQuery, gridEnt, EntityManager))
|
foreach (var reachable in node.GetReachableNodes((node.Owner, xform), _nodeContainerQuery, _xformQuery, gridEnt, EntityManager))
|
||||||
{
|
{
|
||||||
DebugTools.Assert(reachable != node, "GetReachableNodes() should not include self.");
|
DebugTools.Assert(reachable != node, "GetReachableNodes() should not include self.");
|
||||||
|
|
||||||
if (reachable.NodeGroupID == node.NodeGroupID
|
if (reachable.NodeGroupID == node.NodeGroupID
|
||||||
&& reachable.Connectable(EntityManager, xformQuery.GetComponent(reachable.Owner)))
|
&& reachable.Connectable(EntityManager, Transform(reachable.Owner)))
|
||||||
{
|
{
|
||||||
yield return reachable;
|
yield return reachable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,7 @@ namespace Content.Server.Objectives.Components;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Objective condition that requires the player to be a ninja and have doorjacked at least a random number of airlocks.
|
/// Objective condition that requires the player to be a ninja and have doorjacked at least a random number of airlocks.
|
||||||
/// Requires <see cref="NumberObjectiveComponent"/> to function.
|
/// Requires <see cref="NumberObjectiveComponent"/> and <see cref="CounterConditionComponent"/> to function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SharedSpaceNinjaSystem))]
|
[RegisterComponent]
|
||||||
public sealed partial class DoorjackConditionComponent : Component
|
public sealed partial class DoorjackConditionComponent : Component;
|
||||||
{
|
|
||||||
[DataField("doorsJacked"), ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public int DoorsJacked;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Content.Server.Objectives.Components;
|
||||||
|
using Content.Shared.Doors.Components;
|
||||||
|
using Content.Shared.IdentityManagement;
|
||||||
|
using Content.Shared.Mind;
|
||||||
|
using Content.Shared.Ninja.Components;
|
||||||
|
using Content.Shared.Ninja.Systems;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
|
||||||
|
namespace Content.Server.Objectives.Systems;
|
||||||
|
|
||||||
|
public sealed partial class DoorJackObjectiveConditionSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private SharedPopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private SharedMindSystem _mind = default!;
|
||||||
|
[Dependency] private CounterConditionSystem _counterCondition = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<SpaceNinjaComponent, EmaggedSomethingEvent>(OnDoorjack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDoorjack(EntityUid uid, SpaceNinjaComponent comp, ref EmaggedSomethingEvent args)
|
||||||
|
{
|
||||||
|
// incase someone lets ninja emag non-doors double check it here
|
||||||
|
if (!HasComp<DoorComponent>(args.Target))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_mind.TryGetMind(uid, out var mindUid, out var mind))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// this popup is serverside since door emag logic is serverside (power funnies)
|
||||||
|
_popupSystem.PopupEntity(
|
||||||
|
Loc.GetString("ninja-doorjack-success", ("target", Identity.Entity(args.Target, EntityManager))),
|
||||||
|
uid,
|
||||||
|
uid,
|
||||||
|
PopupType.Medium);
|
||||||
|
|
||||||
|
foreach (var obj in _mind.EnumerateObjectives<DoorjackConditionComponent>((mindUid, mind)))
|
||||||
|
{
|
||||||
|
_counterCondition.IncreaseCount(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,9 @@ public sealed partial class HijackShuttleConditionSystem : EntitySystem
|
|||||||
[Dependency] private SharedRoleSystem _role = default!;
|
[Dependency] private SharedRoleSystem _role = default!;
|
||||||
[Dependency] private MobStateSystem _mobState = default!;
|
[Dependency] private MobStateSystem _mobState = default!;
|
||||||
|
|
||||||
|
[Dependency] private EntityQuery<HumanoidProfileComponent> _humanoidsQuery = default!;
|
||||||
|
[Dependency] private EntityQuery<CuffableComponent> _cuffableQuery = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -61,9 +64,6 @@ public sealed partial class HijackShuttleConditionSystem : EntitySystem
|
|||||||
private bool IsShuttleHijacked(EntityUid shuttleGridId, EntityUid mindId)
|
private bool IsShuttleHijacked(EntityUid shuttleGridId, EntityUid mindId)
|
||||||
{
|
{
|
||||||
var gridPlayers = Filter.BroadcastGrid(shuttleGridId).Recipients;
|
var gridPlayers = Filter.BroadcastGrid(shuttleGridId).Recipients;
|
||||||
var humanoids = GetEntityQuery<HumanoidProfileComponent>();
|
|
||||||
var cuffable = GetEntityQuery<CuffableComponent>();
|
|
||||||
EntityQuery<MobStateComponent>();
|
|
||||||
|
|
||||||
var agentOnShuttle = false;
|
var agentOnShuttle = false;
|
||||||
foreach (var player in gridPlayers)
|
foreach (var player in gridPlayers)
|
||||||
@@ -78,7 +78,7 @@ public sealed partial class HijackShuttleConditionSystem : EntitySystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isHumanoid = humanoids.HasComponent(player.AttachedEntity.Value);
|
var isHumanoid = _humanoidsQuery.HasComponent(player.AttachedEntity.Value);
|
||||||
if (!isHumanoid) // Only humanoids count as enemies
|
if (!isHumanoid) // Only humanoids count as enemies
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public sealed partial class HijackShuttleConditionSystem : EntitySystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var isPersonCuffed =
|
var isPersonCuffed =
|
||||||
cuffable.TryGetComponent(player.AttachedEntity.Value, out var cuffed)
|
_cuffableQuery.TryGetComponent(player.AttachedEntity.Value, out var cuffed)
|
||||||
&& cuffed.CuffedHandCount > 0;
|
&& cuffed.CuffedHandCount > 0;
|
||||||
if (isPersonCuffed) // Allow handcuffed
|
if (isPersonCuffed) // Allow handcuffed
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -24,15 +24,12 @@ public sealed partial class MailFraudObjectiveSystem : EntitySystem
|
|||||||
if (_fingerprintReader.IsAllowed(ent.Owner, args.User, out var _, showPopup: false, checkGloves: false))
|
if (_fingerprintReader.IsAllowed(ent.Owner, args.User, out var _, showPopup: false, checkGloves: false))
|
||||||
return; //cutting open your own letter
|
return; //cutting open your own letter
|
||||||
|
|
||||||
if (!_mind.TryGetMind(args.User, out _, out var mind))
|
if (!_mind.TryGetMind(args.User, out var mindUid, out var mind))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var obj in mind.Objectives)
|
foreach (var obj in _mind.EnumerateObjectives<MailFraudConditionComponent>((mindUid, mind)))
|
||||||
{
|
{
|
||||||
if (HasComp<MailFraudConditionComponent>(obj))
|
_counterCondition.IncreaseCount(obj);
|
||||||
{
|
|
||||||
_counterCondition.IncreaseCount(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,30 +22,12 @@ public sealed partial class NinjaConditionsSystem : EntitySystem
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<DoorjackConditionComponent, ObjectiveGetProgressEvent>(OnDoorjackGetProgress);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<SpiderChargeConditionComponent, RequirementCheckEvent>(OnSpiderChargeRequirementCheck);
|
SubscribeLocalEvent<SpiderChargeConditionComponent, RequirementCheckEvent>(OnSpiderChargeRequirementCheck);
|
||||||
SubscribeLocalEvent<SpiderChargeConditionComponent, ObjectiveAfterAssignEvent>(OnSpiderChargeAfterAssign);
|
SubscribeLocalEvent<SpiderChargeConditionComponent, ObjectiveAfterAssignEvent>(OnSpiderChargeAfterAssign);
|
||||||
|
|
||||||
SubscribeLocalEvent<StealResearchConditionComponent, ObjectiveGetProgressEvent>(OnStealResearchGetProgress);
|
SubscribeLocalEvent<StealResearchConditionComponent, ObjectiveGetProgressEvent>(OnStealResearchGetProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// doorjack
|
|
||||||
|
|
||||||
private void OnDoorjackGetProgress(EntityUid uid, DoorjackConditionComponent comp, ref ObjectiveGetProgressEvent args)
|
|
||||||
{
|
|
||||||
args.Progress = DoorjackProgress(comp, _number.GetTarget(uid));
|
|
||||||
}
|
|
||||||
|
|
||||||
private float DoorjackProgress(DoorjackConditionComponent comp, int target)
|
|
||||||
{
|
|
||||||
// prevent divide-by-zero
|
|
||||||
if (target == 0)
|
|
||||||
return 1f;
|
|
||||||
|
|
||||||
return MathF.Min(comp.DoorsJacked / (float) target, 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// spider charge
|
// spider charge
|
||||||
private void OnSpiderChargeRequirementCheck(EntityUid uid, SpiderChargeConditionComponent comp, ref RequirementCheckEvent args)
|
private void OnSpiderChargeRequirementCheck(EntityUid uid, SpiderChargeConditionComponent comp, ref RequirementCheckEvent args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ public sealed partial class StealConditionSystem : EntitySystem
|
|||||||
[Dependency] private SharedInteractionSystem _interaction = default!;
|
[Dependency] private SharedInteractionSystem _interaction = default!;
|
||||||
[Dependency] private SharedObjectivesSystem _objectives = default!;
|
[Dependency] private SharedObjectivesSystem _objectives = default!;
|
||||||
[Dependency] private EntityLookupSystem _lookup = default!;
|
[Dependency] private EntityLookupSystem _lookup = default!;
|
||||||
|
[Dependency] private EntityQuery<ContainerManagerComponent> _containerQuery = default!;
|
||||||
private EntityQuery<ContainerManagerComponent> _containerQuery;
|
|
||||||
|
|
||||||
private HashSet<Entity<TransformComponent>> _nearestEnts = new();
|
private HashSet<Entity<TransformComponent>> _nearestEnts = new();
|
||||||
private HashSet<EntityUid> _countedItems = new();
|
private HashSet<EntityUid> _countedItems = new();
|
||||||
@@ -34,8 +33,6 @@ public sealed partial class StealConditionSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
_containerQuery = GetEntityQuery<ContainerManagerComponent>();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<StealConditionComponent, ObjectiveAssignedEvent>(OnAssigned);
|
SubscribeLocalEvent<StealConditionComponent, ObjectiveAssignedEvent>(OnAssigned);
|
||||||
SubscribeLocalEvent<StealConditionComponent, ObjectiveAfterAssignEvent>(OnAfterAssign);
|
SubscribeLocalEvent<StealConditionComponent, ObjectiveAfterAssignEvent>(OnAfterAssign);
|
||||||
SubscribeLocalEvent<StealConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);
|
SubscribeLocalEvent<StealConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.Atmos;
|
|
||||||
using Content.Server.Atmos.Components;
|
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Decals;
|
using Content.Server.Decals;
|
||||||
using Content.Server.Ghost.Roles.Components;
|
using Content.Server.Ghost.Roles.Components;
|
||||||
using Content.Server.Shuttles.Events;
|
using Content.Server.Shuttles.Events;
|
||||||
using Content.Server.Shuttles.Systems;
|
using Content.Server.Shuttles.Systems;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Decals;
|
|
||||||
using Content.Shared.Ghost;
|
using Content.Shared.Ghost;
|
||||||
using Content.Shared.Gravity;
|
using Content.Shared.Gravity;
|
||||||
using Content.Shared.Light.Components;
|
using Content.Shared.Light.Components;
|
||||||
@@ -53,10 +49,10 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
[Dependency] private ShuttleSystem _shuttles = default!;
|
[Dependency] private ShuttleSystem _shuttles = default!;
|
||||||
[Dependency] private TagSystem _tags = default!;
|
[Dependency] private TagSystem _tags = default!;
|
||||||
|
|
||||||
private EntityQuery<BiomeComponent> _biomeQuery;
|
[Dependency] private EntityQuery<BiomeComponent> _biomeQuery = default!;
|
||||||
private EntityQuery<FixturesComponent> _fixturesQuery;
|
[Dependency] private EntityQuery<FixturesComponent> _fixturesQuery = default!;
|
||||||
private EntityQuery<GhostComponent> _ghostQuery;
|
[Dependency] private EntityQuery<GhostComponent> _ghostQuery = default!;
|
||||||
private EntityQuery<TransformComponent> _xformQuery;
|
[Dependency] private EntityQuery<TransformComponent> _xformQuery = default!;
|
||||||
|
|
||||||
private readonly HashSet<EntityUid> _handledEntities = new();
|
private readonly HashSet<EntityUid> _handledEntities = new();
|
||||||
private const float DefaultLoadRange = 16f;
|
private const float DefaultLoadRange = 16f;
|
||||||
@@ -85,10 +81,6 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
Log.Level = LogLevel.Debug;
|
Log.Level = LogLevel.Debug;
|
||||||
_biomeQuery = GetEntityQuery<BiomeComponent>();
|
|
||||||
_fixturesQuery = GetEntityQuery<FixturesComponent>();
|
|
||||||
_ghostQuery = GetEntityQuery<GhostComponent>();
|
|
||||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
||||||
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
||||||
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
SubscribeLocalEvent<ShuttleFlattenEvent>(OnShuttleFlatten);
|
||||||
@@ -924,11 +916,9 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||||||
// Ideally any entities that aren't modified just get deleted and re-generated later
|
// Ideally any entities that aren't modified just get deleted and re-generated later
|
||||||
// This is because if we want to save the map (e.g. persistent server) it makes the file much smaller
|
// This is because if we want to save the map (e.g. persistent server) it makes the file much smaller
|
||||||
// and also if the map is enormous will make stuff like physics broadphase much faster
|
// and also if the map is enormous will make stuff like physics broadphase much faster
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
|
|
||||||
foreach (var (ent, tile) in component.LoadedEntities[chunk])
|
foreach (var (ent, tile) in component.LoadedEntities[chunk])
|
||||||
{
|
{
|
||||||
if (Deleted(ent) || !xformQuery.TryGetComponent(ent, out var xform))
|
if (Deleted(ent) || !TryComp(ent, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
modified.Add(tile);
|
modified.Add(tile);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+3
-4
@@ -14,8 +14,7 @@ public sealed partial class ParticleAcceleratorSystem
|
|||||||
if (!Resolve(uid, ref emitter))
|
if (!Resolve(uid, ref emitter))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
if (!TryComp(uid, out TransformComponent? xform))
|
||||||
if (!xformQuery.TryGetComponent(uid, out var xform))
|
|
||||||
{
|
{
|
||||||
Log.Error("ParticleAccelerator attempted to emit a particle without (having) a transform from which to base its initial position and orientation.");
|
Log.Error("ParticleAccelerator attempted to emit a particle without (having) a transform from which to base its initial position and orientation.");
|
||||||
return;
|
return;
|
||||||
@@ -23,12 +22,12 @@ public sealed partial class ParticleAcceleratorSystem
|
|||||||
|
|
||||||
var emitted = Spawn(emitter.EmittedPrototype, xform.Coordinates);
|
var emitted = Spawn(emitter.EmittedPrototype, xform.Coordinates);
|
||||||
|
|
||||||
if (xformQuery.TryGetComponent(emitted, out var particleXform))
|
if (TryComp(emitted, out TransformComponent? particleXform))
|
||||||
_transformSystem.SetLocalRotation(emitted, xform.LocalRotation, particleXform);
|
_transformSystem.SetLocalRotation(emitted, xform.LocalRotation, particleXform);
|
||||||
|
|
||||||
if (TryComp<PhysicsComponent>(emitted, out var particlePhys))
|
if (TryComp<PhysicsComponent>(emitted, out var particlePhys))
|
||||||
{
|
{
|
||||||
var angle = _transformSystem.GetWorldRotation(uid, xformQuery);
|
var angle = _transformSystem.GetWorldRotation(uid);
|
||||||
_physicsSystem.SetBodyStatus(emitted, particlePhys, BodyStatus.InAir);
|
_physicsSystem.SetBodyStatus(emitted, particlePhys, BodyStatus.InAir);
|
||||||
|
|
||||||
var velocity = angle.ToWorldVec() * 20f;
|
var velocity = angle.ToWorldVec() * 20f;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user