mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-02-15 01:15:13 +01:00
Merge remote-tracking branch 'refs/remotes/upstream/master' into upstream-sync
# Conflicts: # Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml # Resources/ServerInfo/Guidebook/Mobs/SlimePerson.xml # Resources/Textures/Clothing/Hands/Gloves/Color/yellow.rsi/meta.json # Resources/Textures/Clothing/Shoes/Boots/combatboots.rsi/meta.json # Resources/Textures/Clothing/Shoes/Boots/magboots-science.rsi/meta.json # Resources/Textures/Clothing/Shoes/Boots/speedboots.rsi/meta.json # Resources/Textures/Structures/Wallmounts/signs.rsi/chemistry1.png # Resources/Textures/Structures/Wallmounts/signs.rsi/chemistry2.png # Resources/Textures/Structures/Wallmounts/signs.rsi/court.png # Resources/Textures/Structures/Wallmounts/signs.rsi/deathsposal.png # Resources/Textures/Structures/Wallmounts/signs.rsi/doors.png # Resources/Textures/Structures/Wallmounts/signs.rsi/examroom.png # Resources/Textures/Structures/Wallmounts/signs.rsi/hydro1.png # Resources/Textures/Structures/Wallmounts/signs.rsi/hydro2.png # Resources/Textures/Structures/Wallmounts/signs.rsi/hydro3.png # Resources/Textures/Structures/Wallmounts/signs.rsi/janitor.png # Resources/Textures/Structures/Wallmounts/signs.rsi/law.png # Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json # Resources/Textures/Structures/Wallmounts/signs.rsi/psychology.png # Resources/Textures/Structures/Wallmounts/signs.rsi/science1.png # Resources/Textures/Structures/Wallmounts/signs.rsi/science2.png # Resources/Textures/Structures/Wallmounts/signs.rsi/security.png # Resources/Textures/Structures/Wallmounts/signs.rsi/space.png # Resources/Textures/Structures/Wallmounts/signs.rsi/xenobio.png # Resources/Textures/Structures/Wallmounts/signs.rsi/xenobio2.png # Resources/migration.yml
This commit is contained in:
@@ -129,7 +129,7 @@ csharp_indent_braces = false
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = true
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
|
||||
@@ -12,11 +12,18 @@ namespace Content.Client.Access.UI;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AccessLevelControl : GridContainer
|
||||
{
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public readonly Dictionary<ProtoId<AccessLevelPrototype>, Button> ButtonsList = new();
|
||||
|
||||
public AccessLevelControl()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_sawmill = _logManager.GetSawmill("accesslevelcontrol");
|
||||
}
|
||||
|
||||
public void Populate(List<ProtoId<AccessLevelPrototype>> accessLevels, IPrototypeManager prototypeManager)
|
||||
@@ -25,7 +32,7 @@ public sealed partial class AccessLevelControl : GridContainer
|
||||
{
|
||||
if (!prototypeManager.TryIndex(access, out var accessLevel))
|
||||
{
|
||||
Logger.Error($"Unable to find accesslevel for {access}");
|
||||
_sawmill.Error($"Unable to find accesslevel for {access}");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Content.Client.Actions
|
||||
UpdateAction(uid, component);
|
||||
}
|
||||
|
||||
protected override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
|
||||
public override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
|
||||
{
|
||||
if (!ResolveActionData(actionId, ref action))
|
||||
return;
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
|
||||
public sealed partial class ObjectsTab : Control
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
private readonly Color _altColor = Color.FromHex("#292B38");
|
||||
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
|
||||
|
||||
@@ -54,7 +54,7 @@ public sealed class AudioUIController : UIController
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
var resource = _cache.GetResource<AudioResource>(value);
|
||||
var resource = GetSoundOrFallback(value, CCVars.UIClickSound.DefaultValue);
|
||||
var source =
|
||||
_audioManager.CreateAudioSource(resource);
|
||||
|
||||
@@ -77,7 +77,7 @@ public sealed class AudioUIController : UIController
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
var hoverResource = _cache.GetResource<AudioResource>(value);
|
||||
var hoverResource = GetSoundOrFallback(value, CCVars.UIHoverSound.DefaultValue);
|
||||
var hoverSource =
|
||||
_audioManager.CreateAudioSource(hoverResource);
|
||||
|
||||
@@ -95,4 +95,12 @@ public sealed class AudioUIController : UIController
|
||||
UIManager.SetHoverSound(null);
|
||||
}
|
||||
}
|
||||
|
||||
private AudioResource GetSoundOrFallback(string path, string fallback)
|
||||
{
|
||||
if (!_cache.TryGetResource(path, out AudioResource? resource))
|
||||
return _cache.GetResource<AudioResource>(fallback);
|
||||
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Shared.Audio;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Rules;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.ResourceManagement;
|
||||
|
||||
@@ -31,7 +31,7 @@ public sealed partial class NewsReaderUiFragment : BoxContainer
|
||||
Author.Visible = true;
|
||||
|
||||
PageName.Text = article.Title;
|
||||
PageText.SetMarkup(article.Content);
|
||||
PageText.SetMarkupPermissive(article.Content);
|
||||
|
||||
PageNum.Text = $"{targetNum}/{totalNum}";
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace Content.Client.Construction
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Disposal;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Disposal.UI
|
||||
{
|
||||
@@ -11,6 +12,8 @@ namespace Content.Client.Disposal.UI
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MailingUnitWindow : DefaultWindow
|
||||
{
|
||||
public TimeSpan FullPressure;
|
||||
|
||||
public MailingUnitWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -26,6 +29,7 @@ namespace Content.Client.Disposal.UI
|
||||
|
||||
Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", state.Tag ?? " "));
|
||||
UnitState.Text = disposalState.UnitState;
|
||||
FullPressure = disposalState.FullPressureTime;
|
||||
var pressureReached = PressureBar.UpdatePressure(disposalState.FullPressureTime);
|
||||
Power.Pressed = disposalState.Powered;
|
||||
Engage.Pressed = disposalState.Engaged;
|
||||
@@ -42,9 +46,10 @@ namespace Content.Client.Disposal.UI
|
||||
return !disposalState.Powered || pressureReached;
|
||||
}
|
||||
|
||||
public bool UpdatePressure(TimeSpan stateFullPressureTime)
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
return PressureBar.UpdatePressure(stateFullPressureTime);
|
||||
base.FrameUpdate(args);
|
||||
PressureBar.UpdatePressure(FullPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,24 +25,30 @@ public sealed class FaxVisualsSystem : EntitySystem
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && visuals == FaxMachineVisualState.Inserting)
|
||||
if (_player.HasRunningAnimation(uid, "faxecute"))
|
||||
return;
|
||||
|
||||
if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) &&
|
||||
visuals == FaxMachineVisualState.Inserting)
|
||||
{
|
||||
_player.Play(uid, new Animation()
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(2.4),
|
||||
AnimationTracks =
|
||||
_player.Play(uid,
|
||||
new Animation()
|
||||
{
|
||||
new AnimationTrackSpriteFlick()
|
||||
Length = TimeSpan.FromSeconds(2.4),
|
||||
AnimationTracks =
|
||||
{
|
||||
LayerKey = FaxMachineVisuals.VisualState,
|
||||
KeyFrames =
|
||||
new AnimationTrackSpriteFlick()
|
||||
{
|
||||
new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
|
||||
new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "faxecute");
|
||||
LayerKey = FaxMachineVisuals.VisualState,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
|
||||
new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"faxecute");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs
Normal file
29
Content.Client/IconSmoothing/ClientRandomIconSmoothSystem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Content.Shared.IconSmoothing;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.IconSmoothing;
|
||||
|
||||
public sealed class ClientRandomIconSmoothSystem : SharedRandomIconSmoothSystem
|
||||
{
|
||||
[Dependency] private readonly IconSmoothSystem _iconSmooth = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RandomIconSmoothComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(Entity<RandomIconSmoothComponent> ent, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (!TryComp<IconSmoothComponent>(ent, out var smooth))
|
||||
return;
|
||||
|
||||
if (!_appearance.TryGetData<string>(ent, RandomIconSmoothState.State, out var state, args.Component))
|
||||
return;
|
||||
|
||||
smooth.StateBase = state;
|
||||
_iconSmooth.SetStateBase(ent, smooth, state);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Content.Client.IconSmoothing
|
||||
/// Prepended to the RSI state.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("base")]
|
||||
public string StateBase { get; private set; } = string.Empty;
|
||||
public string StateBase { get; set; } = string.Empty;
|
||||
|
||||
[DataField("shader", customTypeSerializer:typeof(PrototypeIdSerializer<ShaderPrototype>))]
|
||||
public string? Shader;
|
||||
|
||||
@@ -55,6 +55,33 @@ namespace Content.Client.IconSmoothing
|
||||
if (component.Mode != IconSmoothingMode.Corners || !TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
SetCornerLayers(sprite, component);
|
||||
|
||||
if (component.Shader != null)
|
||||
{
|
||||
sprite.LayerSetShader(CornerLayers.SE, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.NE, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.NW, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.SW, component.Shader);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStateBase(EntityUid uid, IconSmoothComponent component, string newState)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
component.StateBase = newState;
|
||||
SetCornerLayers(sprite, component);
|
||||
}
|
||||
|
||||
private void SetCornerLayers(SpriteComponent sprite, IconSmoothComponent component)
|
||||
{
|
||||
sprite.LayerMapRemove(CornerLayers.SE);
|
||||
sprite.LayerMapRemove(CornerLayers.NE);
|
||||
sprite.LayerMapRemove(CornerLayers.NW);
|
||||
sprite.LayerMapRemove(CornerLayers.SW);
|
||||
|
||||
var state0 = $"{component.StateBase}0";
|
||||
sprite.LayerMapSet(CornerLayers.SE, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.SE, DirectionOffset.None);
|
||||
@@ -64,14 +91,6 @@ namespace Content.Client.IconSmoothing
|
||||
sprite.LayerSetDirOffset(CornerLayers.NW, DirectionOffset.Flip);
|
||||
sprite.LayerMapSet(CornerLayers.SW, sprite.AddLayerState(state0));
|
||||
sprite.LayerSetDirOffset(CornerLayers.SW, DirectionOffset.Clockwise);
|
||||
|
||||
if (component.Shader != null)
|
||||
{
|
||||
sprite.LayerSetShader(CornerLayers.SE, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.NE, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.NW, component.Shader);
|
||||
sprite.LayerSetShader(CornerLayers.SW, component.Shader);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, IconSmoothComponent component, ComponentShutdown args)
|
||||
|
||||
@@ -21,7 +21,6 @@ public sealed partial class LatheMenu : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IResourceCache _resources = default!;
|
||||
|
||||
private EntityUid _owner;
|
||||
private readonly SpriteSystem _spriteSystem;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Shared.Research;
|
||||
using Content.Shared.Research.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Research.UI
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Research.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Research.UI
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Shared.Research.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Research.UI;
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state)
|
||||
{
|
||||
var amountMsg = new FormattedMessage();
|
||||
amountMsg.AddMarkup(Loc.GetString("research-console-menu-research-points-text",
|
||||
amountMsg.AddMarkupOrThrow(Loc.GetString("research-console-menu-research-points-text",
|
||||
("points", state.Points)));
|
||||
ResearchAmountLabel.SetMessage(amountMsg);
|
||||
|
||||
@@ -98,7 +98,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
}
|
||||
|
||||
var msg = new FormattedMessage();
|
||||
msg.AddMarkup(Loc.GetString("research-console-menu-main-discipline",
|
||||
msg.AddMarkupOrThrow(Loc.GetString("research-console-menu-main-discipline",
|
||||
("name", disciplineText), ("color", disciplineColor)));
|
||||
MainDisciplineLabel.SetMessage(msg);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed partial class TechnologyCardControl : Control
|
||||
DisciplineTexture.Texture = spriteSys.Frame0(discipline.Icon);
|
||||
TechnologyNameLabel.Text = Loc.GetString(technology.Name);
|
||||
var message = new FormattedMessage();
|
||||
message.AddMarkup(Loc.GetString("research-console-tier-discipline-info",
|
||||
message.AddMarkupOrThrow(Loc.GetString("research-console-tier-discipline-info",
|
||||
("tier", technology.Tier), ("color", discipline.Color), ("discipline", Loc.GetString(discipline.Name))));
|
||||
TierLabel.SetMessage(message);
|
||||
UnlocksLabel.SetMessage(description);
|
||||
|
||||
@@ -1343,6 +1343,9 @@ namespace Content.Client.Stylesheets
|
||||
new StyleProperty(Label.StylePropertyAlignMode, Label.AlignMode.Center),
|
||||
}),
|
||||
|
||||
Element<PanelContainer>().Class(OptionButton.StyleClassOptionsBackground)
|
||||
.Prop(PanelContainer.StylePropertyPanel, new StyleBoxFlat(Color.FromHex("#25252A"))),
|
||||
|
||||
new StyleRule(new SelectorElement(typeof(PanelContainer), new []{ ClassHighDivider}, null, null), new []
|
||||
{
|
||||
new StyleProperty(PanelContainer.StylePropertyPanel, new StyleBoxFlat { BackgroundColor = NanoGold, ContentMarginBottomOverride = 2, ContentMarginLeftOverride = 2}),
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Linq;
|
||||
using Content.Client.CharacterInfo;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.Character.Controls;
|
||||
using Content.Client.UserInterface.Systems.Character.Windows;
|
||||
using Content.Client.UserInterface.Systems.Objectives.Controls;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Objectives.Systems;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
@@ -121,11 +123,17 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
|
||||
Modulate = Color.Gray
|
||||
};
|
||||
|
||||
objectiveControl.AddChild(new Label
|
||||
|
||||
var objectiveText = new FormattedMessage();
|
||||
objectiveText.TryAddMarkup(groupId, out _);
|
||||
|
||||
var objectiveLabel = new RichTextLabel
|
||||
{
|
||||
Text = groupId,
|
||||
Modulate = Color.LightSkyBlue
|
||||
});
|
||||
StyleClasses = {StyleNano.StyleClassTooltipActionTitle}
|
||||
};
|
||||
objectiveLabel.SetMessage(objectiveText);
|
||||
|
||||
objectiveControl.AddChild(objectiveLabel);
|
||||
|
||||
foreach (var condition in conditions)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Content.Client.VendingMachines.UI
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
private readonly Dictionary<EntProtoId, EntityUid> _dummies = [];
|
||||
|
||||
|
||||
@@ -904,6 +904,9 @@ namespace Content.Server.Database
|
||||
Panic = 3,
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*
|
||||
* If baby jail is removed, please reserve this value for as long as can reasonably be done to prevent causing ambiguity in connection denial reasons.
|
||||
* Reservation by commenting out the value is likely sufficient for this purpose, but may impact projects which depend on SS14 like SS14.Admin.
|
||||
*/
|
||||
BabyJail = 4,
|
||||
}
|
||||
|
||||
@@ -12,13 +12,12 @@ using Robust.Shared.Console;
|
||||
namespace Content.Server.Administration.Commands;
|
||||
|
||||
[AdminCommand(AdminFlags.Admin)]
|
||||
public sealed class AGhost : LocalizedCommands
|
||||
public sealed class AGhostCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entities = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public override string Command => "aghost";
|
||||
public override string Description => LocalizationManager.GetString("aghost-description");
|
||||
public override string Help => "aghost";
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
@@ -22,8 +22,6 @@ namespace Content.Server.Ame.EntitySystems;
|
||||
public sealed class AmeControllerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
|
||||
@@ -141,7 +141,7 @@ public sealed partial class AnomalySystem
|
||||
var msg = new FormattedMessage();
|
||||
if (component.ScannedAnomaly is not { } anomaly || !TryComp<AnomalyComponent>(anomaly, out var anomalyComp))
|
||||
{
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-no-anomaly"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-no-anomaly"));
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -149,14 +149,14 @@ public sealed partial class AnomalySystem
|
||||
|
||||
//Severity
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Severity))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-severity-percentage-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P"))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P"))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Stability
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Stability))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-stability-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-stability-unknown"));
|
||||
else
|
||||
{
|
||||
string stateLoc;
|
||||
@@ -166,54 +166,54 @@ public sealed partial class AnomalySystem
|
||||
stateLoc = Loc.GetString("anomaly-scanner-stability-high");
|
||||
else
|
||||
stateLoc = Loc.GetString("anomaly-scanner-stability-medium");
|
||||
msg.AddMarkup(stateLoc);
|
||||
msg.AddMarkupOrThrow(stateLoc);
|
||||
}
|
||||
msg.PushNewline();
|
||||
|
||||
//Point output
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.OutputPoint))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-point-output-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp))));
|
||||
msg.PushNewline();
|
||||
msg.PushNewline();
|
||||
|
||||
//Particles title
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-readout"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-readout"));
|
||||
msg.PushNewline();
|
||||
|
||||
//Danger
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleDanger))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-danger-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Unstable
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleUnstable))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-unstable-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Containment
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleContainment))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-containment-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Transformation
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleTransformation))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation-unknown"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-transformation-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType))));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType))));
|
||||
|
||||
|
||||
//Behavior
|
||||
msg.PushNewline();
|
||||
msg.PushNewline();
|
||||
msg.AddMarkup(Loc.GetString("anomaly-behavior-title"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-title"));
|
||||
msg.PushNewline();
|
||||
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Behavior))
|
||||
@@ -224,14 +224,14 @@ public sealed partial class AnomalySystem
|
||||
{
|
||||
var behavior = _prototype.Index(anomalyComp.CurrentBehavior.Value);
|
||||
|
||||
msg.AddMarkup("- " + Loc.GetString(behavior.Description));
|
||||
msg.AddMarkupOrThrow("- " + Loc.GetString(behavior.Description));
|
||||
msg.PushNewline();
|
||||
var mod = Math.Floor((behavior.EarnPointModifier) * 100);
|
||||
msg.AddMarkup("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod)));
|
||||
msg.AddMarkupOrThrow("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod)));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.AddMarkup(Loc.GetString("anomaly-behavior-balanced"));
|
||||
msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-balanced"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Content.Server.Botany.Components
|
||||
/// <summary>
|
||||
/// Name of a base seed prototype that is used if <see cref="Seed"/> is null.
|
||||
/// </summary>
|
||||
[DataField("seedId", customTypeSerializer:typeof(PrototypeIdSerializer<SeedPrototype>))]
|
||||
[DataField("seedId", customTypeSerializer: typeof(PrototypeIdSerializer<SeedPrototype>))]
|
||||
public string? SeedId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using System.Linq;
|
||||
using Content.Shared.Atmos;
|
||||
using FastAccessors;
|
||||
|
||||
namespace Content.Server.Botany;
|
||||
|
||||
@@ -42,6 +40,7 @@ public sealed class MutationSystem : EntitySystem
|
||||
// Add up everything in the bits column and put the number here.
|
||||
const int totalbits = 275;
|
||||
|
||||
#pragma warning disable IDE0055 // disable formatting warnings because this looks more readable
|
||||
// Tolerances (55)
|
||||
MutateFloat(ref seed.NutrientConsumption , 0.05f, 1.2f, 5, totalbits, severity);
|
||||
MutateFloat(ref seed.WaterConsumption , 3f , 9f , 5, totalbits, severity);
|
||||
@@ -75,6 +74,7 @@ public sealed class MutationSystem : EntitySystem
|
||||
MutateBool(ref seed.TurnIntoKudzu , true , 10, totalbits, severity);
|
||||
MutateBool(ref seed.CanScream , true , 10, totalbits, severity);
|
||||
seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity);
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
// ConstantUpgade (10)
|
||||
MutateHarvestType(ref seed.HarvestRepeat, 10, totalbits, severity);
|
||||
@@ -261,7 +261,7 @@ public sealed class MutationSystem : EntitySystem
|
||||
{
|
||||
var pick = _randomChems.Pick(_robustRandom);
|
||||
string chemicalId = pick.reagent;
|
||||
int amount = _robustRandom.Next(1, ((int)pick.quantity));
|
||||
int amount = _robustRandom.Next(1, (int)pick.quantity);
|
||||
SeedChemQuantity seedChemQuantity = new SeedChemQuantity();
|
||||
if (chemicals.ContainsKey(chemicalId))
|
||||
{
|
||||
@@ -274,7 +274,7 @@ public sealed class MutationSystem : EntitySystem
|
||||
seedChemQuantity.Max = 1 + amount;
|
||||
seedChemQuantity.Inherent = false;
|
||||
}
|
||||
int potencyDivisor = (int) Math.Ceiling(100.0f / seedChemQuantity.Max);
|
||||
int potencyDivisor = (int)Math.Ceiling(100.0f / seedChemQuantity.Max);
|
||||
seedChemQuantity.PotencyDivisor = potencyDivisor;
|
||||
chemicals[chemicalId] = seedChemQuantity;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@ public sealed class SeedExtractorSystem : EntitySystem
|
||||
return;
|
||||
if (!_botanySystem.TryGetSeed(produce, out var seed) || seed.Seedless)
|
||||
{
|
||||
_popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-no-seeds",("name", args.Used)),
|
||||
_popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-no-seeds", ("name", args.Used)),
|
||||
args.User, PopupType.MediumCaution);
|
||||
return;
|
||||
}
|
||||
|
||||
_popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message",("name", args.Used)),
|
||||
_popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)),
|
||||
args.User, PopupType.Medium);
|
||||
|
||||
QueueDel(args.Used);
|
||||
|
||||
@@ -36,14 +36,14 @@ public sealed class CharacterInfoSystem : EntitySystem
|
||||
if (_minds.TryGetMind(entity, out var mindId, out var mind))
|
||||
{
|
||||
// Get objectives
|
||||
foreach (var objective in mind.AllObjectives)
|
||||
foreach (var objective in mind.Objectives)
|
||||
{
|
||||
var info = _objectives.GetInfo(objective, mindId, mind);
|
||||
if (info == null)
|
||||
continue;
|
||||
|
||||
// group objectives by their issuer
|
||||
var issuer = Comp<ObjectiveComponent>(objective).Issuer;
|
||||
var issuer = Comp<ObjectiveComponent>(objective).LocIssuer;
|
||||
if (!objectives.ContainsKey(issuer))
|
||||
objectives[issuer] = new List<ObjectiveInfo>();
|
||||
objectives[issuer].Add(info.Value);
|
||||
|
||||
@@ -60,7 +60,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
|
||||
@@ -29,7 +29,6 @@ public sealed class CluwneSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly AutoEmoteSystem _autoEmote = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly NameModifierSystem _nameMod = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
||||
@@ -337,6 +337,12 @@ namespace Content.Server.Connection
|
||||
return (false, "");
|
||||
|
||||
var isAccountAgeInvalid = record.FirstSeenTime.CompareTo(DateTimeOffset.Now - TimeSpan.FromMinutes(maxAccountAgeMinutes)) <= 0;
|
||||
|
||||
if (isAccountAgeInvalid)
|
||||
{
|
||||
_sawmill.Debug($"Baby jail will deny {userId} for account age {record.FirstSeenTime}"); // Remove on or after 2024-09
|
||||
}
|
||||
|
||||
if (isAccountAgeInvalid && showReason)
|
||||
{
|
||||
var locAccountReason = reason != string.Empty
|
||||
@@ -351,7 +357,12 @@ namespace Content.Server.Connection
|
||||
}
|
||||
|
||||
var overallTime = ( await _db.GetPlayTimes(e.UserId)).Find(p => p.Tracker == PlayTimeTrackingShared.TrackerOverall);
|
||||
var isTotalPlaytimeInvalid = overallTime == null || overallTime.TimeSpent.TotalMinutes >= maxPlaytimeMinutes;
|
||||
var isTotalPlaytimeInvalid = overallTime != null && overallTime.TimeSpent.TotalMinutes >= maxPlaytimeMinutes;
|
||||
|
||||
if (isTotalPlaytimeInvalid)
|
||||
{
|
||||
_sawmill.Debug($"Baby jail will deny {userId} for playtime {overallTime!.TimeSpent}"); // Remove on or after 2024-09
|
||||
}
|
||||
|
||||
if (isTotalPlaytimeInvalid && showReason)
|
||||
{
|
||||
|
||||
@@ -32,31 +32,25 @@ namespace Content.Server.Damage.Systems
|
||||
|
||||
private void OnDoHit(EntityUid uid, DamageOtherOnHitComponent component, ThrowDoHitEvent args)
|
||||
{
|
||||
if (!TerminatingOrDeleted(args.Target))
|
||||
if (TerminatingOrDeleted(args.Target))
|
||||
return;
|
||||
|
||||
var dmg = _damageable.TryChangeDamage(args.Target, component.Damage, component.IgnoreResistances, origin: args.Component.Thrower);
|
||||
|
||||
// Log damage only for mobs. Useful for when people throw spears at each other, but also avoids log-spam when explosions send glass shards flying.
|
||||
if (dmg != null && HasComp<MobStateComponent>(args.Target))
|
||||
_adminLogger.Add(LogType.ThrowHit, $"{ToPrettyString(args.Target):target} received {dmg.GetTotal():damage} damage from collision");
|
||||
|
||||
if (dmg is { Empty: false })
|
||||
{
|
||||
var dmg = _damageable.TryChangeDamage(args.Target, component.Damage, component.IgnoreResistances, origin: args.Component.Thrower);
|
||||
|
||||
// Log damage only for mobs. Useful for when people throw spears at each other, but also avoids log-spam when explosions send glass shards flying.
|
||||
if (dmg != null && HasComp<MobStateComponent>(args.Target))
|
||||
_adminLogger.Add(LogType.ThrowHit, $"{ToPrettyString(args.Target):target} received {dmg.GetTotal():damage} damage from collision");
|
||||
|
||||
if (dmg is { Empty: false })
|
||||
{
|
||||
_color.RaiseEffect(Color.Red, new List<EntityUid>() { args.Target }, Filter.Pvs(args.Target, entityManager: EntityManager));
|
||||
}
|
||||
|
||||
_guns.PlayImpactSound(args.Target, dmg, null, false);
|
||||
if (TryComp<PhysicsComponent>(uid, out var body) && body.LinearVelocity.LengthSquared() > 0f)
|
||||
{
|
||||
var direction = body.LinearVelocity.Normalized();
|
||||
_sharedCameraRecoil.KickCamera(args.Target, direction);
|
||||
}
|
||||
_color.RaiseEffect(Color.Red, new List<EntityUid>() { args.Target }, Filter.Pvs(args.Target, entityManager: EntityManager));
|
||||
}
|
||||
|
||||
// TODO: If more stuff touches this then handle it after.
|
||||
if (TryComp<PhysicsComponent>(uid, out var physics))
|
||||
_guns.PlayImpactSound(args.Target, dmg, null, false);
|
||||
if (TryComp<PhysicsComponent>(uid, out var body) && body.LinearVelocity.LengthSquared() > 0f)
|
||||
{
|
||||
_thrownItem.LandComponent(args.Thrown, args.Component, physics, false);
|
||||
var direction = body.LinearVelocity.Normalized();
|
||||
_sharedCameraRecoil.KickCamera(args.Target, direction);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -423,11 +423,11 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
|
||||
if (Delay(configurator))
|
||||
return;
|
||||
|
||||
if (!targetUid.HasValue || !configurator.ActiveDeviceLink.HasValue || !TryComp(userUid, out ActorComponent? actor) || !AccessCheck(targetUid.Value, userUid, configurator))
|
||||
if (!targetUid.HasValue || !configurator.ActiveDeviceLink.HasValue || !AccessCheck(targetUid.Value, userUid, configurator))
|
||||
return;
|
||||
|
||||
|
||||
_uiSystem.OpenUi(configuratorUid, NetworkConfiguratorUiKey.Link, actor.PlayerSession);
|
||||
_uiSystem.OpenUi(configuratorUid, NetworkConfiguratorUiKey.Link, userUid);
|
||||
configurator.DeviceLinkTarget = targetUid;
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ using Content.Shared.Disposal;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Disposal.Mailing;
|
||||
|
||||
@@ -35,7 +36,7 @@ public sealed class MailingUnitSystem : EntitySystem
|
||||
SubscribeLocalEvent<MailingUnitComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||
SubscribeLocalEvent<MailingUnitComponent, BeforeDisposalFlushEvent>(OnBeforeFlush);
|
||||
SubscribeLocalEvent<MailingUnitComponent, ConfigurationSystem.ConfigurationUpdatedEvent>(OnConfigurationUpdated);
|
||||
SubscribeLocalEvent<MailingUnitComponent, ActivateInWorldEvent>(HandleActivate);
|
||||
SubscribeLocalEvent<MailingUnitComponent, ActivateInWorldEvent>(HandleActivate, before: new[] { typeof(DisposalUnitSystem) });
|
||||
SubscribeLocalEvent<MailingUnitComponent, DisposalUnitUIStateUpdatedEvent>(OnDisposalUnitUIStateChange);
|
||||
SubscribeLocalEvent<MailingUnitComponent, TargetSelectedMessage>(OnTargetSelected);
|
||||
}
|
||||
@@ -179,7 +180,7 @@ public sealed class MailingUnitSystem : EntitySystem
|
||||
if (component.DisposalUnitInterfaceState == null)
|
||||
return;
|
||||
|
||||
var state = new MailingUnitBoundUserInterfaceState(component.DisposalUnitInterfaceState, component.Target, component.TargetList, component.Tag);
|
||||
var state = new MailingUnitBoundUserInterfaceState(component.DisposalUnitInterfaceState, component.Target, component.TargetList.ShallowClone(), component.Tag);
|
||||
_userInterfaceSystem.SetUiState(uid, MailingUnitUiKey.Key, state);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace Content.Server.Doors.Systems
|
||||
public sealed class FirelockSystem : SharedFirelockSystem
|
||||
{
|
||||
[Dependency] private readonly SharedDoorSystem _doorSystem = default!;
|
||||
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmosSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapping = default!;
|
||||
|
||||
@@ -24,7 +24,6 @@ public sealed partial class DragonSystem : EntitySystem
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
|
||||
[Dependency] private readonly NpcFactionSystem _faction = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly RoleSystem _role = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
@@ -225,7 +224,7 @@ public sealed partial class DragonSystem : EntitySystem
|
||||
return;
|
||||
|
||||
var mind = Comp<MindComponent>(mindContainer.Mind.Value);
|
||||
foreach (var objId in mind.AllObjectives)
|
||||
foreach (var objId in mind.Objectives)
|
||||
{
|
||||
if (_objQuery.TryGetComponent(objId, out var obj))
|
||||
{
|
||||
@@ -247,7 +246,7 @@ public sealed partial class DragonSystem : EntitySystem
|
||||
return;
|
||||
|
||||
var mind = Comp<MindComponent>(mindContainer.Mind.Value);
|
||||
foreach (var objId in mind.AllObjectives)
|
||||
foreach (var objId in mind.Objectives)
|
||||
{
|
||||
if (_objQuery.TryGetComponent(objId, out var obj))
|
||||
{
|
||||
|
||||
@@ -324,6 +324,13 @@ public sealed partial class GameTicker
|
||||
|
||||
foreach (var rule in args)
|
||||
{
|
||||
if (!_prototypeManager.HasIndex(rule))
|
||||
{
|
||||
shell.WriteError($"Invalid game rule {rule} was skipped.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shell.Player != null)
|
||||
{
|
||||
_adminLogger.Add(LogType.EventStarted, $"{shell.Player} tried to add game rule [{rule}] via command");
|
||||
|
||||
@@ -13,7 +13,6 @@ public sealed class LoadMapRuleSystem : GameRuleSystem<LoadMapRuleComponent>
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly GridPreloaderSystem _gridPreloader = default!;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ public sealed class SecretRuleSystem : GameRuleSystem<SecretRuleComponent>
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||
[Dependency] private readonly IComponentFactory _compFact = default!;
|
||||
|
||||
private string _ruleCompName = default!;
|
||||
|
||||
@@ -12,10 +12,8 @@ namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly AntagSelectionSystem _antag = default!;
|
||||
[Dependency] private readonly ObjectivesSystem _objectives = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -29,7 +29,6 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roleSystem = default!;
|
||||
[Dependency] private readonly SharedJobSystem _jobs = default!;
|
||||
[Dependency] private readonly ObjectivesSystem _objectives = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ public sealed class RandomGiftSystem : EntitySystem
|
||||
|
||||
foreach (var proto in _prototype.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (proto.Abstract || proto.NoSpawn || proto.Components.ContainsKey(mapGridCompName) || !proto.Components.ContainsKey(physicsCompName))
|
||||
if (proto.Abstract || proto.HideSpawnMenu || proto.Components.ContainsKey(mapGridCompName) || !proto.Components.ContainsKey(physicsCompName))
|
||||
continue;
|
||||
|
||||
_possibleGiftsUnsafe.Add(proto.ID);
|
||||
|
||||
26
Content.Server/IconSmoothing/RandomIconSmoothSystem.cs
Normal file
26
Content.Server/IconSmoothing/RandomIconSmoothSystem.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Content.Shared.IconSmoothing;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.IconSmoothing;
|
||||
|
||||
public sealed partial class RandomIconSmoothSystem : SharedRandomIconSmoothSystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RandomIconSmoothComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<RandomIconSmoothComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
if (ent.Comp.RandomStates.Count == 0)
|
||||
return;
|
||||
|
||||
var state = _random.Pick(ent.Comp.RandomStates);
|
||||
_appearance.SetData(ent, RandomIconSmoothState.State, state);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
||||
[Dependency] private readonly UserInterfaceSystem _bui = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly InteractionSystem _interactions = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
|
||||
private const float MaxInstrumentBandRange = 10f;
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace Content.Server.Kitchen.EntitySystems
|
||||
SubscribeLocalEvent<MicrowaveComponent, EntInsertedIntoContainerMessage>(OnContentUpdate);
|
||||
SubscribeLocalEvent<MicrowaveComponent, EntRemovedFromContainerMessage>(OnContentUpdate);
|
||||
SubscribeLocalEvent<MicrowaveComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(AnchorableSystem) });
|
||||
SubscribeLocalEvent<MicrowaveComponent, ContainerIsInsertingAttemptEvent>(OnInsertAttempt);
|
||||
SubscribeLocalEvent<MicrowaveComponent, BreakageEventArgs>(OnBreak);
|
||||
SubscribeLocalEvent<MicrowaveComponent, PowerChangedEvent>(OnPowerChanged);
|
||||
SubscribeLocalEvent<MicrowaveComponent, AnchorStateChangedEvent>(OnAnchorChanged);
|
||||
@@ -309,6 +310,32 @@ namespace Content.Server.Kitchen.EntitySystems
|
||||
UpdateUserInterfaceState(uid, component);
|
||||
}
|
||||
|
||||
private void OnInsertAttempt(Entity<MicrowaveComponent> ent, ref ContainerIsInsertingAttemptEvent args)
|
||||
{
|
||||
if (ent.Comp.Broken)
|
||||
{
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryComp<ItemComponent>(args.EntityUid, out var item))
|
||||
{
|
||||
if (_item.GetSizePrototype(item.Size) > _item.GetSizePrototype(ent.Comp.MaxItemSize))
|
||||
{
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent.Comp.Storage.Count >= ent.Comp.Capacity)
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnInteractUsing(Entity<MicrowaveComponent> ent, ref InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
||||
@@ -46,7 +46,6 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -160,9 +160,9 @@ public sealed class HTNPlanJob : Job<HTNPlan>
|
||||
{
|
||||
var compound = _protoManager.Index<HTNCompoundPrototype>(compoundId.Task);
|
||||
|
||||
for (var i = mtrIndex; i < compound.Branches.Count; i++)
|
||||
for (; mtrIndex < compound.Branches.Count; mtrIndex++)
|
||||
{
|
||||
var branch = compound.Branches[i];
|
||||
var branch = compound.Branches[mtrIndex];
|
||||
var isValid = true;
|
||||
|
||||
foreach (var con in branch.Preconditions)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Content.Server.NPC.Components;
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Robust.Shared.Map;
|
||||
@@ -134,7 +133,7 @@ public sealed partial class NPCCombatSystem
|
||||
{
|
||||
comp.LOSAccumulator += UnoccludedCooldown;
|
||||
// For consistency with NPC steering.
|
||||
comp.TargetInLOS = _interaction.InRangeUnobstructed(uid, Transform(comp.Target).Coordinates, distance + 0.1f);
|
||||
comp.TargetInLOS = _interaction.InRangeUnobstructed(uid, comp.Target, distance + 0.1f);
|
||||
}
|
||||
|
||||
if (!comp.TargetInLOS)
|
||||
|
||||
@@ -32,10 +32,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly BatterySystem _battery = default!;
|
||||
[Dependency] private readonly CodeConditionSystem _codeCondition = default!;
|
||||
[Dependency] private readonly IChatManager _chatMan = default!;
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly RoleSystem _role = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
||||
@@ -10,7 +10,6 @@ using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Organ;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -31,6 +30,7 @@ using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Robust.Server.GameObjects;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
@@ -138,6 +138,16 @@ public sealed class FoodSystem : EntitySystem
|
||||
return (false, true);
|
||||
}
|
||||
|
||||
// Checks for used item slots
|
||||
if (TryComp<ItemSlotsComponent>(food, out var itemSlots))
|
||||
{
|
||||
if (itemSlots.Slots.Any(slot => slot.Value.HasItem))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("food-has-used-storage", ("food", food)), user, user);
|
||||
return (false, true);
|
||||
}
|
||||
}
|
||||
|
||||
var flavors = _flavorProfile.GetLocalizedFlavorsMessage(food, user, foodSolution);
|
||||
|
||||
if (GetUsesRemaining(food, foodComp) <= 0)
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Content.Server.Nutrition.EntitySystems
|
||||
{
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly TransformSystem _xformSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Content.Server.Objectives.Commands
|
||||
}
|
||||
|
||||
shell.WriteLine($"Objectives for player {player.UserId}:");
|
||||
var objectives = mind.AllObjectives.ToList();
|
||||
var objectives = mind.Objectives.ToList();
|
||||
if (objectives.Count == 0)
|
||||
{
|
||||
shell.WriteLine("None.");
|
||||
|
||||
@@ -129,12 +129,12 @@ public sealed class ObjectivesSystem : SharedObjectivesSystem
|
||||
var agentSummary = new StringBuilder();
|
||||
agentSummary.AppendLine(Loc.GetString("objectives-with-objectives", ("custody", custody), ("title", title), ("agent", agent)));
|
||||
|
||||
foreach (var objectiveGroup in objectives.GroupBy(o => Comp<ObjectiveComponent>(o).Issuer))
|
||||
foreach (var objectiveGroup in objectives.GroupBy(o => Comp<ObjectiveComponent>(o).LocIssuer))
|
||||
{
|
||||
//TO DO:
|
||||
//check for the right group here. Getting the target issuer is easy: objectiveGroup.Key
|
||||
//It should be compared to the type of the group's issuer.
|
||||
agentSummary.AppendLine(Loc.GetString($"objective-issuer-{objectiveGroup.Key}"));
|
||||
agentSummary.AppendLine(objectiveGroup.Key);
|
||||
|
||||
foreach (var objective in objectiveGroup)
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed class HelpProgressConditionSystem : EntitySystem
|
||||
if (!TryComp<MindComponent>(traitor, out var mind))
|
||||
continue;
|
||||
|
||||
foreach (var objective in mind.AllObjectives)
|
||||
foreach (var objective in mind.Objectives)
|
||||
{
|
||||
if (HasComp<HelpProgressConditionComponent>(objective))
|
||||
removeList.Add(traitor);
|
||||
@@ -88,7 +88,7 @@ public sealed class HelpProgressConditionSystem : EntitySystem
|
||||
|
||||
if (TryComp<MindComponent>(target, out var mind))
|
||||
{
|
||||
foreach (var objective in mind.AllObjectives)
|
||||
foreach (var objective in mind.Objectives)
|
||||
{
|
||||
// this has the potential to loop forever, anything setting target has to check that there is no HelpProgressCondition.
|
||||
var info = _objectives.GetInfo(objective, target, mind);
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed class ObjectiveBlacklistRequirementSystem : EntitySystem
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
foreach (var objective in args.Mind.AllObjectives)
|
||||
foreach (var objective in args.Mind.Objectives)
|
||||
{
|
||||
if (_whitelistSystem.IsBlacklistPass(comp.Blacklist, objective))
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
|
||||
[Dependency] private readonly MindSystem _minds = default!;
|
||||
[Dependency] private readonly PlayTimeTrackingManager _tracking = default!;
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _role = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -152,9 +152,7 @@ namespace Content.Server.Pointing.EntitySystems
|
||||
|
||||
if (TryComp<PointingArrowComponent>(arrow, out var pointing))
|
||||
{
|
||||
if (TryComp(player, out TransformComponent? xformPlayer))
|
||||
pointing.StartPosition = _transform.ToCoordinates((player, xformPlayer), _transform.ToMapCoordinates(xformPlayer.Coordinates)).Position;
|
||||
|
||||
pointing.StartPosition = _transform.ToCoordinates((arrow, Transform(arrow)), _transform.ToMapCoordinates(Transform(player).Coordinates)).Position;
|
||||
pointing.EndTime = _gameTiming.CurTime + PointDuration;
|
||||
|
||||
Dirty(arrow, pointing);
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Content.Server.Power.EntitySystems
|
||||
[Dependency] private readonly PowerNetConnectorSystem _powerNetConnector = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IParallelManager _parMan = default!;
|
||||
[Dependency] private readonly PowerReceiverSystem _powerReceiver = default!;
|
||||
|
||||
private readonly PowerState _powerState = new();
|
||||
private readonly HashSet<PowerNet> _powerNetReconnectQueue = new();
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Content.Server.Power.EntitySystems
|
||||
{
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IAdminManager _adminManager = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
private EntityQuery<ApcPowerReceiverComponent> _recQuery;
|
||||
private EntityQuery<ApcPowerProviderComponent> _provQuery;
|
||||
|
||||
@@ -9,7 +9,7 @@ public static class StaticPowerSystem
|
||||
public static bool IsPowered(this EntitySystem system, EntityUid uid, IEntityManager entManager, ApcPowerReceiverComponent? receiver = null)
|
||||
{
|
||||
if (receiver == null && !entManager.TryGetComponent(uid, out receiver))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
return receiver.Powered;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public sealed partial class DungeonSystem
|
||||
// go BRRNNTTT on existing stuff
|
||||
if (clearExisting)
|
||||
{
|
||||
var gridBounds = new Box2(Vector2.Transform(Vector2.Zero, roomTransform), Vector2.Transform(room.Size, roomTransform));
|
||||
var gridBounds = new Box2(Vector2.Transform(-room.Size/2, roomTransform), Vector2.Transform(room.Size/2, roomTransform));
|
||||
_entitySet.Clear();
|
||||
// Polygon skin moment
|
||||
gridBounds = gridBounds.Enlarged(-0.05f);
|
||||
|
||||
@@ -33,7 +33,6 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
||||
[Dependency] private readonly AnchorableSystem _anchorable = default!;
|
||||
[Dependency] private readonly DecalSystem _decals = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly TileSystem _tile = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
|
||||
@@ -40,7 +40,6 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
[Dependency] private readonly IBanManager _banManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAccessSystem _access = default!;
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetwork = default!;
|
||||
|
||||
@@ -17,7 +17,6 @@ public sealed partial class StationJobsSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IBanManager _banManager = default!;
|
||||
[Dependency] private readonly PlayTimeTrackingSystem _playTime = default!;
|
||||
|
||||
private Dictionary<int, HashSet<string>> _jobsByWeight = default!;
|
||||
private List<int> _orderedWeights = default!;
|
||||
|
||||
@@ -27,10 +27,8 @@ namespace Content.Server.Station.Systems;
|
||||
[PublicAPI]
|
||||
public sealed class StationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using Content.Server.StationEvents.Events;
|
||||
|
||||
namespace Content.Server.StationEvents.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This is used to keep track of hallucinated entities to remove effects when event ends
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(MassHallucinationsRule))]
|
||||
public sealed partial class MassHallucinationsComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Collections;
|
||||
|
||||
namespace Content.Server.StationEvents.Components;
|
||||
|
||||
@@ -23,4 +24,7 @@ public sealed partial class MassHallucinationsRuleComponent : Component
|
||||
|
||||
[DataField("sounds", required: true)]
|
||||
public SoundSpecifier Sounds = default!;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||
public List<EntityUid> AffectedEntities = new();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Traits.Assorted;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Traits.Assorted;
|
||||
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
public sealed class MassHallucinationsRule : StationEventSystem<MassHallucinationsRuleComponent>
|
||||
@@ -14,16 +16,17 @@ public sealed class MassHallucinationsRule : StationEventSystem<MassHallucinatio
|
||||
protected override void Started(EntityUid uid, MassHallucinationsRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
||||
{
|
||||
base.Started(uid, component, gameRule, args);
|
||||
var query = EntityQueryEnumerator<MindContainerComponent>();
|
||||
while (query.MoveNext(out var ent, out _))
|
||||
|
||||
var query = EntityQueryEnumerator<MindContainerComponent, HumanoidAppearanceComponent>();
|
||||
while (query.MoveNext(out var ent, out _, out _))
|
||||
{
|
||||
if (!HasComp<ParacusiaComponent>(ent))
|
||||
if (!EnsureComp<ParacusiaComponent>(ent, out var paracusia))
|
||||
{
|
||||
EnsureComp<MassHallucinationsComponent>(ent);
|
||||
var paracusia = EnsureComp<ParacusiaComponent>(ent);
|
||||
_paracusia.SetSounds(ent, component.Sounds, paracusia);
|
||||
_paracusia.SetTime(ent, component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents, paracusia);
|
||||
_paracusia.SetDistance(ent, component.MaxSoundDistance);
|
||||
|
||||
component.AffectedEntities.Add(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,10 +34,12 @@ public sealed class MassHallucinationsRule : StationEventSystem<MassHallucinatio
|
||||
protected override void Ended(EntityUid uid, MassHallucinationsRuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args)
|
||||
{
|
||||
base.Ended(uid, component, gameRule, args);
|
||||
var query = EntityQueryEnumerator<MassHallucinationsComponent>();
|
||||
while (query.MoveNext(out var ent, out _))
|
||||
|
||||
foreach (var ent in component.AffectedEntities)
|
||||
{
|
||||
RemComp<ParacusiaComponent>(ent);
|
||||
}
|
||||
|
||||
component.AffectedEntities.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace Content.Server.Traits;
|
||||
public sealed class TraitSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ISerializationManager _serializationManager = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
|
||||
@@ -155,7 +155,12 @@ public sealed class AccessReaderSystem : EntitySystem
|
||||
return IsAllowedInternal(access, stationKeys, reader);
|
||||
|
||||
if (!_containerSystem.TryGetContainer(target, reader.ContainerAccessProvider, out var container))
|
||||
return Paused(target); // when mapping, containers with electronics arent spawned
|
||||
return false;
|
||||
|
||||
// If entity is paused then always allow it at this point.
|
||||
// Door electronics is kind of a mess but yeah, it should only be an unpaused ent interacting with it
|
||||
if (Paused(target))
|
||||
return true;
|
||||
|
||||
foreach (var entity in container.ContainedEntities)
|
||||
{
|
||||
|
||||
@@ -120,7 +120,13 @@ namespace Content.Shared.ActionBlocker
|
||||
var ev = new ThrowAttemptEvent(user, itemUid);
|
||||
RaiseLocalEvent(user, ev);
|
||||
|
||||
return !ev.Cancelled;
|
||||
if (ev.Cancelled)
|
||||
return false;
|
||||
|
||||
var itemEv = new ThrowItemAttemptEvent(user);
|
||||
RaiseLocalEvent(itemUid, ref itemEv);
|
||||
|
||||
return !itemEv.Cancelled;
|
||||
}
|
||||
|
||||
public bool CanSpeak(EntityUid uid)
|
||||
|
||||
@@ -25,7 +25,6 @@ public abstract class SharedActionsSystem : EntitySystem
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
@@ -238,7 +237,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
||||
}
|
||||
|
||||
#region ComponentStateManagement
|
||||
protected virtual void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
|
||||
public virtual void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
|
||||
{
|
||||
// See client-side code.
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Rules;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace Content.Shared.Beeper.Systems;
|
||||
/// </summary>
|
||||
public sealed class ProximityBeeperSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly ProximityDetectionSystem _proximity = default!;
|
||||
[Dependency] private readonly BeeperSystem _beeper = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
@@ -14,13 +14,10 @@ namespace Content.Shared.Clothing;
|
||||
|
||||
public sealed class ClothingSpeedModifierSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly ClothingSpeedModifierSystem _clothingSpeedModifier = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
|
||||
[Dependency] private readonly ItemToggleSystem _toggle = default!;
|
||||
[Dependency] private readonly SharedPowerCellSystem _powerCell = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -78,7 +78,7 @@ public abstract class SharedChameleonClothingSystem : EntitySystem
|
||||
public bool IsValidTarget(EntityPrototype proto, SlotFlags chameleonSlot = SlotFlags.NONE)
|
||||
{
|
||||
// check if entity is valid
|
||||
if (proto.Abstract || proto.NoSpawn)
|
||||
if (proto.Abstract || proto.HideSpawnMenu)
|
||||
return false;
|
||||
|
||||
// check if it is marked as valid chameleon target
|
||||
|
||||
@@ -192,6 +192,11 @@ public sealed partial class StaminaSystem : EntitySystem
|
||||
|
||||
private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, EntityUid target)
|
||||
{
|
||||
// you can't inflict stamina damage on things with no stamina component
|
||||
// this prevents stun batons from using up charges when throwing it at lockers or lights
|
||||
if (!HasComp<StaminaComponent>(target))
|
||||
return;
|
||||
|
||||
var ev = new StaminaDamageOnHitAttemptEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
if (ev.Cancelled)
|
||||
|
||||
@@ -32,23 +32,23 @@ public sealed class PettableFriendSystem : EntitySystem
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
var user = args.User;
|
||||
if (args.Handled || !_exceptionQuery.TryGetComponent(uid, out var exceptionComp))
|
||||
return;
|
||||
|
||||
if (_useDelayQuery.TryGetComponent(uid, out var useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true))
|
||||
if (args.Handled || !_exceptionQuery.TryComp(uid, out var exceptionComp))
|
||||
return;
|
||||
|
||||
var exception = (uid, exceptionComp);
|
||||
if (_factionException.IsIgnored(exception, user))
|
||||
if (!_factionException.IsIgnored(exception, user))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString(comp.FailureString, ("target", uid)), user, user);
|
||||
// you have made a new friend :)
|
||||
_popup.PopupClient(Loc.GetString(comp.SuccessString, ("target", uid)), user, user);
|
||||
_factionException.IgnoreEntity(exception, user);
|
||||
args.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// you have made a new friend :)
|
||||
_popup.PopupClient(Loc.GetString(comp.SuccessString, ("target", uid)), user, user);
|
||||
_factionException.IgnoreEntity(exception, user);
|
||||
args.Handled = true;
|
||||
if (_useDelayQuery.TryComp(uid, out var useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true))
|
||||
return;
|
||||
|
||||
_popup.PopupClient(Loc.GetString(comp.FailureString, ("target", uid)), user, user);
|
||||
}
|
||||
|
||||
private void OnRehydrated(Entity<PettableFriendComponent> ent, ref GotRehydratedEvent args)
|
||||
|
||||
16
Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs
Normal file
16
Content.Shared/IconSmoothing/RandomIconSmoothComponent.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.IconSmoothing;
|
||||
|
||||
/// <summary>
|
||||
/// Allow randomize StateBase of IconSmoothComponent for random visual variation
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class RandomIconSmoothComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// StateBase will be randomly selected from this list. Allows to randomize the visual.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public List<string> RandomStates = new();
|
||||
}
|
||||
12
Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs
Normal file
12
Content.Shared/IconSmoothing/SharedRandomIconSmoothSystem.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.IconSmoothing;
|
||||
|
||||
public abstract class SharedRandomIconSmoothSystem : EntitySystem
|
||||
{
|
||||
}
|
||||
[Serializable, NetSerializable]
|
||||
public enum RandomIconSmoothState : byte
|
||||
{
|
||||
State
|
||||
}
|
||||
@@ -38,8 +38,6 @@ using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
#pragma warning disable 618
|
||||
|
||||
namespace Content.Shared.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
@@ -522,11 +520,11 @@ namespace Content.Shared.Interaction
|
||||
protected bool ValidateInteractAndFace(EntityUid user, EntityCoordinates coordinates)
|
||||
{
|
||||
// Verify user is on the same map as the entity they clicked on
|
||||
if (coordinates.GetMapId(EntityManager) != Transform(user).MapID)
|
||||
if (_transform.GetMapId(coordinates) != Transform(user).MapID)
|
||||
return false;
|
||||
|
||||
if (!HasComp<NoRotateOnInteractComponent>(user))
|
||||
_rotateToFaceSystem.TryFaceCoordinates(user, coordinates.ToMapPos(EntityManager, _transform));
|
||||
_rotateToFaceSystem.TryFaceCoordinates(user, _transform.ToMapCoordinates(coordinates).Position);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -859,7 +857,7 @@ namespace Content.Shared.Interaction
|
||||
Ignored? predicate = null,
|
||||
bool popup = false)
|
||||
{
|
||||
return InRangeUnobstructed(origin, other.ToMap(EntityManager, _transform), range, collisionMask, predicate, popup);
|
||||
return InRangeUnobstructed(origin, _transform.ToMapCoordinates(other), range, collisionMask, predicate, popup);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -966,7 +964,7 @@ namespace Content.Shared.Interaction
|
||||
/// </summary>
|
||||
public void InteractDoAfter(EntityUid user, EntityUid used, EntityUid? target, EntityCoordinates clickLocation, bool canReach)
|
||||
{
|
||||
if (target is {Valid: false})
|
||||
if (target is { Valid: false })
|
||||
target = null;
|
||||
|
||||
var afterInteractEvent = new AfterInteractEvent(user, used, target, clickLocation, canReach);
|
||||
|
||||
@@ -62,21 +62,22 @@ public sealed class SmartEquipSystem : EntitySystem
|
||||
if (playerSession.AttachedEntity is not { Valid: true } uid || !Exists(uid))
|
||||
return;
|
||||
|
||||
if (!_actionBlocker.CanInteract(uid, null))
|
||||
return;
|
||||
|
||||
// early out if we don't have any hands or a valid inventory slot
|
||||
if (!TryComp<HandsComponent>(uid, out var hands) || hands.ActiveHand == null)
|
||||
return;
|
||||
|
||||
var handItem = hands.ActiveHand.HeldEntity;
|
||||
|
||||
// can the user interact, and is the item interactable? e.g. virtual items
|
||||
if (!_actionBlocker.CanInteract(uid, handItem))
|
||||
return;
|
||||
|
||||
if (!TryComp<InventoryComponent>(uid, out var inventory) || !_inventory.HasSlot(uid, equipmentSlot, inventory))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("smart-equip-missing-equipment-slot", ("slotName", equipmentSlot)), uid, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
var handItem = hands.ActiveHand.HeldEntity;
|
||||
|
||||
// early out if we have an item and cant drop it at all
|
||||
if (handItem != null && !_hands.CanDropHeld(uid, hands.ActiveHand))
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Popups;
|
||||
@@ -43,6 +44,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem
|
||||
SubscribeLocalEvent<VirtualItemComponent, BeingUnequippedAttemptEvent>(OnBeingUnequippedAttempt);
|
||||
|
||||
SubscribeLocalEvent<VirtualItemComponent, BeforeRangedInteractEvent>(OnBeforeRangedInteract);
|
||||
SubscribeLocalEvent<VirtualItemComponent, GettingInteractedWithAttemptEvent>(OnGettingInteractedWithAttemptEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,6 +74,12 @@ public abstract class SharedVirtualItemSystem : EntitySystem
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnGettingInteractedWithAttemptEvent(Entity<VirtualItemComponent> ent, ref GettingInteractedWithAttemptEvent args)
|
||||
{
|
||||
// No interactions with a virtual item, please.
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
#region Hands
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -370,7 +370,7 @@ public abstract class SharedMindSystem : EntitySystem
|
||||
if (Resolve(mindId, ref mind))
|
||||
{
|
||||
var query = GetEntityQuery<T>();
|
||||
foreach (var uid in mind.AllObjectives)
|
||||
foreach (var uid in mind.Objectives)
|
||||
{
|
||||
if (query.TryGetComponent(uid, out objective))
|
||||
{
|
||||
|
||||
@@ -43,7 +43,6 @@ public sealed class PullingSystem : EntitySystem
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly HeldSpeedModifierSystem _clothingMoveSpeed = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
||||
@@ -18,7 +18,6 @@ public sealed class DashAbilitySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedChargesSystem _charges = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
|
||||
@@ -22,8 +22,11 @@ public sealed partial class ObjectiveComponent : Component
|
||||
/// <summary>
|
||||
/// Organisation that issued this objective, used for grouping and as a header above common objectives.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Issuer = string.Empty;
|
||||
[DataField("issuer", required: true)]
|
||||
private LocId Issuer { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public string LocIssuer => Loc.GetString(Issuer);
|
||||
|
||||
/// <summary>
|
||||
/// Unique objectives can only have 1 per prototype id.
|
||||
|
||||
@@ -58,7 +58,7 @@ public enum CollisionGroup
|
||||
// Tabletop machines, windoors, firelocks
|
||||
TabletopMachineMask = Impassable | HighImpassable,
|
||||
// Tabletop machines
|
||||
TabletopMachineLayer = Opaque | HighImpassable | BulletImpassable,
|
||||
TabletopMachineLayer = Opaque | BulletImpassable,
|
||||
|
||||
// Airlocks, windoors, firelocks
|
||||
GlassAirlockLayer = HighImpassable | MidImpassable | BulletImpassable | InteractImpassable,
|
||||
|
||||
@@ -120,7 +120,10 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
||||
|
||||
if (component.Offset != Vector2.Zero)
|
||||
{
|
||||
_transform.SetLocalPosition(uid, xform.LocalPosition + xform.LocalRotation.RotateVec(component.Offset),
|
||||
var rotation = xform.LocalRotation;
|
||||
if (TryComp<ThrowingAngleComponent>(uid, out var throwingAngleComp))
|
||||
rotation += throwingAngleComp.Angle;
|
||||
_transform.SetLocalPosition(uid, xform.LocalPosition + rotation.RotateVec(component.Offset),
|
||||
xform);
|
||||
}
|
||||
|
||||
|
||||
@@ -239,14 +239,14 @@ public sealed partial class EncryptionKeySystem : EntitySystem
|
||||
{
|
||||
var msg = Loc.GetString("examine-headset-default-channel",
|
||||
("prefix", SharedChatSystem.DefaultChannelPrefix),
|
||||
("channel", defaultChannel),
|
||||
("channel", proto.LocalizedName),
|
||||
("color", proto.Color));
|
||||
examineEvent.PushMarkup(msg);
|
||||
}
|
||||
if (HasComp<EncryptionKeyComponent>(examineEvent.Examined))
|
||||
{
|
||||
var msg = Loc.GetString("examine-encryption-default-channel",
|
||||
("channel", defaultChannel),
|
||||
("channel", proto.LocalizedName),
|
||||
("color", proto.Color));
|
||||
examineEvent.PushMarkup(msg);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ public sealed partial class RadioChannelPrototype : IPrototype
|
||||
/// Human-readable name for the channel.
|
||||
/// </summary>
|
||||
[DataField("name")]
|
||||
public string Name { get; private set; } = string.Empty;
|
||||
public LocId Name { get; private set; } = string.Empty;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public string LocalizedName => Loc.GetString(Name);
|
||||
|
||||
12
Content.Shared/Random/Rules/AlwaysTrue.cs
Normal file
12
Content.Shared/Random/Rules/AlwaysTrue.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Always returns true. Used for fallbacks.
|
||||
/// </summary>
|
||||
public sealed partial class AlwaysTrueRule : RulesRule
|
||||
{
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
39
Content.Shared/Random/Rules/GridInRange.cs
Normal file
39
Content.Shared/Random/Rules/GridInRange.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if on a grid or in range of one.
|
||||
/// </summary>
|
||||
public sealed partial class GridInRangeRule : RulesRule
|
||||
{
|
||||
[DataField]
|
||||
public float Range = 10f;
|
||||
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
if (!entManager.TryGetComponent(uid, out TransformComponent? xform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xform.GridUid != null)
|
||||
{
|
||||
return !Inverted;
|
||||
}
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
|
||||
var worldPos = transform.GetWorldPosition(xform);
|
||||
var gridRange = new Vector2(Range, Range);
|
||||
|
||||
foreach (var _ in mapManager.FindGridsIntersecting(xform.MapID, new Box2(worldPos - gridRange, worldPos + gridRange)))
|
||||
{
|
||||
return !Inverted;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
18
Content.Shared/Random/Rules/InSpace.cs
Normal file
18
Content.Shared/Random/Rules/InSpace.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the attached entity is in space.
|
||||
/// </summary>
|
||||
public sealed partial class InSpaceRule : RulesRule
|
||||
{
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
if (!entManager.TryGetComponent(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid != null)
|
||||
{
|
||||
return Inverted;
|
||||
}
|
||||
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
77
Content.Shared/Random/Rules/NearbyAccess.cs
Normal file
77
Content.Shared/Random/Rules/NearbyAccess.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Checks for an entity nearby with the specified access.
|
||||
/// </summary>
|
||||
public sealed partial class NearbyAccessRule : RulesRule
|
||||
{
|
||||
// This exists because of door electronics contained inside doors.
|
||||
/// <summary>
|
||||
/// Does the access entity need to be anchored.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Anchored = true;
|
||||
|
||||
/// <summary>
|
||||
/// Count of entities that need to be nearby.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Count = 1;
|
||||
|
||||
[DataField(required: true)]
|
||||
public List<ProtoId<AccessLevelPrototype>> Access = new();
|
||||
|
||||
[DataField]
|
||||
public float Range = 10f;
|
||||
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
var xformQuery = entManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
if (!xformQuery.TryGetComponent(uid, out var xform) ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var lookup = entManager.System<EntityLookupSystem>();
|
||||
var reader = entManager.System<AccessReaderSystem>();
|
||||
|
||||
var found = false;
|
||||
var worldPos = transform.GetWorldPosition(xform, xformQuery);
|
||||
var count = 0;
|
||||
|
||||
// TODO: Update this when we get the callback version
|
||||
var entities = new HashSet<Entity<AccessReaderComponent>>();
|
||||
lookup.GetEntitiesInRange(xform.MapID, worldPos, Range, entities);
|
||||
foreach (var comp in entities)
|
||||
{
|
||||
if (!reader.AreAccessTagsAllowed(Access, comp) ||
|
||||
Anchored &&
|
||||
(!xformQuery.TryGetComponent(comp, out var compXform) ||
|
||||
!compXform.Anchored))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
if (count < Count)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return Inverted;
|
||||
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
71
Content.Shared/Random/Rules/NearbyComponents.cs
Normal file
71
Content.Shared/Random/Rules/NearbyComponents.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
public sealed partial class NearbyComponentsRule : RulesRule
|
||||
{
|
||||
/// <summary>
|
||||
/// Does the entity need to be anchored.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Anchored;
|
||||
|
||||
[DataField]
|
||||
public int Count;
|
||||
|
||||
[DataField(required: true)]
|
||||
public ComponentRegistry Components = default!;
|
||||
|
||||
[DataField]
|
||||
public float Range = 10f;
|
||||
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
var inRange = new HashSet<Entity<IComponent>>();
|
||||
var xformQuery = entManager.GetEntityQuery<TransformComponent>();
|
||||
|
||||
if (!xformQuery.TryGetComponent(uid, out var xform) ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var lookup = entManager.System<EntityLookupSystem>();
|
||||
|
||||
var found = false;
|
||||
var worldPos = transform.GetWorldPosition(xform);
|
||||
var count = 0;
|
||||
|
||||
foreach (var compType in Components.Values)
|
||||
{
|
||||
inRange.Clear();
|
||||
lookup.GetEntitiesInRange(compType.Component.GetType(), xform.MapID, worldPos, Range, inRange);
|
||||
foreach (var comp in inRange)
|
||||
{
|
||||
if (Anchored &&
|
||||
(!xformQuery.TryGetComponent(comp, out var compXform) ||
|
||||
!compXform.Anchored))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
if (count < Count)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return Inverted;
|
||||
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
58
Content.Shared/Random/Rules/NearbyEntities.cs
Normal file
58
Content.Shared/Random/Rules/NearbyEntities.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Checks for entities matching the whitelist in range.
|
||||
/// This is more expensive than <see cref="NearbyComponentsRule"/> so prefer that!
|
||||
/// </summary>
|
||||
public sealed partial class NearbyEntitiesRule : RulesRule
|
||||
{
|
||||
/// <summary>
|
||||
/// How many of the entity need to be nearby.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Count = 1;
|
||||
|
||||
[DataField(required: true)]
|
||||
public EntityWhitelist Whitelist = new();
|
||||
|
||||
[DataField]
|
||||
public float Range = 10f;
|
||||
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
if (!entManager.TryGetComponent(uid, out TransformComponent? xform) ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var lookup = entManager.System<EntityLookupSystem>();
|
||||
var whitelistSystem = entManager.System<EntityWhitelistSystem>();
|
||||
|
||||
var found = false;
|
||||
var worldPos = transform.GetWorldPosition(xform);
|
||||
var count = 0;
|
||||
|
||||
foreach (var ent in lookup.GetEntitiesInRange(xform.MapID, worldPos, Range))
|
||||
{
|
||||
if (whitelistSystem.IsWhitelistFail(Whitelist, ent))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if (count < Count)
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return Inverted;
|
||||
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
79
Content.Shared/Random/Rules/NearbyTilesPercent.cs
Normal file
79
Content.Shared/Random/Rules/NearbyTilesPercent.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Random.Rules;
|
||||
|
||||
public sealed partial class NearbyTilesPercentRule : RulesRule
|
||||
{
|
||||
/// <summary>
|
||||
/// If there are anchored entities on the tile do we ignore the tile.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool IgnoreAnchored;
|
||||
|
||||
[DataField(required: true)]
|
||||
public float Percent;
|
||||
|
||||
[DataField(required: true)]
|
||||
public List<ProtoId<ContentTileDefinition>> Tiles = new();
|
||||
|
||||
[DataField]
|
||||
public float Range = 10f;
|
||||
|
||||
public override bool Check(EntityManager entManager, EntityUid uid)
|
||||
{
|
||||
if (!entManager.TryGetComponent(uid, out TransformComponent? xform) ||
|
||||
!entManager.TryGetComponent<MapGridComponent>(xform.GridUid, out var grid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var transform = entManager.System<SharedTransformSystem>();
|
||||
var tileDef = IoCManager.Resolve<ITileDefinitionManager>();
|
||||
|
||||
var physicsQuery = entManager.GetEntityQuery<PhysicsComponent>();
|
||||
var tileCount = 0;
|
||||
var matchingTileCount = 0;
|
||||
|
||||
foreach (var tile in grid.GetTilesIntersecting(new Circle(transform.GetWorldPosition(xform),
|
||||
Range)))
|
||||
{
|
||||
// Only consider collidable anchored (for reasons some subfloor stuff has physics but non-collidable)
|
||||
if (IgnoreAnchored)
|
||||
{
|
||||
var gridEnum = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices);
|
||||
var found = false;
|
||||
|
||||
while (gridEnum.MoveNext(out var ancUid))
|
||||
{
|
||||
if (!physicsQuery.TryGetComponent(ancUid, out var physics) ||
|
||||
!physics.CanCollide)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
}
|
||||
|
||||
tileCount++;
|
||||
|
||||
if (!Tiles.Contains(tileDef[tile.Tile.TypeId].ID))
|
||||
continue;
|
||||
|
||||
matchingTileCount++;
|
||||
}
|
||||
|
||||
if (tileCount == 0 || matchingTileCount / (float) tileCount < Percent)
|
||||
return Inverted;
|
||||
|
||||
return !Inverted;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user