diff --git a/.editorconfig b/.editorconfig index 0409377f1dd..a8ce1d6b68b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -196,7 +196,7 @@ csharp_preserve_single_line_blocks = true #dotnet_naming_style.begins_with_i.word_separator = #dotnet_naming_style.begins_with_i.capitalization = pascal_case -dotnet_diagnostic.IDE0055.severity = warning +dotnet_diagnostic.ide0055.severity = warning dotnet_naming_rule.constants_rule.severity = warning dotnet_naming_rule.constants_rule.style = upper_camel_case_style @@ -336,6 +336,7 @@ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter # ReSharper properties resharper_braces_for_ifelse = required_for_multiline +resharper_keep_existing_attribute_arrangement = true [*.{csproj,xml,yml,dll.config,msbuildproj,targets}] indent_size = 2 diff --git a/.github/workflows/build-map-renderer.yml b/.github/workflows/build-map-renderer.yml index 4aa4b29c85e..e921bd2558c 100644 --- a/.github/workflows/build-map-renderer.yml +++ b/.github/workflows/build-map-renderer.yml @@ -13,7 +13,7 @@ jobs: if: github.actor != 'PJBot' && github.event.pull_request.draft == false strategy: matrix: - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/build-test-debug.yml b/.github/workflows/build-test-debug.yml index 12584c4da72..9abd4fbe17e 100644 --- a/.github/workflows/build-test-debug.yml +++ b/.github/workflows/build-test-debug.yml @@ -13,7 +13,7 @@ jobs: if: github.actor != 'PJBot' && github.event.pull_request.draft == false strategy: matrix: - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/build-test-release.yml b/.github/workflows/build-test-release.yml deleted file mode 100644 index d62bed3a5d1..00000000000 --- a/.github/workflows/build-test-release.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Build & Test Release - -on: - push: - branches: [ master, staging, trying ] - merge_group: - pull_request: - types: [ opened, reopened, synchronize, ready_for_review ] - branches: [ master ] - -jobs: - build: - if: github.actor != 'PJBot' && github.event.pull_request.draft == false - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout Master - uses: actions/checkout@v3.6.0 - - - name: Setup Submodule - run: | - git submodule update --init --recursive - - - name: Pull engine updates - uses: space-wizards/submodule-dependency@v0.1.5 - - - name: Update Engine Submodules - run: | - cd RobustToolbox/ - git submodule update --init --recursive - - - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: 7.0.x - - - name: Install dependencies - run: dotnet restore - - - name: Build Project - run: dotnet build --configuration Tools --no-restore /p:WarningsAsErrors=nullable /m - - - name: Run Content.Tests - run: dotnet test --configuration Tools --no-build Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0 - - - name: Run Content.IntegrationTests - shell: pwsh - run: | - $env:DOTNET_gcServer=1 - dotnet test --configuration Tools --no-build Content.IntegrationTests/Content.IntegrationTests.csproj -- NUnit.ConsoleOut=0 NUnit.MapWarningTo=Failed - ci-success: - name: Build & Test Release - needs: - - build - runs-on: ubuntu-latest - steps: - - name: CI succeeded - run: exit 0 diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index cb431854845..0c23542f798 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -1,7 +1,7 @@ +using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; -using Robust.Client.GameObjects; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.AccessOverriderComponent; @@ -23,7 +23,7 @@ protected override void Open() { base.Open(); - List accessLevels; + List> accessLevels; if (EntMan.TryGetComponent(Owner, out var accessOverrider)) { @@ -33,7 +33,7 @@ protected override void Open() else { - accessLevels = new List(); + accessLevels = new List>(); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); } diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 6a4dcba3078..2fd00571215 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -21,7 +21,7 @@ public sealed partial class AccessOverriderWindow : DefaultWindow private readonly Dictionary _accessButtons = new(); public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, - List accessLevels) + List> accessLevels) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); @@ -31,7 +31,7 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype foreach (var access in accessLevels) { - if (!prototypeManager.TryIndex(access, out var accessLevel)) + if (!prototypeManager.TryIndex(access, out var accessLevel)) { _logMill.Error($"Unable to find accesslevel for {access}"); continue; diff --git a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs index be45e57c8b1..898792aa030 100644 --- a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs +++ b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs @@ -1,8 +1,8 @@ +using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; using Content.Shared.CrewManifest; -using Robust.Client.GameObjects; using Robust.Shared.Prototypes; using static Content.Shared.Access.Components.IdCardConsoleComponent; @@ -23,7 +23,7 @@ public IdCardConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner protected override void Open() { base.Open(); - List accessLevels; + List> accessLevels; if (EntMan.TryGetComponent(Owner, out var idCard)) { @@ -32,7 +32,7 @@ protected override void Open() } else { - accessLevels = new List(); + accessLevels = new List>(); _idCardConsoleSystem.Log.Error($"No IdCardConsole component found for {EntMan.ToPrettyString(Owner)}!"); } diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs index f8450fe578f..670ba088713 100644 --- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs +++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs @@ -28,7 +28,7 @@ public sealed partial class IdCardConsoleWindow : DefaultWindow private string? _lastJobProto; public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager, - List accessLevels) + List> accessLevels) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); diff --git a/Content.Client/Administration/Systems/AdminVerbSystem.cs b/Content.Client/Administration/Systems/AdminVerbSystem.cs index d08ebc0fcef..e0f84bc4f03 100644 --- a/Content.Client/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Client/Administration/Systems/AdminVerbSystem.cs @@ -24,10 +24,9 @@ private void AddAdminVerbs(GetVerbsEvent args) // View variables verbs if (_clientConGroupController.CanViewVar()) { - Verb verb = new() + var verb = new VvVerb() { - Category = VerbCategory.Debug, - Text = "View Variables", + Text = Loc.GetString("view-variables"), Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/vv.svg.192dpi.png")), Act = () => _clientConsoleHost.ExecuteCommand($"vv {GetNetEntity(args.Target)}"), ClientExclusive = true // opening VV window is client-side. Don't ask server to run this verb. diff --git a/Content.Client/Administration/UI/AdminUIHelpers.cs b/Content.Client/Administration/UI/AdminUIHelpers.cs new file mode 100644 index 00000000000..89ab33e931d --- /dev/null +++ b/Content.Client/Administration/UI/AdminUIHelpers.cs @@ -0,0 +1,59 @@ +using System.Threading; +using Content.Client.Stylesheets; +using Robust.Client.UserInterface.Controls; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Client.Administration.UI; + +public static class AdminUIHelpers +{ + private static void ResetButton(Button button, ConfirmationData data) + { + data.Cancellation.Cancel(); + button.ModulateSelfOverride = null; + button.Text = data.OriginalText; + } + + public static bool RemoveConfirm(Button button, Dictionary confirmations) + { + if (confirmations.Remove(button, out var data)) + { + ResetButton(button, data); + return true; + } + + return false; + } + + public static void RemoveAllConfirms(Dictionary confirmations) + { + foreach (var (button, confirmation) in confirmations) + { + ResetButton(button, confirmation); + } + + confirmations.Clear(); + } + + public static bool TryConfirm(Button button, Dictionary confirmations) + { + if (RemoveConfirm(button, confirmations)) + return true; + + var data = new ConfirmationData(new CancellationTokenSource(), button.Text); + confirmations[button] = data; + + Timer.Spawn(TimeSpan.FromSeconds(5), () => + { + confirmations.Remove(button); + button.ModulateSelfOverride = null; + button.Text = data.OriginalText; + }, data.Cancellation.Token); + + button.ModulateSelfOverride = StyleNano.ButtonColorCautionDefault; + button.Text = Loc.GetString("admin-player-actions-confirm"); + return false; + } +} + +public readonly record struct ConfirmationData(CancellationTokenSource Cancellation, string? OriginalText); diff --git a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml index 05c68615ebb..28b55f987f3 100644 --- a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml +++ b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml @@ -6,14 +6,15 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineMenu.xaml.cs b/Content.Client/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineMenu.xaml.cs new file mode 100644 index 00000000000..3e150345da9 --- /dev/null +++ b/Content.Client/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineMenu.xaml.cs @@ -0,0 +1,111 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.ReverseEngineering; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.State; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Utility; + +namespace Content.Client.Nyanotrasen.ReverseEngineering; + +[GenerateTypedNameReferences] +public sealed partial class ReverseEngineeringMachineMenu : FancyWindow +{ + [Dependency] private readonly IEntityManager _ent = default!; + public event Action? OnScanButtonPressed; + public event Action? OnSafetyButtonToggled; + public event Action? OnAutoScanButtonToggled; + public event Action? OnStopButtonPressed; + public event Action? OnEjectButtonPressed; + + public ReverseEngineeringMachineMenu() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + ScanButton.OnPressed += a => OnScanButtonPressed?.Invoke(a); + SafetyButton.OnToggled += a => OnSafetyButtonToggled?.Invoke(a); + AutoScanButton.OnToggled += a => OnAutoScanButtonToggled?.Invoke(a); + StopButton.OnPressed += a => OnStopButtonPressed?.Invoke(a); + EjectButton.OnPressed += a => OnEjectButtonPressed?.Invoke(a); + } + + + public void SetButtonsDisabled(ReverseEngineeringMachineScanUpdateState state) + { + ScanButton.Disabled = !state.CanScan; + StopButton.Disabled = !state.Scanning; + SafetyButton.Pressed = state.Safety; + AutoScanButton.Pressed = state.AutoProbe; + EjectButton.Disabled = (state.Target == null || state.Scanning); + } + + private void UpdateArtifactIcon(EntityUid? uid) + { + if (uid == null) + { + ItemDisplay.Visible = false; + return; + } + ItemDisplay.Visible = true; + + if (!_ent.TryGetComponent(uid, out var sprite)) + return; + + ItemDisplay.Sprite = sprite; + } + + public void UpdateInformationDisplay(ReverseEngineeringMachineScanUpdateState state) + { + var message = new FormattedMessage(); + _ent.TryGetEntity(state.Target, out var entityTarget); + + UpdateArtifactIcon(entityTarget); + + if (state.ScanReport == null) + { + if (!state.CanScan) //no item + message.AddMarkup(Loc.GetString("analysis-console-info-no-artifact")); + else if (state.Target == null) //ready to go + message.AddMarkup(Loc.GetString("analysis-console-info-ready")); + } + else + { + message.AddMessage(state.ScanReport); + } + + Information.SetMessage(message); + } + + public void UpdateProbeTickProgressBar(ReverseEngineeringMachineScanUpdateState state) + { + ProgressBar.Visible = state.Scanning; + ProgressLabel.Visible = state.Scanning; + + if (!state.Scanning) + return; + + if (state.Target != null) + { + TotalProgressLabel.Visible = true; + TotalProgressLabel.Text = Loc.GetString("reverse-engineering-total-progress-label"); + TotalProgressBar.Visible = true; + TotalProgressBar.Value = (float) state.TotalProgress / 100f; + } else + { + TotalProgressLabel.Visible = false; + TotalProgressBar.Visible = false; + } + + ProgressLabel.Text = Loc.GetString("analysis-console-progress-text", + ("seconds", (int) state.TotalTime.TotalSeconds - (int) state.TimeRemaining.TotalSeconds)); + ProgressBar.Value = (float) state.TimeRemaining.Divide(state.TotalTime); + } + + public override void Close() + { + base.Close(); + } +} + diff --git a/Content.Client/Options/UI/OptionsMenu.xaml b/Content.Client/Options/UI/OptionsMenu.xaml index 8ecbc6f227a..5d028879fe8 100644 --- a/Content.Client/Options/UI/OptionsMenu.xaml +++ b/Content.Client/Options/UI/OptionsMenu.xaml @@ -3,9 +3,9 @@ Title="{Loc 'ui-options-title'}" MinSize="800 450"> - - - - + + + + diff --git a/Content.Client/Options/UI/OptionsMenu.xaml.cs b/Content.Client/Options/UI/OptionsMenu.xaml.cs index fdb3ac745b9..1a924d2af17 100644 --- a/Content.Client/Options/UI/OptionsMenu.xaml.cs +++ b/Content.Client/Options/UI/OptionsMenu.xaml.cs @@ -1,6 +1,9 @@ using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; +using Robust.Shared.IoC; +using Content.Client.Options.UI.Tabs; + namespace Content.Client.Options.UI { @@ -16,6 +19,13 @@ public OptionsMenu() Tabs.SetTabTitle(1, Loc.GetString("ui-options-tab-controls")); Tabs.SetTabTitle(2, Loc.GetString("ui-options-tab-audio")); Tabs.SetTabTitle(3, Loc.GetString("ui-options-tab-network")); + + UpdateTabs(); + } + + public void UpdateTabs() + { + GraphicsTab.UpdateProperties(); } } } diff --git a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs index 99076c853d7..852a3c28661 100644 --- a/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/GraphicsTab.xaml.cs @@ -229,6 +229,12 @@ private void UpdateApplyButton() private bool ConfigIsFullscreen => _cfg.GetCVar(CVars.DisplayWindowMode) == (int) WindowMode.Fullscreen; + public void UpdateProperties() + { + FullscreenCheckBox.Pressed = ConfigIsFullscreen; + } + + private float ConfigUIScale => _cfg.GetCVar(CVars.DisplayUIScale); private int GetConfigLightingQuality() diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index ba77c431609..188fe7740cc 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -61,7 +61,7 @@ void AddHeader(string headerContents) { if (!first) { - KeybindsContainer.AddChild(new Control {MinSize = new Vector2(0, 8)}); + KeybindsContainer.AddChild(new Control { MinSize = new Vector2(0, 8) }); } first = false; @@ -69,7 +69,7 @@ void AddHeader(string headerContents) { Text = Loc.GetString(headerContents), FontColorOverride = StyleNano.NanoGold, - StyleClasses = {StyleNano.StyleClassLabelKeyText} + StyleClasses = { StyleNano.StyleClassLabelKeyText } }); } @@ -82,7 +82,7 @@ void AddButton(BoundKeyFunction function) void AddCheckBox(string checkBoxName, bool currentState, Action? callBackOnClick) { - CheckBox newCheckBox = new CheckBox() { Text = Loc.GetString(checkBoxName)}; + CheckBox newCheckBox = new CheckBox() { Text = Loc.GetString(checkBoxName) }; newCheckBox.Pressed = currentState; newCheckBox.OnToggled += callBackOnClick; @@ -159,6 +159,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action(OnHandleState); + SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnGetCharacterInfoControls); } - private void OnHandleState(EntityUid uid, PointManagerComponent component, ref ComponentHandleState args) + private void OnHandleState(EntityUid uid, PointManagerComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not PointManagerComponentState state) - return; - - component.Points = new(state.Points); - component.Scoreboard = state.Scoreboard; _characterInfo.RequestCharacterInfo(); } diff --git a/Content.Client/Projectiles/ProjectileSystem.cs b/Content.Client/Projectiles/ProjectileSystem.cs index 07da813045f..2132256b1bd 100644 --- a/Content.Client/Projectiles/ProjectileSystem.cs +++ b/Content.Client/Projectiles/ProjectileSystem.cs @@ -1,9 +1,10 @@ using Content.Shared.Projectiles; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Weapons.Ranged.Systems; using Robust.Client.Animations; using Robust.Client.GameObjects; using Robust.Shared.GameStates; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Client.Projectiles; diff --git a/Content.Client/Radiation/Systems/GeigerSystem.cs b/Content.Client/Radiation/Systems/GeigerSystem.cs index 7a193d4a751..ffb0ad426e3 100644 --- a/Content.Client/Radiation/Systems/GeigerSystem.cs +++ b/Content.Client/Radiation/Systems/GeigerSystem.cs @@ -2,10 +2,6 @@ using Content.Client.Radiation.UI; using Content.Shared.Radiation.Components; using Content.Shared.Radiation.Systems; -using Robust.Client.GameObjects; -using Robust.Client.Player; -using Robust.Shared.GameStates; -using Robust.Shared.Player; namespace Content.Client.Radiation.Systems; @@ -14,19 +10,12 @@ public sealed class GeigerSystem : SharedGeigerSystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnHandleState); + SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnGetStatusMessage); } - private void OnHandleState(EntityUid uid, GeigerComponent component, ref ComponentHandleState args) + private void OnHandleState(EntityUid uid, GeigerComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not GeigerComponentState state) - return; - - component.CurrentRadiation = state.CurrentRadiation; - component.DangerLevel = state.DangerLevel; - component.IsEnabled = state.IsEnabled; - component.User = EnsureEntity(state.User, uid); component.UiUpdateNeeded = true; } diff --git a/Content.Client/Salvage/FultonSystem.cs b/Content.Client/Salvage/FultonSystem.cs index 05e7dd12d98..7e31fbb1808 100644 --- a/Content.Client/Salvage/FultonSystem.cs +++ b/Content.Client/Salvage/FultonSystem.cs @@ -1,6 +1,6 @@ using System.Numerics; using Content.Shared.Salvage.Fulton; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using JetBrains.Annotations; using Robust.Client.Animations; using Robust.Client.GameObjects; @@ -8,6 +8,7 @@ using Robust.Shared.Animations; using Robust.Shared.Serialization.Manager; using Robust.Shared.Utility; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Client.Salvage; diff --git a/Content.Client/SimpleStation14/Overlays/Shaders/NearsightedOverlays.cs b/Content.Client/SimpleStation14/Overlays/Shaders/NearsightedOverlays.cs new file mode 100644 index 00000000000..2597975bd4e --- /dev/null +++ b/Content.Client/SimpleStation14/Overlays/Shaders/NearsightedOverlays.cs @@ -0,0 +1,130 @@ +using Content.Shared.SimpleStation14.Traits.Components; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Player; +using Robust.Shared.Enums; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Client.SimpleStation14.Overlays.Shaders; + +public sealed class NearsightedOverlay : Overlay +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public override OverlaySpace Space => OverlaySpace.WorldSpace; + private readonly ShaderInstance _nearsightShader; + + public float Radius; + private float _oldRadius; + public float Darkness; + private float _oldDarkness; + + private float _lerpTime; + public float LerpDuration; + + + public NearsightedOverlay() + { + IoCManager.InjectDependencies(this); + _nearsightShader = _prototypeManager.Index("GradientCircleMask").InstanceUnique(); + } + + protected override bool BeforeDraw(in OverlayDrawArgs args) + { + // Check if the player has a NearsightedComponent and is controlling it + if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out NearsightedComponent? nearComp) || + _playerManager.LocalPlayer?.ControlledEntity != nearComp.Owner) + return false; + + // Check if the player has an EyeComponent and if the overlay should be drawn for this eye + if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out EyeComponent? eyeComp) || + args.Viewport.Eye != eyeComp.Eye) + return false; + + return true; + } + + protected override void Draw(in OverlayDrawArgs args) + { + // We already checked if they have a NearsightedComponent and are controlling it in BeforeDraw, so we assume this hasn't changed + var nearComp = _entityManager.GetComponent(_playerManager.LocalPlayer!.ControlledEntity!.Value); + + // Set LerpDuration based on nearComp.LerpDuration + LerpDuration = nearComp.LerpDuration; + + // Set the radius and darkness values based on whether the player is wearing glasses or not + if (nearComp.Active) + { + Radius = nearComp.EquippedRadius; + Darkness = nearComp.EquippedAlpha; + } + else + { + Radius = nearComp.Radius; + Darkness = nearComp.Alpha; + } + + + var viewport = args.WorldAABB; + var handle = args.WorldHandle; + var distance = args.ViewportBounds.Width; + + var lastFrameTime = (float) _timing.FrameTime.TotalSeconds; + + + // If the current radius value is different from the previous one, lerp between them + if (!MathHelper.CloseTo(_oldRadius, Radius, 0.001f)) + { + _lerpTime += lastFrameTime; + var t = MathHelper.Clamp(_lerpTime / LerpDuration, 0f, 1f); // Calculate lerp time + _oldRadius = MathHelper.Lerp(_oldRadius, Radius, t); // Lerp between old and new radius values + } + // If the current radius value is the same as the previous one, reset the lerp time and old radius value + else + { + _lerpTime = 0f; + _oldRadius = Radius; + } + + // If the current darkness value is different from the previous one, lerp between them + if (!MathHelper.CloseTo(_oldDarkness, Darkness, 0.001f)) + { + _lerpTime += lastFrameTime; + var t = MathHelper.Clamp(_lerpTime / LerpDuration, 0f, 1f); // Calculate lerp time + _oldDarkness = MathHelper.Lerp(_oldDarkness, Darkness, t); // Lerp between old and new darkness values + } + // If the current darkness value is the same as the previous one, reset the lerp time and old darkness value + else + { + _lerpTime = 0f; + _oldDarkness = Darkness; + } + + + // Calculate the outer and inner radii based on the current radius value + var outerMaxLevel = 0.6f * distance; + var outerMinLevel = 0.06f * distance; + var innerMaxLevel = 0.02f * distance; + var innerMinLevel = 0.02f * distance; + + var outerRadius = outerMaxLevel - _oldRadius * (outerMaxLevel - outerMinLevel); + var innerRadius = innerMaxLevel - _oldRadius * (innerMaxLevel - innerMinLevel); + + // Set the shader parameters and draw the overlay + _nearsightShader.SetParameter("time", 0.0f); + _nearsightShader.SetParameter("color", new Vector3(1f, 1f, 1f)); + _nearsightShader.SetParameter("darknessAlphaOuter", _oldDarkness); + _nearsightShader.SetParameter("innerCircleRadius", innerRadius); + _nearsightShader.SetParameter("innerCircleMaxRadius", innerRadius); + _nearsightShader.SetParameter("outerCircleRadius", outerRadius); + _nearsightShader.SetParameter("outerCircleMaxRadius", outerRadius + 0.2f * distance); + handle.UseShader(_nearsightShader); + handle.DrawRect(viewport, Color.Black); + + handle.UseShader(null); + } +} diff --git a/Content.Client/SimpleStation14/Overlays/Systems/NearsightedSystems.cs b/Content.Client/SimpleStation14/Overlays/Systems/NearsightedSystems.cs new file mode 100644 index 00000000000..ef413ec65d3 --- /dev/null +++ b/Content.Client/SimpleStation14/Overlays/Systems/NearsightedSystems.cs @@ -0,0 +1,58 @@ +using Content.Client.SimpleStation14.Overlays.Shaders; +using Content.Shared.Inventory.Events; +using Content.Shared.SimpleStation14.Traits; +using Content.Shared.SimpleStation14.Traits.Components; +using Content.Shared.Tag; +using Robust.Client.Graphics; + +namespace Content.Client.SimpleStation14.Overlays.Systems; + +public sealed class NearsightedSystem : EntitySystem +{ + [Dependency] private readonly IOverlayManager _overlayMan = default!; + + private NearsightedOverlay _overlay = default!; + + public override void Initialize() + { + base.Initialize(); + + _overlay = new NearsightedOverlay(); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnEquip); + SubscribeLocalEvent(OnUnEquip); + } + + + private void OnStartup(EntityUid uid, NearsightedComponent component, ComponentStartup args) + { + UpdateShader(component, false); + } + + private void OnEquip(GotEquippedEvent args) + { + if (TryComp(args.Equipee, out var nearsighted) && + EnsureComp(args.Equipment).Tags.Contains("GlassesNearsight")) + UpdateShader(nearsighted, true); + } + + private void OnUnEquip(GotUnequippedEvent args) + { + if (TryComp(args.Equipee, out var nearsighted) && + EnsureComp(args.Equipment).Tags.Contains("GlassesNearsight")) + UpdateShader(nearsighted, false); + } + + + private void UpdateShader(NearsightedComponent component, bool booLean) + { + while (_overlayMan.HasOverlay()) + { + _overlayMan.RemoveOverlay(_overlay); + } + + component.Active = booLean; + _overlayMan.AddOverlay(_overlay); + } +} diff --git a/Content.Client/Spawners/TimedDespawnSystem.cs b/Content.Client/Spawners/TimedDespawnSystem.cs deleted file mode 100644 index 14e34dce44e..00000000000 --- a/Content.Client/Spawners/TimedDespawnSystem.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Content.Shared.Spawners.EntitySystems; - -namespace Content.Client.Spawners; - -public sealed class TimedDespawnSystem : SharedTimedDespawnSystem -{ - protected override bool CanDelete(EntityUid uid) - { - return IsClientSide(uid); - } -} diff --git a/Content.Client/Tabletop/TabletopSystem.cs b/Content.Client/Tabletop/TabletopSystem.cs index d43111f39c1..c71c34d0efd 100644 --- a/Content.Client/Tabletop/TabletopSystem.cs +++ b/Content.Client/Tabletop/TabletopSystem.cs @@ -11,7 +11,6 @@ using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; -using Robust.Shared.GameStates; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; @@ -49,7 +48,6 @@ public override void Initialize() .Register(); SubscribeNetworkEvent(OnTabletopPlay); - SubscribeLocalEvent(HandleComponentState); SubscribeLocalEvent(HandleDraggableRemoved); SubscribeLocalEvent(OnAppearanceChange); } @@ -148,13 +146,6 @@ private void OnTabletopPlay(TabletopPlayEvent msg) _window.OnClose += OnWindowClose; } - private void HandleComponentState(EntityUid uid, TabletopDraggableComponent component, ref ComponentHandleState args) - { - if (args.Current is not TabletopDraggableComponentState state) return; - - component.DraggingPlayer = state.DraggingPlayer; - } - private void OnWindowClose() { if (_table != null) diff --git a/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs b/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs index f26d33f5f87..87d4b8072fc 100644 --- a/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs +++ b/Content.Client/UserInterface/Systems/Bwoink/AHelpUIController.cs @@ -437,6 +437,14 @@ private void EnsureControl() } } + public void HideAllPanels() + { + foreach (var panel in _activePanelMap.Values) + { + panel.Visible = false; + } + } + public BwoinkPanel EnsurePanel(NetUserId channelId) { EnsureControl(); diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index 0451a4a3aa0..98813992967 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -16,6 +16,7 @@ using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Chat; +using Content.Shared.Damage.ForceSay; using Content.Shared.Examine; using Content.Shared.Input; using Content.Shared.Radio; @@ -30,6 +31,7 @@ using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Network; +using Robust.Shared.Random; using Robust.Shared.Replays; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -164,6 +166,7 @@ public override void Initialize() _player.LocalPlayerChanged += OnLocalPlayerChanged; _state.OnStateChanged += StateChanged; _net.RegisterNetMessage(OnChatMessage); + SubscribeNetworkEvent(OnDamageForceSay); _speechBubbleRoot = new LayoutContainer(); @@ -774,6 +777,37 @@ public void SendMessage(ChatBox box, ChatSelectChannel channel) _manager.SendMessage(text, prefixChannel == 0 ? channel : prefixChannel); } + private void OnDamageForceSay(DamageForceSayEvent ev, EntitySessionEventArgs _) + { + if (UIManager.ActiveScreen?.GetWidget() is not { } chatBox) + return; + + // Don't send on OOC/LOOC obviously! + if (chatBox.SelectedChannel is not + (ChatSelectChannel.Local or + ChatSelectChannel.Radio or + ChatSelectChannel.Whisper)) + return; + + if (_player.LocalPlayer?.ControlledEntity is not { } ent + || !EntityManager.TryGetComponent(ent, out var forceSay)) + return; + + var msg = chatBox.ChatInput.Input.Text.TrimEnd(); + + if (string.IsNullOrWhiteSpace(msg)) + return; + + var modifiedText = ev.Suffix != null + ? Loc.GetString(forceSay.ForceSayMessageWrap, + ("message", msg), ("suffix", ev.Suffix)) + : Loc.GetString(forceSay.ForceSayMessageWrapNoSuffix, + ("message", msg)); + + chatBox.ChatInput.Input.SetText(modifiedText); + chatBox.ChatInput.Input.ForceSubmitText(); + } + private void OnChatMessage(MsgChatMessage message) { var msg = message.Message; diff --git a/Content.Client/UserInterface/Systems/EscapeMenu/OptionsUIController.cs b/Content.Client/UserInterface/Systems/EscapeMenu/OptionsUIController.cs index 70a9847331a..fedd64a43ff 100644 --- a/Content.Client/UserInterface/Systems/EscapeMenu/OptionsUIController.cs +++ b/Content.Client/UserInterface/Systems/EscapeMenu/OptionsUIController.cs @@ -47,6 +47,8 @@ public void OpenWindow() { EnsureWindow(); + _optionsWindow.UpdateTabs(); + _optionsWindow.OpenCentered(); _optionsWindow.MoveToFront(); } diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.Ballistic.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.Ballistic.cs index e0d4fa8e84d..b0e3566bdc8 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.Ballistic.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.Ballistic.cs @@ -39,7 +39,7 @@ protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent comp else if (component.UnspawnedCount > 0) { component.UnspawnedCount--; - ent = Spawn(component.FillProto, coordinates); + ent = Spawn(component.Proto, coordinates); EnsureShootable(ent.Value); } diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index 84284c9a506..72f0c2130bd 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -3,7 +3,7 @@ using Content.Client.Weapons.Ranged.Components; using Content.Shared.Camera; using Content.Shared.CombatMode; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Weapons.Ranged; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; @@ -19,6 +19,7 @@ using Robust.Shared.Prototypes; using Robust.Shared.Utility; using SharedGunSystem = Content.Shared.Weapons.Ranged.Systems.SharedGunSystem; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Client.Weapons.Ranged.Systems; diff --git a/Content.IntegrationTests/Pair/TestPair.Helpers.cs b/Content.IntegrationTests/Pair/TestPair.Helpers.cs index 1478a4c7d27..510dc0b854a 100644 --- a/Content.IntegrationTests/Pair/TestPair.Helpers.cs +++ b/Content.IntegrationTests/Pair/TestPair.Helpers.cs @@ -76,4 +76,22 @@ private static EntityUid ConvertUid( return otherUid.Value; } + + /// + /// Execute a command on the server and wait some number of ticks. + /// + public async Task WaitCommand(string cmd, int numTicks = 10) + { + await Server.ExecuteCommand(cmd); + await RunTicksSync(numTicks); + } + + /// + /// Execute a command on the client and wait some number of ticks. + /// + public async Task WaitClientCommand(string cmd, int numTicks = 10) + { + await Client.ExecuteCommand(cmd); + await RunTicksSync(numTicks); + } } diff --git a/Content.Server/Access/Components/PresetIdCardComponent.cs b/Content.Server/Access/Components/PresetIdCardComponent.cs index 89850866d65..a2842d7815f 100644 --- a/Content.Server/Access/Components/PresetIdCardComponent.cs +++ b/Content.Server/Access/Components/PresetIdCardComponent.cs @@ -5,5 +5,8 @@ public sealed partial class PresetIdCardComponent : Component { [DataField("job")] public string? JobName; + + [DataField("name")] + public string? IdName; } } diff --git a/Content.Server/Access/Systems/AccessOverriderSystem.cs b/Content.Server/Access/Systems/AccessOverriderSystem.cs index a41c0839da1..3ec767c200d 100644 --- a/Content.Server/Access/Systems/AccessOverriderSystem.cs +++ b/Content.Server/Access/Systems/AccessOverriderSystem.cs @@ -1,15 +1,15 @@ +using System.Linq; +using Content.Server.Popups; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.Administration.Logs; using Content.Shared.Database; +using Content.Shared.DoAfter; using Content.Shared.Interaction; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Containers; -using System.Linq; using static Content.Shared.Access.Components.AccessOverriderComponent; -using Content.Server.Popups; -using Content.Shared.DoAfter; namespace Content.Server.Access.Systems; @@ -46,7 +46,7 @@ private void AfterInteractOn(EntityUid uid, AccessOverriderComponent component, if (!_interactionSystem.InRangeUnobstructed(args.User, (EntityUid) args.Target)) return; - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.DoAfterTime, new AccessOverriderDoAfterEvent(), uid, target: args.Target, used: uid) + var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.DoAfter, new AccessOverriderDoAfterEvent(), uid, target: args.Target, used: uid) { BreakOnTargetMove = true, BreakOnUserMove = true, diff --git a/Content.Server/Access/Systems/PresetIdCardSystem.cs b/Content.Server/Access/Systems/PresetIdCardSystem.cs index 271e16cbf93..96a38278b5b 100644 --- a/Content.Server/Access/Systems/PresetIdCardSystem.cs +++ b/Content.Server/Access/Systems/PresetIdCardSystem.cs @@ -37,6 +37,7 @@ private void PlayerJobsAssigned(RulePlayerJobsAssignedEvent ev) return; SetupIdAccess(uid, card, true); + SetupIdName(uid, card); } } @@ -53,6 +54,14 @@ private void OnMapInit(EntityUid uid, PresetIdCardComponent id, MapInitEvent arg extended = Comp(station.Value).ExtendedAccess; SetupIdAccess(uid, id, extended); + SetupIdName(uid, id); + } + + private void SetupIdName(EntityUid uid, PresetIdCardComponent id) + { + if (id.IdName == null) + return; + _cardSystem.TryChangeFullName(uid, id.IdName); } private void SetupIdAccess(EntityUid uid, PresetIdCardComponent id, bool extended) diff --git a/Content.Server/Administration/Commands/RoleUnbanCommand.cs b/Content.Server/Administration/Commands/RoleUnbanCommand.cs index ba8ab61c5c1..a49f1231bf4 100644 --- a/Content.Server/Administration/Commands/RoleUnbanCommand.cs +++ b/Content.Server/Administration/Commands/RoleUnbanCommand.cs @@ -1,7 +1,5 @@ -using System.Text; -using Content.Server.Database; +using Content.Server.Administration.Managers; using Content.Shared.Administration; -using Robust.Server.Player; using Robust.Shared.Console; namespace Content.Server.Administration.Commands; @@ -15,9 +13,6 @@ public sealed class RoleUnbanCommand : IConsoleCommand public async void Execute(IConsoleShell shell, string argStr, string[] args) { - var player = shell.Player as IPlayerSession; - var dbMan = IoCManager.Resolve(); - if (args.Length != 1) { shell.WriteLine(Help); @@ -30,32 +25,9 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args) return; } - var ban = await dbMan.GetServerRoleBanAsync(banId); - - if (ban == null) - { - shell.WriteLine($"No ban found with id {banId}"); - return; - } - - if (ban.Unban != null) - { - var response = new StringBuilder("This ban has already been pardoned"); - - if (ban.Unban.UnbanningAdmin != null) - { - response.Append($" by {ban.Unban.UnbanningAdmin.Value}"); - } - - response.Append($" in {ban.Unban.UnbanTime}."); - - shell.WriteLine(response.ToString()); - return; - } - - await dbMan.AddServerRoleUnbanAsync(new ServerRoleUnbanDef(banId, player?.UserId, DateTimeOffset.Now)); - - shell.WriteLine($"Pardoned ban with id {banId}"); + var banManager = IoCManager.Resolve(); + var response = await banManager.PardonRoleBan(banId, shell.Player?.UserId, DateTimeOffset.Now); + shell.WriteLine(response); } public CompletionResult GetCompletion(IConsoleShell shell, string[] args) diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 4640c63dbd2..765df17b179 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -1,21 +1,22 @@ using System.Collections.Immutable; using System.Linq; using System.Net; +using System.Text; using System.Threading.Tasks; using Content.Server.Chat.Managers; using Content.Server.Database; using Content.Server.GameTicking; +using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; using Content.Shared.Roles; -using Microsoft.CodeAnalysis; -using Content.Shared.CCVar; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; using Robust.Shared.Network; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.Server.Administration.Managers; @@ -47,28 +48,25 @@ public void Initialize() private async void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) { - if (e.NewStatus != SessionStatus.Connected - || _cachedRoleBans.ContainsKey(e.Session.UserId)) + if (e.NewStatus != SessionStatus.Connected || _cachedRoleBans.ContainsKey(e.Session.UserId)) return; var netChannel = e.Session.ConnectedClient; - await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId); + ImmutableArray? hwId = netChannel.UserData.HWId.Length == 0 ? null : netChannel.UserData.HWId; + await CacheDbRoleBans(e.Session.UserId, netChannel.RemoteEndPoint.Address, hwId); + + SendRoleBans(e.Session); } private async Task AddRoleBan(ServerRoleBanDef banDef) { + banDef = await _db.AddServerRoleBanAsync(banDef); + if (banDef.UserId != null) { - if (!_cachedRoleBans.TryGetValue(banDef.UserId.Value, out var roleBans)) - { - roleBans = new HashSet(); - _cachedRoleBans.Add(banDef.UserId.Value, roleBans); - } - if (!roleBans.Contains(banDef)) - roleBans.Add(banDef); + _cachedRoleBans.GetOrNew(banDef.UserId.Value).Add(banDef); } - await _db.AddServerRoleBanAsync(banDef); return true; } @@ -231,6 +229,39 @@ public async void CreateRoleBan(NetUserId? target, string? targetUsername, NetUs } } + public async Task PardonRoleBan(int banId, NetUserId? unbanningAdmin, DateTimeOffset unbanTime) + { + var ban = await _db.GetServerRoleBanAsync(banId); + + if (ban == null) + { + return $"No ban found with id {banId}"; + } + + if (ban.Unban != null) + { + var response = new StringBuilder("This ban has already been pardoned"); + + if (ban.Unban.UnbanningAdmin != null) + { + response.Append($" by {ban.Unban.UnbanningAdmin.Value}"); + } + + response.Append($" in {ban.Unban.UnbanTime}."); + return response.ToString(); + } + + await _db.AddServerRoleUnbanAsync(new ServerRoleUnbanDef(banId, unbanningAdmin, DateTimeOffset.Now)); + + if (ban.UserId is { } player && _cachedRoleBans.TryGetValue(player, out var roleBans)) + { + roleBans.RemoveWhere(roleBan => roleBan.Id == ban.Id); + SendRoleBans(player); + } + + return $"Pardoned ban with id {banId}"; + } + public HashSet? GetJobBans(NetUserId playerUserId) { if (!_cachedRoleBans.TryGetValue(playerUserId, out var roleBans)) @@ -254,12 +285,7 @@ public void SendRoleBans(NetUserId userId) public void SendRoleBans(IPlayerSession pSession) { - if (!_cachedRoleBans.TryGetValue(pSession.UserId, out var roleBans)) - { - _sawmill.Error($"Tried to send rolebans for {pSession.Name} but none cached?"); - return; - } - + var roleBans = _cachedRoleBans.GetValueOrDefault(pSession.UserId) ?? new HashSet(); var bans = new MsgRoleBans() { Bans = roleBans.Select(o => o.Role).ToList() diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index 6d991c7576f..8458feac8d0 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -1,8 +1,9 @@ using System.Collections.Immutable; +using System.Net; +using System.Threading.Tasks; using Content.Shared.Database; using Robust.Server.Player; using Robust.Shared.Network; -using System.Net; namespace Content.Server.Administration.Managers; @@ -24,18 +25,26 @@ public interface IBanManager public void CreateServerBan(NetUserId? target, string? targetUsername, NetUserId? banningAdmin, (IPAddress, int)? addressRange, ImmutableArray? hwid, uint? minutes, NoteSeverity severity, string reason); public HashSet? GetRoleBans(NetUserId playerUserId); public HashSet? GetJobBans(NetUserId playerUserId); + /// /// Creates a job ban for the specified target, username or GUID /// - /// Shell reference so we can write messages /// Target user, username or GUID, null for none - /// Job to be banned from + /// Role to be banned from /// Severity of the resulting ban note /// Reason for the ban /// Number of minutes to ban for. 0 and null mean permanent /// Time when the ban was applied, used for grouping role bans public void CreateRoleBan(NetUserId? target, string? targetUsername, NetUserId? banningAdmin, (IPAddress, int)? addressRange, ImmutableArray? hwid, string role, uint? minutes, NoteSeverity severity, string reason, DateTimeOffset timeOfBan); + /// + /// Pardons a role ban for the specified target, username or GUID + /// + /// The id of the role ban to pardon. + /// The admin, if any, that pardoned the role ban. + /// The time at which this role ban was pardoned. + public Task PardonRoleBan(int banId, NetUserId? unbanningAdmin, DateTimeOffset unbanTime); + /// /// Sends role bans to the target /// diff --git a/Content.Server/Armor/ArmorComponent.cs b/Content.Server/Armor/ArmorComponent.cs deleted file mode 100644 index 09be3bf2401..00000000000 --- a/Content.Server/Armor/ArmorComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Content.Shared.Damage; - -namespace Content.Server.Armor -{ - [RegisterComponent] - public sealed partial class ArmorComponent : Component - { - [DataField("modifiers", required: true)] - public DamageModifierSet Modifiers = default!; - } -} diff --git a/Content.Server/Armor/ArmorSystem.cs b/Content.Server/Armor/ArmorSystem.cs index dc02b06667e..dc4b3c7935f 100644 --- a/Content.Server/Armor/ArmorSystem.cs +++ b/Content.Server/Armor/ArmorSystem.cs @@ -1,125 +1,34 @@ -using Content.Shared.Damage; -using Content.Server.Examine; -using Content.Shared.Verbs; -using Robust.Shared.Utility; using Content.Server.Cargo.Systems; +using Content.Shared.Armor; using Robust.Shared.Prototypes; using Content.Shared.Damage.Prototypes; -using Content.Shared.Inventory; -using Content.Shared.Silicons.Borgs; -namespace Content.Server.Armor -{ - public sealed class ArmorSystem : EntitySystem - { - const double CoefDefaultPrice = 2; // default price of 1% protection against any type of damage - const double FlatDefaultPrice = 10; //default price of 1 damage protection against a certain type of damage - - [Dependency] private readonly ExamineSystem _examine = default!; - [Dependency] private readonly IPrototypeManager _protoManager = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent>(OnDamageModify); - SubscribeLocalEvent>(OnBorgDamageModify); - SubscribeLocalEvent>(OnArmorVerbExamine); - SubscribeLocalEvent(GetArmorPrice); - } - - private void GetArmorPrice(EntityUid uid, ArmorComponent component, ref PriceCalculationEvent args) - { - if (component.Modifiers == null) - return; - - double price = 0; - - foreach (var modifier in component.Modifiers.Coefficients) - { - _protoManager.TryIndex(modifier.Key, out DamageTypePrototype? damageType); - - if (damageType != null) - { - price += damageType.ArmorPriceCoefficient * 100 * (1 - modifier.Value); - } - else - { - price += CoefDefaultPrice * 100 * (1 - modifier.Value); - } - } - foreach (var modifier in component.Modifiers.FlatReduction) - { - _protoManager.TryIndex(modifier.Key, out DamageTypePrototype? damageType); +namespace Content.Server.Armor; - if (damageType != null) - { - price += damageType.ArmorPriceFlat * modifier.Value; - } - else - { - price += FlatDefaultPrice * modifier.Value; - } - } - args.Price += price; - } +/// +public sealed class ArmorSystem : SharedArmorSystem +{ + [Dependency] private readonly IPrototypeManager _protoManager = default!; - private void OnDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent args) - { - args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); - } + public override void Initialize() + { + base.Initialize(); - private void OnBorgDamageModify(EntityUid uid, ArmorComponent component, ref BorgModuleRelayedEvent args) - { - args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); - } + SubscribeLocalEvent(GetArmorPrice); + } - private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerbsEvent args) + private void GetArmorPrice(EntityUid uid, ArmorComponent component, ref PriceCalculationEvent args) + { + foreach (var modifier in component.Modifiers.Coefficients) { - if (!args.CanInteract || !args.CanAccess) - return; - - var armorModifiers = component.Modifiers; - - if (armorModifiers == null) - return; - - var examineMarkup = GetArmorExamine(armorModifiers); - - var ev = new ArmorExamineEvent(examineMarkup); - RaiseLocalEvent(uid, ref ev); - - _examine.AddDetailedExamineVerb(args, component, examineMarkup, Loc.GetString("armor-examinable-verb-text"), "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", Loc.GetString("armor-examinable-verb-message")); + var damageType = _protoManager.Index(modifier.Key); + args.Price += damageType.ArmorPriceCoefficient * 100 * (1 - modifier.Value); } - private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers) + foreach (var modifier in component.Modifiers.FlatReduction) { - var msg = new FormattedMessage(); - - msg.AddMarkup(Loc.GetString("armor-examine")); - - foreach (var coefficientArmor in armorModifiers.Coefficients) - { - msg.PushNewline(); - msg.AddMarkup(Loc.GetString("armor-coefficient-value", - ("type", coefficientArmor.Key), - ("value", MathF.Round((1f - coefficientArmor.Value) * 100,1)) - )); - } - - foreach (var flatArmor in armorModifiers.FlatReduction) - { - msg.PushNewline(); - msg.AddMarkup(Loc.GetString("armor-reduction-value", - ("type", flatArmor.Key), - ("value", flatArmor.Value) - )); - } - - return msg; + var damageType = _protoManager.Index(modifier.Key); + args.Price += damageType.ArmorPriceFlat * modifier.Value; } } } - -[ByRefEvent] -public record struct ArmorExamineEvent(FormattedMessage Msg); diff --git a/Content.Server/Atmos/Piping/Binary/Components/GasVolumePumpComponent.cs b/Content.Server/Atmos/Piping/Binary/Components/GasVolumePumpComponent.cs index bdd85524a8a..36ced3887d2 100644 --- a/Content.Server/Atmos/Piping/Binary/Components/GasVolumePumpComponent.cs +++ b/Content.Server/Atmos/Piping/Binary/Components/GasVolumePumpComponent.cs @@ -9,6 +9,9 @@ public sealed partial class GasVolumePumpComponent : Component [DataField("enabled")] public bool Enabled { get; set; } = true; + [DataField("blocked")] + public bool Blocked { get; set; } = false; + [ViewVariables(VVAccess.ReadWrite)] public bool Overclocked { get; set; } = false; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs index aa171ce6ba3..5b8035681e0 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Atmos.Piping; using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Atmos.Piping.Unary.Components; +using Content.Shared.Atmos.Visuals; using Content.Shared.Audio; using Content.Shared.Database; using Content.Shared.Examine; @@ -83,12 +84,24 @@ private void OnVolumePumpUpdated(EntityUid uid, GasVolumePumpComponent pump, Atm var inputStartingPressure = inlet.Air.Pressure; var outputStartingPressure = outlet.Air.Pressure; + var previouslyBlocked = pump.Blocked; + pump.Blocked = false; + // Pump mechanism won't do anything if the pressure is too high/too low unless you overclock it. if ((inputStartingPressure < pump.LowerThreshold) || (outputStartingPressure > pump.HigherThreshold) && !pump.Overclocked) - return; + { + pump.Blocked = true; + } // Overclocked pumps can only force gas a certain amount. if ((outputStartingPressure - inputStartingPressure > pump.OverclockThreshold) && pump.Overclocked) + { + pump.Blocked = true; + } + + if (previouslyBlocked != pump.Blocked) + UpdateAppearance(uid, pump); + if (pump.Blocked) return; // We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters. @@ -172,7 +185,12 @@ private void UpdateAppearance(EntityUid uid, GasVolumePumpComponent? pump = null if (!Resolve(uid, ref pump, ref appearance, false)) return; - _appearance.SetData(uid, PumpVisuals.Enabled, pump.Enabled, appearance); + if (!pump.Enabled) + _appearance.SetData(uid, GasVolumePumpVisuals.State, GasVolumePumpState.Off, appearance); + else if (pump.Blocked) + _appearance.SetData(uid, GasVolumePumpVisuals.State, GasVolumePumpState.Blocked, appearance); + else + _appearance.SetData(uid, GasVolumePumpVisuals.State, GasVolumePumpState.On, appearance); } private void OnPacketRecv(EntityUid uid, GasVolumePumpComponent component, DeviceNetworkPacketEvent args) diff --git a/Content.Server/BarSign/Systems/BarSignSystem.cs b/Content.Server/BarSign/Systems/BarSignSystem.cs index c26fe2c2884..4a481408452 100644 --- a/Content.Server/BarSign/Systems/BarSignSystem.cs +++ b/Content.Server/BarSign/Systems/BarSignSystem.cs @@ -1,6 +1,5 @@ using System.Linq; using Content.Shared.BarSign; -using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -15,17 +14,11 @@ public sealed class BarSignSystem : EntitySystem public override void Initialize() { SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnGetState); - } - - private void OnGetState(EntityUid uid, BarSignComponent component, ref ComponentGetState args) - { - args.State = new BarSignComponentState(component.CurrentSign); } private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent args) { - if (component.CurrentSign != null) + if (component.Current != null) return; var prototypes = _prototypeManager @@ -40,7 +33,7 @@ private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent a _metaData.SetEntityName(uid, Loc.GetString(name), meta); _metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta); - component.CurrentSign = newPrototype.ID; + component.Current = newPrototype.ID; Dirty(component); } } diff --git a/Content.Server/Body/Systems/BrainSystem.cs b/Content.Server/Body/Systems/BrainSystem.cs index 629db0a1fb1..16a2a6737b0 100644 --- a/Content.Server/Body/Systems/BrainSystem.cs +++ b/Content.Server/Body/Systems/BrainSystem.cs @@ -19,25 +19,10 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent((uid, _, args) => HandleMind(args.Body, uid)); - SubscribeLocalEvent((uid, _, args) => HandleMind(args.Part, uid)); SubscribeLocalEvent((uid, _, args) => HandleMind(args.Body, uid)); - SubscribeLocalEvent(OnRemovedFromBody); - SubscribeLocalEvent((uid, _, args) => HandleMind(uid, args.Old)); SubscribeLocalEvent((uid, _, args) => HandleMind(args.OldBody, uid)); } - private void OnRemovedFromBody(EntityUid uid, BrainComponent component, RemovedFromBodyEvent args) - { - // This one needs to be special, okay? - if (!EntityManager.TryGetComponent(uid, out OrganComponent? organ)) - { - return; - } - - HandleMind(uid, args.Old); - } - private void HandleMind(EntityUid newEntity, EntityUid oldEntity) { EnsureComp(newEntity); diff --git a/Content.Server/Botany/SeedPrototype.cs b/Content.Server/Botany/SeedPrototype.cs index 3d700f2775e..82d5b8de10b 100644 --- a/Content.Server/Botany/SeedPrototype.cs +++ b/Content.Server/Botany/SeedPrototype.cs @@ -56,9 +56,26 @@ public enum PlantJuicy : byte [DataDefinition] public partial struct SeedChemQuantity { + /// + /// Minimum amount of chemical that is added to produce, regardless of the potency + /// [DataField("Min")] public int Min; + + /// + /// Maximum amount of chemical that can be produced after taking plant potency into account. + /// [DataField("Max")] public int Max; + + /// + /// When chemicals are added to produce, the potency of the seed is divided with this value. Final chemical amount is the result plus the `Min` value. + /// Example: PotencyDivisor of 20 with seed potency of 55 results in 2.75, 55/20 = 2.75. If minimum is 1 then final result will be 3.75 of that chemical, 55/20+1 = 3.75. + /// [DataField("PotencyDivisor")] public int PotencyDivisor; + + /// + /// Inherent chemical is one that is NOT result of mutation or crossbreeding. These chemicals are removed if species mutation is executed. + /// + [DataField("Inherent")] public bool Inherent = true; } // TODO reduce the number of friends to a reasonable level. Requires ECS-ing things like plant holder component. @@ -293,4 +310,82 @@ public SeedData Clone() return newSeed; } + + + /// + /// Handles copying most species defining data from 'other' to this seed while keeping the accumulated mutations intact. + /// + public SeedData SpeciesChange(SeedData other) + { + var newSeed = new SeedData + { + Name = other.Name, + Noun = other.Noun, + DisplayName = other.DisplayName, + Mysterious = other.Mysterious, + + PacketPrototype = other.PacketPrototype, + ProductPrototypes = new List(other.ProductPrototypes), + MutationPrototypes = new List(other.MutationPrototypes), + + Chemicals = new Dictionary(Chemicals), + ConsumeGasses = new Dictionary(ConsumeGasses), + ExudeGasses = new Dictionary(ExudeGasses), + + NutrientConsumption = NutrientConsumption, + WaterConsumption = WaterConsumption, + IdealHeat = IdealHeat, + HeatTolerance = HeatTolerance, + IdealLight = IdealLight, + LightTolerance = LightTolerance, + ToxinsTolerance = ToxinsTolerance, + LowPressureTolerance = LowPressureTolerance, + HighPressureTolerance = HighPressureTolerance, + PestTolerance = PestTolerance, + WeedTolerance = WeedTolerance, + + Endurance = Endurance, + Yield = Yield, + Lifespan = Lifespan, + Maturation = Maturation, + Production = Production, + GrowthStages = other.GrowthStages, + HarvestRepeat = HarvestRepeat, + Potency = Potency, + + Seedless = Seedless, + Viable = Viable, + Slip = Slip, + Sentient = Sentient, + Ligneous = Ligneous, + + PlantRsi = other.PlantRsi, + PlantIconState = other.PlantIconState, + Bioluminescent = Bioluminescent, + CanScream = CanScream, + TurnIntoKudzu = TurnIntoKudzu, + BioluminescentColor = BioluminescentColor, + SplatPrototype = other.SplatPrototype, + + // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified. + Unique = true, + }; + + // Adding the new chemicals from the new species. + foreach (var otherChem in other.Chemicals) + { + Chemicals.TryAdd(otherChem.Key, otherChem.Value); + } + + // Removing the inherent chemicals from the old species. Leaving mutated/crossbread ones intact. + foreach (var originalChem in Chemicals) + { + if (!other.Chemicals.ContainsKey(originalChem.Key) && originalChem.Value.Inherent) + { + Chemicals.Remove(originalChem.Key); + } + } + + return newSeed; + } } diff --git a/Content.Server/Botany/Systems/MutationSystem.cs b/Content.Server/Botany/Systems/MutationSystem.cs index 13ef8e37818..94a450ebeff 100644 --- a/Content.Server/Botany/Systems/MutationSystem.cs +++ b/Content.Server/Botany/Systems/MutationSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Chemistry.Reagent; using System.Linq; using Content.Shared.Atmos; +using FastAccessors; namespace Content.Server.Botany; @@ -269,6 +270,7 @@ private void MutateChemicals(ref Dictionary chemicals, { seedChemQuantity.Min = 1; seedChemQuantity.Max = 1 + amount; + seedChemQuantity.Inherent = false; } int potencyDivisor = (int) Math.Ceiling(100.0f / seedChemQuantity.Max); seedChemQuantity.PotencyDivisor = potencyDivisor; @@ -295,10 +297,7 @@ private void MutateSpecies(ref SeedData seed, int bits, int totalbits, float mul return; } - var oldSeed = seed.Clone(); - seed = protoSeed.Clone(); - seed.Potency = oldSeed.Potency; - seed.Yield = oldSeed.Yield; + seed = seed.SpeciesChange(protoSeed); } private Color RandomColor(Color color, int bits, int totalbits, float mult) @@ -330,12 +329,14 @@ private void CrossChemicals(ref Dictionary val, Dictio { val[otherChem.Key] = Random(0.5f) ? otherChem.Value : val[otherChem.Key]; } - // if target plant doesn't have this chemical, has 50% chance to add it. + // if target plant doesn't have this chemical, has 50% chance to add it. else { if (Random(0.5f)) { - val.Add(otherChem.Key, otherChem.Value); + var fixedChem = otherChem.Value; + fixedChem.Inherent = false; + val.Add(otherChem.Key, fixedChem); } } } diff --git a/Content.Server/Chat/SuicideSystem.cs b/Content.Server/Chat/SuicideSystem.cs index 2f6ac51d724..7f450a1ced7 100644 --- a/Content.Server/Chat/SuicideSystem.cs +++ b/Content.Server/Chat/SuicideSystem.cs @@ -41,6 +41,8 @@ public bool Suicide(EntityUid victim) if (SuicideAttemptBlocked(victim, suicideEvent)) return false; + return false; // DeltaV - Prevent Suicide. We allow the event to go out anyways in case anything relies on the event for a message or whatever. + bool environmentSuicide = false; // If you are critical, you wouldn't be able to use your surroundings to suicide, so you do the default suicide if (!_mobState.IsCritical(victim, mobState)) diff --git a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs index 8cff8a19cb6..d95490e9a01 100644 --- a/Content.Server/Chemistry/EntitySystems/VaporSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/VaporSystem.cs @@ -6,7 +6,7 @@ using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Content.Shared.Physics; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Throwing; using JetBrains.Annotations; using Robust.Shared.Map; @@ -15,6 +15,7 @@ using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.Chemistry.EntitySystems { diff --git a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs index 00266c39a85..be8dbbaf52a 100644 --- a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs +++ b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs @@ -23,7 +23,7 @@ public override void Effect(ReagentEffectArgs args) entityManager.RemoveComponent(uid); // Stops from adding a ghost role to things like people who already have a mind - if (entityManager.HasComponent(uid)) + if (entityManager.TryGetComponent(uid, out var mindContainer) && mindContainer.HasMind) { return; } diff --git a/Content.Server/Climbing/ClimbSystem.cs b/Content.Server/Climbing/ClimbSystem.cs index 73c0eda3f36..e9d25f361f2 100644 --- a/Content.Server/Climbing/ClimbSystem.cs +++ b/Content.Server/Climbing/ClimbSystem.cs @@ -21,7 +21,6 @@ using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Shared.GameStates; using Robust.Shared.Physics; using Robust.Shared.Physics.Collision.Shapes; using Robust.Shared.Physics.Components; @@ -62,7 +61,6 @@ public override void Initialize() SubscribeLocalEvent(OnDoAfter); SubscribeLocalEvent(OnClimbEndCollide); SubscribeLocalEvent(OnBuckleChange); - SubscribeLocalEvent(OnClimbingGetState); SubscribeLocalEvent(OnGlassClimbed); } @@ -366,11 +364,6 @@ private void OnBuckleChange(EntityUid uid, ClimbingComponent component, ref Buck StopClimb(uid, component); } - private static void OnClimbingGetState(EntityUid uid, ClimbingComponent component, ref ComponentGetState args) - { - args.State = new ClimbingComponent.ClimbModeComponentState(component.IsClimbing, component.OwnerIsTransitioning); - } - private void OnGlassClimbed(EntityUid uid, GlassTableComponent component, ClimbedOnEvent args) { if (TryComp(args.Climber, out var physics) && physics.Mass <= component.MassLimit) diff --git a/Content.Server/Clothing/Systems/ChameleonClothingSystem.cs b/Content.Server/Clothing/Systems/ChameleonClothingSystem.cs index 10fadbbba1c..7dc3b8489df 100644 --- a/Content.Server/Clothing/Systems/ChameleonClothingSystem.cs +++ b/Content.Server/Clothing/Systems/ChameleonClothingSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Prototypes; using Content.Shared.Verbs; using Robust.Server.GameObjects; -using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -22,22 +21,13 @@ public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(GetState); SubscribeLocalEvent>(OnVerb); SubscribeLocalEvent(OnSelected); } private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args) { - SetSelectedPrototype(uid, component.SelectedId, true, component); - } - - private void GetState(EntityUid uid, ChameleonClothingComponent component, ref ComponentGetState args) - { - args.State = new ChameleonClothingComponentState - { - SelectedId = component.SelectedId - }; + SetSelectedPrototype(uid, component.Default, true, component); } private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent args) @@ -72,7 +62,7 @@ private void UpdateUi(EntityUid uid, ChameleonClothingComponent? component = nul if (!Resolve(uid, ref component)) return; - var state = new ChameleonBoundUserInterfaceState(component.Slot, component.SelectedId); + var state = new ChameleonBoundUserInterfaceState(component.Slot, component.Default); _uiSystem.TrySetUiState(uid, ChameleonUiKey.Key, state); } @@ -87,7 +77,7 @@ public void SetSelectedPrototype(EntityUid uid, string? protoId, bool forceUpdat // check that wasn't already selected // forceUpdate on component init ignores this check - if (component.SelectedId == protoId && !forceUpdate) + if (component.Default == protoId && !forceUpdate) return; // make sure that it is valid change @@ -95,7 +85,7 @@ public void SetSelectedPrototype(EntityUid uid, string? protoId, bool forceUpdat return; if (!IsValidTarget(proto, component.Slot)) return; - component.SelectedId = protoId; + component.Default = protoId; UpdateIdentityBlocker(uid, component, proto); UpdateVisuals(uid, component); diff --git a/Content.Server/Communications/CommsHackerSystem.cs b/Content.Server/Communications/CommsHackerSystem.cs index 851be07454f..1248d214003 100644 --- a/Content.Server/Communications/CommsHackerSystem.cs +++ b/Content.Server/Communications/CommsHackerSystem.cs @@ -64,7 +64,7 @@ private void OnDoAfter(EntityUid uid, CommsHackerComponent comp, TerrorDoAfterEv var threats = _proto.Index(comp.Threats); var threat = threats.Pick(_random); - CallInThreat(_proto.Index(threat)); + CallInThreat(_proto.Index(threat)); // prevent calling in multiple threats RemComp(uid); @@ -76,10 +76,10 @@ private void OnDoAfter(EntityUid uid, CommsHackerComponent comp, TerrorDoAfterEv /// /// Makes announcement and adds game rule of the threat. /// - public void CallInThreat(ThreatPrototype threat) + public void CallInThreat(NinjaHackingThreatPrototype ninjaHackingThreat) { - _gameTicker.StartGameRule(threat.Rule, out _); - _chat.DispatchGlobalAnnouncement(Loc.GetString(threat.Announcement), playSound: true, colorOverride: Color.Red); + _gameTicker.StartGameRule(ninjaHackingThreat.Rule, out _); + _chat.DispatchGlobalAnnouncement(Loc.GetString(ninjaHackingThreat.Announcement), playSound: true, colorOverride: Color.Red); } } diff --git a/Content.Server/Cuffs/CuffableSystem.cs b/Content.Server/Cuffs/CuffableSystem.cs index 2b65803673b..2c28603c3f4 100644 --- a/Content.Server/Cuffs/CuffableSystem.cs +++ b/Content.Server/Cuffs/CuffableSystem.cs @@ -1,6 +1,6 @@ using Content.Shared.Cuffs; -using JetBrains.Annotations; using Content.Shared.Cuffs.Components; +using JetBrains.Annotations; using Robust.Shared.GameStates; namespace Content.Server.Cuffs @@ -12,15 +12,9 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnHandcuffGetState); SubscribeLocalEvent(OnCuffableGetState); } - private void OnHandcuffGetState(EntityUid uid, HandcuffComponent component, ref ComponentGetState args) - { - args.State = new HandcuffComponentState(component.OverlayIconState); - } - private void OnCuffableGetState(EntityUid uid, CuffableComponent component, ref ComponentGetState args) { // there are 2 approaches i can think of to handle the handcuff overlay on players @@ -34,7 +28,7 @@ private void OnCuffableGetState(EntityUid uid, CuffableComponent component, ref args.State = new CuffableComponentState(component.CuffedHandCount, component.CanStillInteract, cuffs?.CuffedRSI, - $"{cuffs?.OverlayIconState}-{component.CuffedHandCount}", + $"{cuffs?.BodyIconState}-{component.CuffedHandCount}", cuffs?.Color); // the iconstate is formatted as blah-2, blah-4, blah-6, etc. // the number corresponds to how many hands are cuffed. diff --git a/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs new file mode 100644 index 00000000000..3d3346403ad --- /dev/null +++ b/Content.Server/Damage/ForceSay/DamageForceSaySystem.cs @@ -0,0 +1,126 @@ +using Content.Shared.Damage; +using Content.Shared.Damage.ForceSay; +using Content.Shared.FixedPoint; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; +using Content.Shared.Stunnable; +using Robust.Server.GameObjects; +using Robust.Server.Player; +using Robust.Shared.Players; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Damage.ForceSay; + +/// +public sealed class DamageForceSaySystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStunned); + SubscribeLocalEvent(OnMobStateChanged); + + // need to raise after mobthreshold + // so that we don't accidentally raise one for damage before one for mobstate + // (this won't double raise, because of the cooldown) + SubscribeLocalEvent(OnDamageChanged, after: new []{ typeof(MobThresholdSystem)} ); + SubscribeLocalEvent(OnSleep); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = AllEntityQuery(); + while (query.MoveNext(out var uid, out var comp)) + { + if (_timing.CurTime < comp.Timeout) + continue; + + RemCompDeferred(uid); + } + } + + private void TryForceSay(EntityUid uid, DamageForceSayComponent component, bool useSuffix=true, string? suffixOverride = null) + { + if (!TryComp(uid, out var actor)) + return; + + // disallow if cooldown hasn't ended + if (component.NextAllowedTime != null && + _timing.CurTime < component.NextAllowedTime) + return; + + var suffix = Loc.GetString(suffixOverride ?? component.ForceSayStringPrefix + _random.Next(1, component.ForceSayStringCount)); + + // set cooldown & raise event + component.NextAllowedTime = _timing.CurTime + component.Cooldown; + RaiseNetworkEvent(new DamageForceSayEvent { Suffix = useSuffix ? suffix : null }, actor.PlayerSession); + } + + private void AllowNextSpeech(EntityUid uid) + { + if (!TryComp(uid, out var actor)) + return; + + var nextCrit = EnsureComp(uid); + + // timeout is *3 ping to compensate for roundtrip + leeway + nextCrit.Timeout = _timing.CurTime + TimeSpan.FromMilliseconds(actor.PlayerSession.Ping * 3); + } + + private void OnSleep(EntityUid uid, DamageForceSayComponent component, SleepStateChangedEvent args) + { + if (!args.FellAsleep) + return; + + TryForceSay(uid, component, true, "damage-force-say-sleep"); + AllowNextSpeech(uid); + } + + private void OnStunned(EntityUid uid, DamageForceSayComponent component, ref StunnedEvent args) + { + TryForceSay(uid, component); + } + + private void OnDamageChanged(EntityUid uid, DamageForceSayComponent component, DamageChangedEvent args) + { + if (args.DamageDelta == null || !args.DamageIncreased || args.DamageDelta.Total < component.DamageThreshold) + return; + + if (component.ValidDamageGroups != null) + { + var totalApplicableDamage = FixedPoint2.Zero; + foreach (var (group, value) in args.DamageDelta.GetDamagePerGroup(_prototype)) + { + if (!component.ValidDamageGroups.Contains(group)) + continue; + + totalApplicableDamage += value; + } + + if (totalApplicableDamage < component.DamageThreshold) + return; + } + + TryForceSay(uid, component); + } + + private void OnMobStateChanged(EntityUid uid, DamageForceSayComponent component, MobStateChangedEvent args) + { + if (args is not { OldMobState: MobState.Alive, NewMobState: MobState.Critical or MobState.Dead }) + return; + + // no suffix for the drama + // LING IN MAI- + TryForceSay(uid, component, false); + AllowNextSpeech(uid); + } +} diff --git a/Content.Server/Database/ServerDbBase.cs b/Content.Server/Database/ServerDbBase.cs index f90b938b791..aeebc64f07b 100644 --- a/Content.Server/Database/ServerDbBase.cs +++ b/Content.Server/Database/ServerDbBase.cs @@ -432,7 +432,7 @@ public abstract Task> GetServerRoleBansAsync(IPAddress? a ImmutableArray? hwId, bool includeUnbanned); - public abstract Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan); + public abstract Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan); public abstract Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverRoleUnban); public async Task EditServerRoleBan(int id, string reason, NoteSeverity severity, DateTime? expiration, Guid editedBy, DateTime editedAt) diff --git a/Content.Server/Database/ServerDbManager.cs b/Content.Server/Database/ServerDbManager.cs index f345763f53d..8d07a5ac5ea 100644 --- a/Content.Server/Database/ServerDbManager.cs +++ b/Content.Server/Database/ServerDbManager.cs @@ -14,7 +14,6 @@ using Microsoft.Extensions.Logging; using Npgsql; using Prometheus; -using Robust.Shared.Asynchronous; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; using Robust.Shared.Network; @@ -140,7 +139,7 @@ Task> GetServerRoleBansAsync( ImmutableArray? hwId, bool includeUnbanned = true); - Task AddServerRoleBanAsync(ServerRoleBanDef serverBan); + Task AddServerRoleBanAsync(ServerRoleBanDef serverBan); Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverBan); public Task EditServerRoleBan( @@ -453,7 +452,7 @@ public Task> GetServerRoleBansAsync( return RunDbCommand(() => _db.GetServerRoleBansAsync(address, userId, hwId, includeUnbanned)); } - public Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan) + public Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan) { DbWriteOpsMetric.Inc(); return RunDbCommand(() => _db.AddServerRoleBanAsync(serverRoleBan)); diff --git a/Content.Server/Database/ServerDbPostgres.cs b/Content.Server/Database/ServerDbPostgres.cs index 40e9010cf78..3548b1d1b37 100644 --- a/Content.Server/Database/ServerDbPostgres.cs +++ b/Content.Server/Database/ServerDbPostgres.cs @@ -1,5 +1,6 @@ using System.Collections.Immutable; using System.Data; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Threading; @@ -350,6 +351,7 @@ private static IQueryable MakeRoleBanLookupQuery( return query; } + [return: NotNullIfNotNull(nameof(ban))] private static ServerRoleBanDef? ConvertRoleBan(ServerRoleBan? ban) { if (ban == null) @@ -406,11 +408,11 @@ private static IQueryable MakeRoleBanLookupQuery( unban.UnbanTime); } - public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan) + public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan) { await using var db = await GetDbImpl(); - db.PgDbContext.RoleBan.Add(new ServerRoleBan + var ban = new ServerRoleBan { Address = serverRoleBan.Address, HWId = serverRoleBan.HWId?.ToArray(), @@ -423,9 +425,11 @@ public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverRoleBan) PlaytimeAtNote = serverRoleBan.PlaytimeAtNote, PlayerUserId = serverRoleBan.UserId?.UserId, RoleId = serverRoleBan.Role, - }); + }; + db.PgDbContext.RoleBan.Add(ban); await db.PgDbContext.SaveChangesAsync(); + return ConvertRoleBan(ban); } public override async Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverRoleUnban) diff --git a/Content.Server/Database/ServerDbSqlite.cs b/Content.Server/Database/ServerDbSqlite.cs index 35ee95f8d21..676081c54ed 100644 --- a/Content.Server/Database/ServerDbSqlite.cs +++ b/Content.Server/Database/ServerDbSqlite.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Threading; @@ -246,11 +247,11 @@ private static bool RoleBanMatches( return hwId is { Length: > 0 } hwIdVar && hwIdVar.AsSpan().SequenceEqual(ban.HWId); } - public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverBan) + public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverBan) { await using var db = await GetDbImpl(); - db.SqliteDbContext.RoleBan.Add(new ServerRoleBan + var ban = new ServerRoleBan { Address = serverBan.Address, Reason = serverBan.Reason, @@ -263,9 +264,11 @@ public override async Task AddServerRoleBanAsync(ServerRoleBanDef serverBan) PlaytimeAtNote = serverBan.PlaytimeAtNote, PlayerUserId = serverBan.UserId?.UserId, RoleId = serverBan.Role, - }); + }; + db.SqliteDbContext.RoleBan.Add(ban); await db.SqliteDbContext.SaveChangesAsync(); + return ConvertRoleBan(ban); } public override async Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverUnban) @@ -282,6 +285,7 @@ public override async Task AddServerRoleUnbanAsync(ServerRoleUnbanDef serverUnba await db.SqliteDbContext.SaveChangesAsync(); } + [return: NotNullIfNotNull(nameof(ban))] private static ServerRoleBanDef? ConvertRoleBan(ServerRoleBan? ban) { if (ban == null) diff --git a/Content.Server/DeltaV/Hologram/HologramSystem.cs b/Content.Server/DeltaV/Hologram/HologramSystem.cs new file mode 100644 index 00000000000..45b9e35bb53 --- /dev/null +++ b/Content.Server/DeltaV/Hologram/HologramSystem.cs @@ -0,0 +1,43 @@ +using Content.Shared.Actions.Events; +using Content.Shared.DeltaV.Hologram; +using Content.Shared.Examine; +using Content.Shared.IdentityManagement; +using Content.Shared.Popups; +using Robust.Shared.Player; + +namespace Content.Server.DeltaV.Hologram; + +public sealed class HologramSystem : SharedHologramSystem +{ + [Dependency] private readonly SharedPopupSystem _popup = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnDisarmAttempt); + } + + private void OnExamine(EntityUid uid, HologramComponent component, ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("hologram-on-examine")); + } + + private void OnDisarmAttempt(EntityUid uid, HologramComponent component, DisarmAttemptEvent args) + { + if (component.PreventDisarm) + { + args.Cancel(); + + var filterOther = Filter.PvsExcept(args.DisarmerUid, entityManager: EntityManager); + var messageUser = Loc.GetString("hologram-disarm-blocked", + ("target", Identity.Entity(args.TargetUid, EntityManager))); + var messageOther = Loc.GetString("hologram-disarm-blocked-other", + ("target", Identity.Entity(args.TargetUid, EntityManager)), ("performerName", args.DisarmerUid)); + + _popup.PopupEntity(messageOther, args.DisarmerUid, filterOther, true); + _popup.PopupEntity(messageUser, args.TargetUid, args.DisarmerUid); + } + + } +} diff --git a/Content.Server/Doors/Systems/AirlockSystem.cs b/Content.Server/Doors/Systems/AirlockSystem.cs index bb75fc7d476..0ea2755ab66 100644 --- a/Content.Server/Doors/Systems/AirlockSystem.cs +++ b/Content.Server/Doors/Systems/AirlockSystem.cs @@ -1,7 +1,6 @@ using Content.Server.DeviceLinking.Events; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; -using Content.Shared.Tools.Components; using Content.Server.Wires; using Content.Shared.Doors; using Content.Shared.Doors.Components; @@ -9,6 +8,7 @@ using Content.Shared.Interaction; using Robust.Server.GameObjects; using Content.Shared.Wires; +using Content.Shared.Prying.Components; using Robust.Shared.Prototypes; namespace Content.Server.Doors.Systems; @@ -31,9 +31,9 @@ public override void Initialize() SubscribeLocalEvent(OnStateChanged); SubscribeLocalEvent(OnBeforeDoorOpened); SubscribeLocalEvent(OnBeforeDoorDenied); - SubscribeLocalEvent(OnActivate, before: new [] {typeof(DoorSystem)}); - SubscribeLocalEvent(OnGetPryMod); - SubscribeLocalEvent(OnDoorPry); + SubscribeLocalEvent(OnActivate, before: new[] { typeof(DoorSystem) }); + SubscribeLocalEvent(OnGetPryMod); + SubscribeLocalEvent(OnBeforePry); } @@ -169,20 +169,18 @@ private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWor } } - private void OnGetPryMod(EntityUid uid, AirlockComponent component, DoorGetPryTimeModifierEvent args) + private void OnGetPryMod(EntityUid uid, AirlockComponent component, ref GetPryTimeModifierEvent args) { if (_power.IsPowered(uid)) args.PryTimeModifier *= component.PoweredPryModifier; } - private void OnDoorPry(EntityUid uid, AirlockComponent component, BeforeDoorPryEvent args) + private void OnBeforePry(EntityUid uid, AirlockComponent component, ref BeforePryEvent args) { - if (this.IsPowered(uid, EntityManager)) + if (this.IsPowered(uid, EntityManager) && !args.PryPowered) { - if (HasComp(args.Tool)) - return; - Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User); - args.Cancel(); + Popup.PopupClient(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User); + args.Cancelled = true; } } diff --git a/Content.Server/Doors/Systems/DoorSystem.cs b/Content.Server/Doors/Systems/DoorSystem.cs index f9918dfb0a6..5899baf2fcd 100644 --- a/Content.Server/Doors/Systems/DoorSystem.cs +++ b/Content.Server/Doors/Systems/DoorSystem.cs @@ -1,23 +1,19 @@ using Content.Server.Access; +using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; -using Content.Server.Construction; +using Content.Server.Power.EntitySystems; using Content.Shared.Database; -using Content.Shared.Doors; using Content.Shared.Doors.Components; using Content.Shared.Doors.Systems; using Content.Shared.Emag.Systems; using Content.Shared.Interaction; -using Content.Shared.Tools.Components; -using Content.Shared.Verbs; +using Content.Shared.Prying.Components; +using Content.Shared.Prying.Systems; +using Content.Shared.Tools.Systems; using Robust.Shared.Audio; -using Content.Server.Administration.Logs; -using Content.Server.Power.EntitySystems; -using Content.Shared.Tools; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; -using Content.Shared.DoAfter; -using Content.Shared.Tools.Systems; namespace Content.Server.Doors.Systems; @@ -26,21 +22,18 @@ public sealed class DoorSystem : SharedDoorSystem [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly DoorBoltSystem _bolts = default!; [Dependency] private readonly AirtightSystem _airtightSystem = default!; - [Dependency] private readonly SharedToolSystem _toolSystem = default!; + [Dependency] private readonly PryingSystem _pryingSystem = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnInteractUsing, after: new[] { typeof(ConstructionSystem) }); - // Mob prying doors - SubscribeLocalEvent>(OnDoorAltVerb); - - SubscribeLocalEvent(OnPryFinished); + SubscribeLocalEvent(OnBeforeDoorPry); SubscribeLocalEvent(OnWeldAttempt); SubscribeLocalEvent(OnWeldChanged); SubscribeLocalEvent(OnEmagged); + SubscribeLocalEvent(OnAfterPry); } protected override void OnActivate(EntityUid uid, DoorComponent door, ActivateInWorldEvent args) @@ -49,7 +42,9 @@ protected override void OnActivate(EntityUid uid, DoorComponent door, ActivateIn if (args.Handled || !door.ClickOpen) return; - TryToggleDoor(uid, door, args.User); + if (!TryToggleDoor(uid, door, args.User)) + _pryingSystem.TryPry(uid, args.User, out _); + args.Handled = true; } @@ -108,24 +103,7 @@ protected override void PlaySound(EntityUid uid, SoundSpecifier soundSpecifier, Audio.PlayPvs(soundSpecifier, uid, audioParams); } -#region DoAfters - /// - /// Weld or pry open a door. - /// - private void OnInteractUsing(EntityUid uid, DoorComponent door, InteractUsingEvent args) - { - if (args.Handled) - return; - - if (!TryComp(args.Used, out ToolComponent? tool)) - return; - - if (tool.Qualities.Contains(door.PryingQuality)) - { - args.Handled = TryPryDoor(uid, args.Used, args.User, door, out _); - } - } - + #region DoAfters private void OnWeldAttempt(EntityUid uid, DoorComponent component, WeldableAttemptEvent args) { if (component.CurrentlyCrushing.Count > 0) @@ -147,69 +125,12 @@ private void OnWeldChanged(EntityUid uid, DoorComponent component, ref WeldableC SetState(uid, DoorState.Closed, component); } - private void OnDoorAltVerb(EntityUid uid, DoorComponent component, GetVerbsEvent args) + private void OnBeforeDoorPry(EntityUid id, DoorComponent door, ref BeforePryEvent args) { - if (!args.CanInteract || !args.CanAccess) - return; - - if (!TryComp(args.User, out var tool) || !tool.Qualities.Contains(component.PryingQuality)) - return; - - args.Verbs.Add(new AlternativeVerb() - { - Text = Loc.GetString("door-pry"), - Impact = LogImpact.Low, - Act = () => TryPryDoor(uid, args.User, args.User, component, out _, force: true), - }); + if (door.State == DoorState.Welded || !door.CanPry) + args.Cancelled = true; } - - - /// - /// Pry open a door. This does not check if the user is holding the required tool. - /// - public bool TryPryDoor(EntityUid target, EntityUid tool, EntityUid user, DoorComponent door, out DoAfterId? id, bool force = false) - { - id = null; - - if (door.State == DoorState.Welded) - return false; - - if (!force) - { - var canEv = new BeforeDoorPryEvent(user, tool); - RaiseLocalEvent(target, canEv, false); - - if (!door.CanPry || canEv.Cancelled) - // mark handled, as airlock component will cancel after generating a pop-up & you don't want to pry a tile - // under a windoor. - return true; - } - - var modEv = new DoorGetPryTimeModifierEvent(user); - RaiseLocalEvent(target, modEv, false); - - _adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user)} is using {ToPrettyString(tool)} to pry {ToPrettyString(target)} while it is {door.State}"); // TODO move to generic tool use logging in a way that includes door state - _toolSystem.UseTool(tool, user, target, TimeSpan.FromSeconds(modEv.PryTimeModifier * door.PryTime), new[] {door.PryingQuality}, new DoorPryDoAfterEvent(), out id); - return true; // we might not actually succeeded, but a do-after has started - } - - private void OnPryFinished(EntityUid uid, DoorComponent door, DoAfterEvent args) - { - if (args.Cancelled) - return; - - if (door.State == DoorState.Closed) - { - _adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} open"); // TODO move to generic tool use logging in a way that includes door state - StartOpening(uid, door); - } - else if (door.State == DoorState.Open) - { - _adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} closed"); // TODO move to generic tool use logging in a way that includes door state - StartClosing(uid, door); - } - } -#endregion + #endregion /// @@ -233,7 +154,7 @@ protected override void HandleCollide(EntityUid uid, DoorComponent door, ref Sta } private void OnEmagged(EntityUid uid, DoorComponent door, ref GotEmaggedEvent args) { - if(TryComp(uid, out var airlockComponent)) + if (TryComp(uid, out var airlockComponent)) { if (_bolts.IsBolted(uid) || !this.IsPowered(uid, EntityManager)) return; @@ -259,10 +180,27 @@ public override void StartOpening(EntityUid uid, DoorComponent? door = null, Ent if (door.OpenSound != null) PlaySound(uid, door.OpenSound, AudioParams.Default.WithVolume(-5), user, predicted); - if(lastState == DoorState.Emagging && TryComp(uid, out var doorBoltComponent)) + if (lastState == DoorState.Emagging && TryComp(uid, out var doorBoltComponent)) _bolts.SetBoltsWithAudio(uid, doorBoltComponent, !doorBoltComponent.BoltsDown); } + /// + /// Open or close a door after it has been successfuly pried. + /// + private void OnAfterPry(EntityUid uid, DoorComponent door, ref PriedEvent args) + { + if (door.State == DoorState.Closed) + { + _adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} open"); + StartOpening(uid, door, args.User); + } + else if (door.State == DoorState.Open) + { + _adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} closed"); + StartClosing(uid, door, args.User); + } + } + protected override void CheckDoorBump(DoorComponent component, PhysicsComponent body) { var uid = body.Owner; diff --git a/Content.Server/Doors/Systems/FirelockSystem.cs b/Content.Server/Doors/Systems/FirelockSystem.cs index 7147aa4f24c..e2f25c63ab4 100644 --- a/Content.Server/Doors/Systems/FirelockSystem.cs +++ b/Content.Server/Doors/Systems/FirelockSystem.cs @@ -18,6 +18,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Map.Components; using Robust.Shared.Player; +using Content.Shared.Prying.Components; namespace Content.Server.Doors.Systems { @@ -38,7 +39,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnBeforeDoorOpened); - SubscribeLocalEvent(OnDoorGetPryTimeModifier); + SubscribeLocalEvent(OnDoorGetPryTimeModifier); SubscribeLocalEvent(OnUpdateState); SubscribeLocalEvent(OnBeforeDoorAutoclose); @@ -144,7 +145,7 @@ private void OnBeforeDoorOpened(EntityUid uid, FirelockComponent component, Befo args.Cancel(); } - private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, DoorGetPryTimeModifierEvent args) + private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, ref GetPryTimeModifierEvent args) { var state = CheckPressureAndFire(uid, component); @@ -261,7 +262,7 @@ public bool IsHoldingPressureOrFire(EntityUid uid, FirelockComponent firelock) List directions = new(4); for (var i = 0; i < Atmospherics.Directions; i++) { - var dir = (AtmosDirection) (1 << i); + var dir = (AtmosDirection)(1 << i); if (airtight.AirBlockedDirection.HasFlag(dir)) { directions.Add(dir); diff --git a/Content.Server/Dragon/DragonRiftSystem.cs b/Content.Server/Dragon/DragonRiftSystem.cs new file mode 100644 index 00000000000..52137f2ee6e --- /dev/null +++ b/Content.Server/Dragon/DragonRiftSystem.cs @@ -0,0 +1,115 @@ +using Content.Server.Chat.Systems; +using Content.Server.NPC; +using Content.Server.NPC.Systems; +using Content.Server.Pinpointer; +using Content.Shared.Damage; +using Content.Shared.Dragon; +using Content.Shared.Examine; +using Content.Shared.Sprite; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Player; +using Robust.Shared.Serialization.Manager; +using System.Numerics; + +namespace Content.Server.Dragon; + +/// +/// Handles events for rift entities and rift updating. +/// +public sealed class DragonRiftSystem : EntitySystem +{ + [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly DragonSystem _dragon = default!; + [Dependency] private readonly ISerializationManager _serManager = default!; + [Dependency] private readonly NavMapSystem _navMap = default!; + [Dependency] private readonly NPCSystem _npc = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnAnchorChange); + SubscribeLocalEvent(OnShutdown); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp, out var xform)) + { + if (comp.State != DragonRiftState.Finished && comp.Accumulator >= comp.MaxAccumulator) + { + // TODO: When we get autocall you can buff if the rift finishes / 3 rifts are up + // for now they just keep 3 rifts up. + + if (comp.Dragon != null) + _dragon.RiftCharged(comp.Dragon.Value); + + comp.Accumulator = comp.MaxAccumulator; + RemComp(uid); + comp.State = DragonRiftState.Finished; + Dirty(uid, comp); + } + else if (comp.State != DragonRiftState.Finished) + { + comp.Accumulator += frameTime; + } + + comp.SpawnAccumulator += frameTime; + + if (comp.State < DragonRiftState.AlmostFinished && comp.Accumulator > comp.MaxAccumulator / 2f) + { + comp.State = DragonRiftState.AlmostFinished; + Dirty(comp); + + var location = xform.LocalPosition; + _chat.DispatchGlobalAnnouncement(Loc.GetString("carp-rift-warning", ("location", location)), playSound: false, colorOverride: Color.Red); + _audio.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true); + _navMap.SetBeaconEnabled(uid, true); + } + + if (comp.SpawnAccumulator > comp.SpawnCooldown) + { + comp.SpawnAccumulator -= comp.SpawnCooldown; + var ent = Spawn(comp.SpawnPrototype, xform.Coordinates); + + // Update their look to match the leader. + if (TryComp(comp.Dragon, out var randomSprite)) + { + var spawnedSprite = EnsureComp(ent); + _serManager.CopyTo(randomSprite, ref spawnedSprite, notNullableOverride: true); + Dirty(ent, spawnedSprite); + } + + if (comp.Dragon != null) + _npc.SetBlackboard(ent, NPCBlackboard.FollowTarget, new EntityCoordinates(comp.Dragon.Value, Vector2.Zero)); + } + } + } + + private void OnExamined(EntityUid uid, DragonRiftComponent component, ExaminedEvent args) + { + args.PushMarkup(Loc.GetString("carp-rift-examine", ("percentage", MathF.Round(component.Accumulator / component.MaxAccumulator * 100)))); + } + + private void OnAnchorChange(EntityUid uid, DragonRiftComponent component, ref AnchorStateChangedEvent args) + { + if (!args.Anchored && component.State == DragonRiftState.Charging) + { + QueueDel(uid); + } + } + + private void OnShutdown(EntityUid uid, DragonRiftComponent comp, ComponentShutdown args) + { + if (!TryComp(comp.Dragon, out var dragon) || dragon.Weakened) + return; + + _dragon.RiftDestroyed(comp.Dragon.Value, dragon); + } +} diff --git a/Content.Server/Dragon/DragonSystem.Rule.cs b/Content.Server/Dragon/DragonSystem.Rule.cs deleted file mode 100644 index 4a4f44e143b..00000000000 --- a/Content.Server/Dragon/DragonSystem.Rule.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Linq; -using Content.Server.GameTicking; -using Content.Server.GameTicking.Rules.Components; -using Content.Server.Station.Components; -using Content.Shared.Dragon; -using Robust.Server.GameObjects; -using Robust.Shared.Map.Components; -using Robust.Shared.Random; - -namespace Content.Server.Dragon; - -public sealed partial class DragonSystem -{ - private int RiftsMet(DragonComponent component) - { - var finished = 0; - - foreach (var rift in component.Rifts) - { - if (!TryComp(rift, out var drift) || - drift.State != DragonRiftState.Finished) - continue; - - finished++; - } - - return finished; - } - - private void OnRiftRoundEnd(RoundEndTextAppendEvent args) - { - if (EntityQuery().Count() == 0) - return; - - args.AddLine(Loc.GetString("dragon-round-end-summary")); - - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var dragon)) - { - var met = RiftsMet(dragon); - - if (TryComp(uid, out var actor)) - { - args.AddLine(Loc.GetString("dragon-round-end-dragon-player", ("name", uid), ("count", met), ("player", actor.PlayerSession))); - } - else - { - args.AddLine(Loc.GetString("dragon-round-end-dragon", ("name", uid), ("count", met))); - } - } - } -} diff --git a/Content.Server/Dragon/DragonSystem.cs b/Content.Server/Dragon/DragonSystem.cs index 40039be50e2..ed17ba8bdc2 100644 --- a/Content.Server/Dragon/DragonSystem.cs +++ b/Content.Server/Dragon/DragonSystem.cs @@ -1,35 +1,33 @@ -using System.Numerics; -using Content.Server.Chat.Systems; -using Content.Server.GameTicking; -using Content.Server.NPC; -using Content.Server.NPC.Systems; +using Content.Server.GenericAntag; +using Content.Server.Objectives.Components; +using Content.Server.Objectives.Systems; using Content.Server.Popups; +using Content.Server.Roles; using Content.Shared.Actions; -using Content.Shared.Damage; using Content.Shared.Dragon; -using Content.Shared.Examine; using Content.Shared.Maps; +using Content.Shared.Mind; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; using Content.Shared.Movement.Systems; -using Content.Shared.Sprite; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Player; -using Robust.Shared.Serialization.Manager; namespace Content.Server.Dragon; public sealed partial class DragonSystem : EntitySystem { + [Dependency] private readonly CarpRiftsConditionSystem _carpRifts = default!; [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ISerializationManager _serManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDef = default!; - [Dependency] private readonly ChatSystem _chat = default!; - [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly NPCSystem _npc = 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!; + + private EntityQuery _objQuery; /// /// Minimum distance between 2 rifts allowed. @@ -47,26 +45,22 @@ public override void Initialize() { base.Initialize(); + _objQuery = GetEntityQuery(); + SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnDragonRift); + SubscribeLocalEvent(OnSpawnRift); SubscribeLocalEvent(OnDragonMove); - SubscribeLocalEvent(OnMobStateChanged); - - SubscribeLocalEvent(OnRiftShutdown); - SubscribeLocalEvent(OnRiftGetState); - SubscribeLocalEvent(OnAnchorChange); - SubscribeLocalEvent(OnRiftExamined); - - SubscribeLocalEvent(OnRiftRoundEnd); + SubscribeLocalEvent(OnCreated); } public override void Update(float frameTime) { base.Update(frameTime); - foreach (var comp in EntityQuery()) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) { if (comp.WeakenedAccumulator > 0f) { @@ -76,15 +70,13 @@ public override void Update(float frameTime) if (comp.WeakenedAccumulator < 0f) { comp.WeakenedAccumulator = 0f; - _movement.RefreshMovementSpeedModifiers(comp.Owner); + _movement.RefreshMovementSpeedModifiers(uid); } } // At max rifts if (comp.Rifts.Count >= RiftsAllowed) - { continue; - } // If there's an active rift don't accumulate. if (comp.Rifts.Count > 0) @@ -103,125 +95,40 @@ public override void Update(float frameTime) // Delete it, naughty dragon! if (comp.RiftAccumulator >= comp.RiftMaxAccumulator) { - Roar(comp); - QueueDel(comp.Owner); - } - } - - foreach (var comp in EntityQuery()) - { - if (comp.State != DragonRiftState.Finished && comp.Accumulator >= comp.MaxAccumulator) - { - // TODO: When we get autocall you can buff if the rift finishes / 3 rifts are up - // for now they just keep 3 rifts up. - - comp.Accumulator = comp.MaxAccumulator; - RemComp(comp.Owner); - comp.State = DragonRiftState.Finished; - Dirty(comp); - } - else if (comp.State != DragonRiftState.Finished) - { - comp.Accumulator += frameTime; - } - - comp.SpawnAccumulator += frameTime; - - if (comp.State < DragonRiftState.AlmostFinished && comp.Accumulator > comp.MaxAccumulator / 2f) - { - comp.State = DragonRiftState.AlmostFinished; - Dirty(comp); - var location = Transform(comp.Owner).LocalPosition; - - _chat.DispatchGlobalAnnouncement(Loc.GetString("carp-rift-warning", ("location", location)), playSound: false, colorOverride: Color.Red); - _audioSystem.PlayGlobal("/Audio/Misc/notice1.ogg", Filter.Broadcast(), true); - } - - if (comp.SpawnAccumulator > comp.SpawnCooldown) - { - comp.SpawnAccumulator -= comp.SpawnCooldown; - var ent = Spawn(comp.SpawnPrototype, Transform(comp.Owner).Coordinates); - - // Update their look to match the leader. - if (TryComp(comp.Dragon, out var randomSprite)) - { - var spawnedSprite = EnsureComp(ent); - _serManager.CopyTo(randomSprite, ref spawnedSprite, notNullableOverride: true); - Dirty(ent, spawnedSprite); - } - - if (comp.Dragon != null) - _npc.SetBlackboard(ent, NPCBlackboard.FollowTarget, new EntityCoordinates(comp.Dragon.Value, Vector2.Zero)); + Roar(uid, comp); + QueueDel(uid); } } } - #region Rift - - private void OnRiftExamined(EntityUid uid, DragonRiftComponent component, ExaminedEvent args) + private void OnInit(EntityUid uid, DragonComponent component, MapInitEvent args) { - args.PushMarkup(Loc.GetString("carp-rift-examine", ("percentage", MathF.Round(component.Accumulator / component.MaxAccumulator * 100)))); + Roar(uid, component); + _actions.AddAction(uid, ref component.SpawnRiftActionEntity, component.SpawnRiftAction); } - private void OnAnchorChange(EntityUid uid, DragonRiftComponent component, ref AnchorStateChangedEvent args) - { - if (!args.Anchored && component.State == DragonRiftState.Charging) - { - QueueDel(uid); - } - } - - private void OnRiftShutdown(EntityUid uid, DragonRiftComponent component, ComponentShutdown args) - { - if (TryComp(component.Dragon, out var dragon) && !dragon.Weakened) - { - foreach (var rift in dragon.Rifts) - { - QueueDel(rift); - } - - dragon.Rifts.Clear(); - - // We can't predict the rift being destroyed anyway so no point adding weakened to shared. - dragon.WeakenedAccumulator = dragon.WeakenedDuration; - _movement.RefreshMovementSpeedModifiers(component.Dragon.Value); - _popupSystem.PopupEntity(Loc.GetString("carp-rift-destroyed"), component.Dragon.Value, component.Dragon.Value); - } - } - - private void OnRiftGetState(EntityUid uid, DragonRiftComponent component, ref ComponentGetState args) + private void OnShutdown(EntityUid uid, DragonComponent component, ComponentShutdown args) { - args.State = new DragonRiftComponentState() - { - State = component.State - }; + DeleteRifts(uid, false, component); } - private void OnDragonMove(EntityUid uid, DragonComponent component, RefreshMovementSpeedModifiersEvent args) + private void OnSpawnRift(EntityUid uid, DragonComponent component, DragonSpawnRiftActionEvent args) { if (component.Weakened) { - args.ModifySpeed(0.5f, 0.5f); - } - } - - private void OnDragonRift(EntityUid uid, DragonComponent component, DragonSpawnRiftActionEvent args) - { - if (component.Weakened) - { - _popupSystem.PopupEntity(Loc.GetString("carp-rift-weakened"), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-weakened"), uid, uid); return; } if (component.Rifts.Count >= RiftsAllowed) { - _popupSystem.PopupEntity(Loc.GetString("carp-rift-max"), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-max"), uid, uid); return; } if (component.Rifts.Count > 0 && TryComp(component.Rifts[^1], out var rift) && rift.State != DragonRiftState.Finished) { - _popupSystem.PopupEntity(Loc.GetString("carp-rift-duplicate"), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-duplicate"), uid, uid); return; } @@ -230,72 +137,144 @@ private void OnDragonRift(EntityUid uid, DragonComponent component, DragonSpawnR // Have to be on a grid fam if (!_mapManager.TryGetGrid(xform.GridUid, out var grid)) { - _popupSystem.PopupEntity(Loc.GetString("carp-rift-anchor"), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-anchor"), uid, uid); return; } + // cant stack rifts near eachother foreach (var (_, riftXform) in EntityQuery(true)) { if (riftXform.Coordinates.InRange(EntityManager, xform.Coordinates, RiftRange)) { - _popupSystem.PopupEntity(Loc.GetString("carp-rift-proximity", ("proximity", RiftRange)), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-proximity", ("proximity", RiftRange)), uid, uid); return; } } + // cant put a rift on solars foreach (var tile in grid.GetTilesIntersecting(new Circle(xform.WorldPosition, RiftTileRadius), false)) { if (!tile.IsSpace(_tileDef)) continue; - _popupSystem.PopupEntity(Loc.GetString("carp-rift-space-proximity", ("proximity", RiftTileRadius)), uid, uid); + _popup.PopupEntity(Loc.GetString("carp-rift-space-proximity", ("proximity", RiftTileRadius)), uid, uid); return; } var carpUid = Spawn(component.RiftPrototype, xform.MapPosition); component.Rifts.Add(carpUid); Comp(carpUid).Dragon = uid; - _audioSystem.PlayPvs("/Audio/Weapons/Guns/Gunshots/rocket_launcher.ogg", carpUid); } - #endregion - - private void OnShutdown(EntityUid uid, DragonComponent component, ComponentShutdown args) + // TODO: just make this a move speed modifier component??? + private void OnDragonMove(EntityUid uid, DragonComponent component, RefreshMovementSpeedModifiersEvent args) { - foreach (var rift in component.Rifts) + if (component.Weakened) { - QueueDel(rift); + args.ModifySpeed(0.5f, 0.5f); } } private void OnMobStateChanged(EntityUid uid, DragonComponent component, MobStateChangedEvent args) { - //Empties the stomach upon death - //TODO: Do this when the dragon gets butchered instead - if (args.NewMobState == MobState.Dead) + // Deletes all rifts after dying + if (args.NewMobState != MobState.Dead) + return; + + if (component.SoundDeath != null) + _audio.PlayPvs(component.SoundDeath, uid); + + // objective is explicitly not reset so that it will show how many you got before dying in round end text + DeleteRifts(uid, false, component); + } + + private void OnCreated(EntityUid uid, DragonComponent comp, ref GenericAntagCreatedEvent args) + { + var mindId = args.MindId; + var mind = args.Mind; + + _role.MindAddRole(mindId, new DragonRoleComponent(), mind); + _role.MindAddRole(mindId, new RoleBriefingComponent() + { + Briefing = Loc.GetString("dragon-role-briefing") + }, mind); + } + + private void Roar(EntityUid uid, DragonComponent comp) + { + if (comp.SoundRoar != null) + _audio.Play(comp.SoundRoar, Filter.Pvs(uid, 4f, EntityManager), uid, true); + } + + /// + /// Delete all rifts this dragon made. + /// + /// Entity id of the dragon + /// If true, the role's rift count will be reset too + /// The dragon component + public void DeleteRifts(EntityUid uid, bool resetRole, DragonComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + foreach (var rift in comp.Rifts) { - if (component.SoundDeath != null) - _audioSystem.PlayPvs(component.SoundDeath, uid, component.SoundDeath.Params); + QueueDel(rift); + } + + comp.Rifts.Clear(); - foreach (var rift in component.Rifts) + // stop here if not trying to reset the objective's rift count + if (!resetRole || !TryComp(uid, out var mindContainer) || !mindContainer.HasMind) + return; + + var mind = Comp(mindContainer.Mind.Value); + foreach (var objId in mind.AllObjectives) + { + if (_objQuery.TryGetComponent(objId, out var obj)) { - QueueDel(rift); + _carpRifts.ResetRifts(objId, obj); + break; } - - component.Rifts.Clear(); } } - private void Roar(DragonComponent component) + /// + /// Increment the dragon role's charged rift count. + /// + public void RiftCharged(EntityUid uid, DragonComponent? comp = null) { - if (component.SoundRoar != null) - _audioSystem.Play(component.SoundRoar, Filter.Pvs(component.Owner, 4f, EntityManager), component.Owner, true, component.SoundRoar.Params); + if (!Resolve(uid, ref comp)) + return; + + if (!TryComp(uid, out var mindContainer) || !mindContainer.HasMind) + return; + + var mind = Comp(mindContainer.Mind.Value); + foreach (var objId in mind.AllObjectives) + { + if (_objQuery.TryGetComponent(objId, out var obj)) + { + _carpRifts.RiftCharged(objId, obj); + break; + } + } } - private void OnInit(EntityUid uid, DragonComponent component, MapInitEvent args) + /// + /// Do everything that needs to happen when a rift gets destroyed by the crew. + /// + public void RiftDestroyed(EntityUid uid, DragonComponent? comp = null) { - Roar(component); - _actionsSystem.AddAction(uid, ref component.SpawnRiftActionEntity, component.SpawnRiftAction); + if (!Resolve(uid, ref comp)) + return; + + // do reset the rift count since crew destroyed the rift, not deleted by the dragon dying. + DeleteRifts(uid, true, comp); + + // We can't predict the rift being destroyed anyway so no point adding weakened to shared. + comp.WeakenedAccumulator = comp.WeakenedDuration; + _movement.RefreshMovementSpeedModifiers(uid); + _popup.PopupEntity(Loc.GetString("carp-rift-destroyed"), uid, uid); } } - diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index c6ce90692ff..844d526c58e 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Damage.Prototypes; using Content.Shared.Database; using Content.Shared.Electrocution; +using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Inventory; using Content.Shared.Jittering; @@ -210,7 +211,7 @@ private void OnElectrifiedInteractUsing(EntityUid uid, ElectrifiedComponent elec return; var siemens = TryComp(args.Used, out var insulation) - ? insulation.SiemensCoefficient + ? insulation.Coefficient : 1; TryDoElectrifiedAct(uid, args.User, siemens, electrified); @@ -432,17 +433,18 @@ private bool DoCommonElectrocution(EntityUid uid, EntityUid? sourceUid, var filter = Filter.PvsExcept(uid, entityManager: EntityManager); + var identifiedUid = Identity.Entity(uid, ent: EntityManager); // TODO: Allow being able to pass EntityUid to Loc... if (sourceUid != null) { _popup.PopupEntity(Loc.GetString("electrocuted-component-mob-shocked-by-source-popup-others", - ("mob", uid), ("source", (sourceUid.Value))), uid, filter, true); + ("mob", identifiedUid), ("source", (sourceUid.Value))), uid, filter, true); PlayElectrocutionSound(uid, sourceUid.Value); } else { _popup.PopupEntity(Loc.GetString("electrocuted-component-mob-shocked-popup-others", - ("mob", uid)), uid, filter, true); + ("mob", identifiedUid)), uid, filter, true); } return true; diff --git a/Content.Server/Explosion/Components/OnUseTimerTriggerComponent.cs b/Content.Server/Explosion/Components/OnUseTimerTriggerComponent.cs index 008bbbe284b..f2e94239a03 100644 --- a/Content.Server/Explosion/Components/OnUseTimerTriggerComponent.cs +++ b/Content.Server/Explosion/Components/OnUseTimerTriggerComponent.cs @@ -29,6 +29,12 @@ public sealed partial class OnUseTimerTriggerComponent : Component [DataField("beepInterval")] public float BeepInterval = 1; + /// + /// Whether the timer should instead be activated through a verb in the right-click menu + /// + [DataField("useVerbInstead")] + public bool UseVerbInstead = false; + /// /// Should timer be started when it was stuck to another entity. /// Used for C4 charges and similar behaviour. diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index 1938831f7e1..cce7050e3f4 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -9,7 +9,7 @@ using Content.Shared.Mind.Components; using Content.Shared.Physics; using Content.Shared.Projectiles; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Tag; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -18,6 +18,7 @@ using Robust.Shared.Physics.Dynamics; using Robust.Shared.Random; using Robust.Shared.Timing; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.Explosion.EntitySystems; diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 06c95383fcb..aa007c61c05 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Explosion.Components; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NPC.Pathfinding; +using Content.Shared.Armor; using Content.Shared.Camera; using Content.Shared.CCVar; using Content.Shared.Damage; diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.OnUse.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.OnUse.cs index 1a3323b1ce2..fb1f72eb445 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.OnUse.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.OnUse.cs @@ -48,6 +48,32 @@ private void OnGetAltVerbs(EntityUid uid, OnUseTimerTriggerComponent component, if (!args.CanInteract || !args.CanAccess) return; + if (component.UseVerbInstead) + { + args.Verbs.Add(new AlternativeVerb() + { + Text = Loc.GetString("verb-start-detonation"), + Act = () => HandleTimerTrigger( + uid, + args.User, + component.Delay, + component.BeepInterval, + component.InitialBeepDelay, + component.BeepSound + ), + Priority = 2 + }); + } + + if (component.AllowToggleStartOnStick) + { + args.Verbs.Add(new AlternativeVerb() + { + Text = Loc.GetString("verb-toggle-start-on-stick"), + Act = () => ToggleStartOnStick(uid, args.User, component) + }); + } + if (component.DelayOptions == null || component.DelayOptions.Count == 1) return; @@ -86,15 +112,6 @@ private void OnGetAltVerbs(EntityUid uid, OnUseTimerTriggerComponent component, }, }); } - - if (component.AllowToggleStartOnStick) - { - args.Verbs.Add(new AlternativeVerb() - { - Text = Loc.GetString("verb-toggle-start-on-stick"), - Act = () => ToggleStartOnStick(uid, args.User, component) - }); - } } private void CycleDelay(OnUseTimerTriggerComponent component, EntityUid user) @@ -140,7 +157,7 @@ private void ToggleStartOnStick(EntityUid grenade, EntityUid user, OnUseTimerTri private void OnTimerUse(EntityUid uid, OnUseTimerTriggerComponent component, UseInHandEvent args) { - if (args.Handled || HasComp(uid)) + if (args.Handled || HasComp(uid) || component.UseVerbInstead) return; HandleTimerTrigger( diff --git a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs index ee0d16a7a2d..a192b39e560 100644 --- a/Content.Server/Fluids/EntitySystems/SmokeSystem.cs +++ b/Content.Server/Fluids/EntitySystems/SmokeSystem.cs @@ -14,12 +14,13 @@ using Content.Shared.Database; using Content.Shared.FixedPoint; using Content.Shared.Smoking; -using Content.Shared.Spawners; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Robust.Server.GameObjects; using Robust.Shared.Map; using Robust.Shared.Prototypes; +using Robust.Shared.Spawners; using Robust.Shared.Timing; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.Fluids.EntitySystems; diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 82e2872914e..c04b8d67116 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -94,7 +94,7 @@ public bool StartGameRule(EntityUid ruleEntity, GameRuleComponent? ruleData = nu ruleData ??= EnsureComp(ruleEntity); // can't start an already active rule - if (ruleData.Active || ruleData.Ended) + if (HasComp(ruleEntity) || HasComp(ruleEntity)) return false; if (MetaData(ruleEntity).EntityPrototype?.ID is not { } id) // you really fucked up @@ -103,8 +103,9 @@ public bool StartGameRule(EntityUid ruleEntity, GameRuleComponent? ruleData = nu _allPreviousGameRules.Add((RoundDuration(), id)); _sawmill.Info($"Started game rule {ToPrettyString(ruleEntity)}"); - ruleData.Active = true; + EnsureComp(ruleEntity); ruleData.ActivatedAt = _gameTiming.CurTime; + var ev = new GameRuleStartedEvent(ruleEntity, id); RaiseLocalEvent(ruleEntity, ref ev, true); return true; @@ -120,14 +121,15 @@ public bool EndGameRule(EntityUid ruleEntity, GameRuleComponent? ruleData = null return false; // don't end it multiple times - if (ruleData.Ended) + if (HasComp(ruleEntity)) return false; if (MetaData(ruleEntity).EntityPrototype?.ID is not { } id) // you really fucked up return false; - ruleData.Active = false; - ruleData.Ended = true; + RemComp(ruleEntity); + EnsureComp(ruleEntity); + _sawmill.Info($"Ended game rule {ToPrettyString(ruleEntity)}"); var ev = new GameRuleEndedEvent(ruleEntity, id); @@ -137,7 +139,7 @@ public bool EndGameRule(EntityUid ruleEntity, GameRuleComponent? ruleData = null public bool IsGameRuleAdded(EntityUid ruleEntity, GameRuleComponent? component = null) { - return Resolve(ruleEntity, ref component) && !component.Ended; + return Resolve(ruleEntity, ref component) && !HasComp(ruleEntity); } public bool IsGameRuleAdded(string rule) @@ -153,7 +155,7 @@ public bool IsGameRuleAdded(string rule) public bool IsGameRuleActive(EntityUid ruleEntity, GameRuleComponent? component = null) { - return Resolve(ruleEntity, ref component) && component.Active; + return Resolve(ruleEntity, ref component) && HasComp(ruleEntity); } public bool IsGameRuleActive(string rule) @@ -193,11 +195,10 @@ public IEnumerable GetAddedGameRules() /// public IEnumerable GetActiveGameRules() { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var ruleData)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out _)) { - if (ruleData.Active) - yield return uid; + yield return uid; } } diff --git a/Content.Server/GameTicking/GameTicker.Replays.cs b/Content.Server/GameTicking/GameTicker.Replays.cs index 42e2de02287..78a8182ce6f 100644 --- a/Content.Server/GameTicking/GameTicker.Replays.cs +++ b/Content.Server/GameTicking/GameTicker.Replays.cs @@ -23,36 +23,45 @@ private void InitializeReplays() /// private void ReplayStartRound() { - if (!_cfg.GetCVar(CCVars.ReplayAutoRecord)) - return; - - if (_replays.IsRecording) + try { - _sawmillReplays.Warning("Already an active replay recording before the start of the round, not starting automatic recording."); - return; - } + if (!_cfg.GetCVar(CCVars.ReplayAutoRecord)) + return; - _sawmillReplays.Debug($"Starting replay recording for round {RoundId}"); + if (_replays.IsRecording) + { + _sawmillReplays.Warning("Already an active replay recording before the start of the round, not starting automatic recording."); + return; + } - var finalPath = GetAutoReplayPath(); - var recordPath = finalPath; - var tempDir = _cfg.GetCVar(CCVars.ReplayAutoRecordTempDir); - ResPath? moveToPath = null; + _sawmillReplays.Debug($"Starting replay recording for round {RoundId}"); - if (!string.IsNullOrEmpty(tempDir)) - { - var baseReplayPath = new ResPath(_cfg.GetCVar(CVars.ReplayDirectory)).ToRootedPath(); - moveToPath = baseReplayPath / finalPath; - recordPath = new ResPath(tempDir) / finalPath; + var finalPath = GetAutoReplayPath(); + var recordPath = finalPath; + var tempDir = _cfg.GetCVar(CCVars.ReplayAutoRecordTempDir); + ResPath? moveToPath = null; - _sawmillReplays.Debug($"Replay will record in temporary position: {recordPath}"); - } + if (!string.IsNullOrEmpty(tempDir)) + { + var baseReplayPath = new ResPath(_cfg.GetCVar(CVars.ReplayDirectory)).ToRootedPath(); + moveToPath = baseReplayPath / finalPath; - var recordState = new ReplayRecordState(moveToPath); + var fileName = finalPath.Filename; + recordPath = new ResPath(tempDir) / fileName; - if (!_replays.TryStartRecording(_resourceManager.UserData, recordPath.ToString(), state: recordState)) + _sawmillReplays.Debug($"Replay will record in temporary position: {recordPath}"); + } + + var recordState = new ReplayRecordState(moveToPath); + + if (!_replays.TryStartRecording(_resourceManager.UserData, recordPath.ToString(), state: recordState)) + { + _sawmillReplays.Error("Can't start automatic replay recording!"); + } + } + catch (Exception e) { - _sawmillReplays.Error("Can't start automatic replay recording!"); + Log.Error($"Error while starting an automatic replay recording:\n{e}"); } } @@ -61,9 +70,16 @@ private void ReplayStartRound() /// private void ReplayEndRound() { - if (_replays.ActiveRecordingState is ReplayRecordState) + try + { + if (_replays.ActiveRecordingState is ReplayRecordState) + { + _replays.StopRecording(); + } + } + catch (Exception e) { - _replays.StopRecording(); + Log.Error($"Error while stopping replay recording:\n{e}"); } } diff --git a/Content.Server/GameTicking/Rules/Components/ActiveGameRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/ActiveGameRuleComponent.cs new file mode 100644 index 00000000000..956768bdd99 --- /dev/null +++ b/Content.Server/GameTicking/Rules/Components/ActiveGameRuleComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.GameTicking.Rules.Components; + +/// +/// Added to game rules before and removed before . +/// Mutually exclusive with . +/// +[RegisterComponent] +public sealed partial class ActiveGameRuleComponent : Component +{ +} diff --git a/Content.Server/GameTicking/Rules/Components/EndedGameRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/EndedGameRuleComponent.cs new file mode 100644 index 00000000000..4484abd4d0b --- /dev/null +++ b/Content.Server/GameTicking/Rules/Components/EndedGameRuleComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.GameTicking.Rules.Components; + +/// +/// Added to game rules before . +/// Mutually exclusive with . +/// +[RegisterComponent] +public sealed partial class EndedGameRuleComponent : Component +{ +} diff --git a/Content.Server/GameTicking/Rules/Components/GameRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/GameRuleComponent.cs index cc384b47d3c..80a5ab340aa 100644 --- a/Content.Server/GameTicking/Rules/Components/GameRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/GameRuleComponent.cs @@ -9,25 +9,17 @@ namespace Content.Server.GameTicking.Rules.Components; [RegisterComponent] public sealed partial class GameRuleComponent : Component { - /// - /// Whether or not the rule is active. - /// Is enabled after and disabled after - /// - [DataField("active")] - public bool Active; - /// /// Game time when game rule was activated /// - [DataField("activatedAt", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan ActivatedAt; /// - /// Whether or not the gamerule finished. - /// Used for tracking whether a non-active gamerule has been started before. + /// The minimum amount of players needed for this game rule. /// - [DataField("ended")] - public bool Ended; + [DataField] + public int MinPlayers; } /// diff --git a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs index 8ddfd9c14bb..55c14f88d4e 100644 --- a/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs @@ -4,7 +4,6 @@ using Content.Shared.Dataset; using Content.Shared.Roles; using Robust.Shared.Map; -using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; @@ -16,79 +15,80 @@ namespace Content.Server.GameTicking.Rules.Components; [RegisterComponent, Access(typeof(NukeopsRuleSystem), typeof(LoneOpsSpawnRule))] public sealed partial class NukeopsRuleComponent : Component { + // TODO Replace with GameRuleComponent.minPlayers /// /// The minimum needed amount of players /// - [DataField("minPlayers")] + [DataField] public int MinPlayers = 20; /// /// This INCLUDES the operatives. So a value of 3 is satisfied by 2 players & 1 operative /// - [DataField("playersPerOperative")] + [DataField] public int PlayersPerOperative = 10; - [DataField("maxOps")] - public int MaxOperatives = 5; + [DataField] + public int MaxOps = 5; /// /// What will happen if all of the nuclear operatives will die. Used by LoneOpsSpawn event. /// - [DataField("roundEndBehavior")] + [DataField] public RoundEndBehavior RoundEndBehavior = RoundEndBehavior.ShuttleCall; /// /// Text for shuttle call if RoundEndBehavior is ShuttleCall. /// - [DataField("roundEndTextSender")] + [DataField] public string RoundEndTextSender = "comms-console-announcement-title-centcom"; /// /// Text for shuttle call if RoundEndBehavior is ShuttleCall. /// - [DataField("roundEndTextShuttleCall")] + [DataField] public string RoundEndTextShuttleCall = "nuke-ops-no-more-threat-announcement-shuttle-call"; /// /// Text for announcement if RoundEndBehavior is ShuttleCall. Used if shuttle is already called /// - [DataField("roundEndTextAnnouncement")] + [DataField] public string RoundEndTextAnnouncement = "nuke-ops-no-more-threat-announcement"; /// /// Time to emergency shuttle to arrive if RoundEndBehavior is ShuttleCall. /// - [DataField("evacShuttleTime")] + [DataField] public TimeSpan EvacShuttleTime = TimeSpan.FromMinutes(10); /// /// Whether or not to spawn the nuclear operative outpost. Used by LoneOpsSpawn event. /// - [DataField("spawnOutpost")] + [DataField] public bool SpawnOutpost = true; /// /// Whether or not nukie left their outpost /// - [DataField("leftOutpost")] - public bool LeftOutpost = false; + [DataField] + public bool LeftOutpost; /// /// Enables opportunity to get extra TC for war declaration /// - [DataField("canEnableWarOps")] + [DataField] public bool CanEnableWarOps = true; /// /// Indicates time when war has been declared, null if not declared /// - [DataField("warDeclaredTime", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan? WarDeclaredTime; /// /// This amount of TC will be given to each nukie /// - [DataField("warTCAmountPerNukie")] + [DataField] public int WarTCAmountPerNukie = 40; /// @@ -100,55 +100,55 @@ public sealed partial class NukeopsRuleComponent : Component /// /// Delay between war declaration and nuke ops arrival on station map. Gives crew time to prepare /// - [DataField("warNukieArriveDelay")] + [DataField] public TimeSpan? WarNukieArriveDelay = TimeSpan.FromMinutes(15); /// /// Minimal operatives count for war declaration /// - [DataField("warDeclarationMinOps")] + [DataField] public int WarDeclarationMinOps = 4; - [DataField("spawnPointProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string SpawnPointPrototype = "SpawnPointNukies"; + [DataField] + public EntProtoId SpawnPointProto = "SpawnPointNukies"; - [DataField("ghostSpawnPointProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string GhostSpawnPointProto = "SpawnPointGhostNukeOperative"; + [DataField] + public EntProtoId GhostSpawnPointProto = "SpawnPointGhostNukeOperative"; - [DataField("commanderRoleProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string CommanderRolePrototype = "NukeopsCommander"; + [DataField] + public ProtoId CommanderRoleProto = "NukeopsCommander"; - [DataField("operativeRoleProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string OperativeRoleProto = "Nukeops"; + [DataField] + public ProtoId OperativeRoleProto = "Nukeops"; - [DataField("medicRoleProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MedicRoleProto = "NukeopsMedic"; + [DataField] + public ProtoId MedicRoleProto = "NukeopsMedic"; - [DataField("commanderStartingGearProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string CommanderStartGearPrototype = "SyndicateCommanderGearFull"; + [DataField] + public ProtoId CommanderStartGearProto = "SyndicateCommanderGearFull"; - [DataField("medicStartGearProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MedicStartGearPrototype = "SyndicateOperativeMedicFull"; + [DataField] + public ProtoId MedicStartGearProto = "SyndicateOperativeMedicFull"; - [DataField("operativeStartGearProto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string OperativeStartGearPrototype = "SyndicateOperativeGearFull"; + [DataField] + public ProtoId OperativeStartGearProto = "SyndicateOperativeGearFull"; - [DataField("eliteNames", customTypeSerializer: typeof(PrototypeIdSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] public string EliteNames = "SyndicateNamesElite"; - [DataField("normalNames", customTypeSerializer: typeof(PrototypeIdSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] public string NormalNames = "SyndicateNamesNormal"; - [DataField("outpostMap", customTypeSerializer: typeof(ResPathSerializer))] - public ResPath NukieOutpostMap = new("/Maps/nukieplanet.yml"); + [DataField(customTypeSerializer: typeof(ResPathSerializer))] + public ResPath OutpostMap = new("/Maps/nukieplanet.yml"); - [DataField("shuttleMap", customTypeSerializer: typeof(ResPathSerializer))] - public ResPath NukieShuttleMap = new("/Maps/infiltrator.yml"); + [DataField(customTypeSerializer: typeof(ResPathSerializer))] + public ResPath ShuttleMap = new("/Maps/infiltrator.yml"); - [DataField("winType")] + [DataField] public WinType WinType = WinType.Neutral; - [DataField("winConditions")] + [DataField] public List WinConditions = new (); public MapId? NukiePlanet; @@ -162,30 +162,30 @@ public sealed partial class NukeopsRuleComponent : Component /// /// Cached starting gear prototypes. /// - [DataField("startingGearPrototypes")] + [DataField] public Dictionary StartingGearPrototypes = new (); /// /// Cached operator name prototypes. /// - [DataField("operativeNames")] + [DataField] public Dictionary> OperativeNames = new(); /// /// Data to be used in for an operative once the Mind has been added. /// - [DataField("operativeMindPendingData")] + [DataField] public Dictionary OperativeMindPendingData = new(); /// /// Players who played as an operative at some point in the round. /// Stores the mind as well as the entity name /// - [DataField("operativePlayers")] + [DataField] public Dictionary OperativePlayers = new(); - [DataField("faction", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] - public string Faction = default!; + [DataField(required: true)] + public ProtoId Faction = default!; } public enum WinType : byte diff --git a/Content.Server/GameTicking/Rules/GameRuleSystem.cs b/Content.Server/GameTicking/Rules/GameRuleSystem.cs index e87660c2cc4..b13f00f3638 100644 --- a/Content.Server/GameTicking/Rules/GameRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/GameRuleSystem.cs @@ -1,9 +1,11 @@ +using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; namespace Content.Server.GameTicking.Rules; public abstract partial class GameRuleSystem : EntitySystem where T : Component { + [Dependency] protected readonly IChatManager ChatManager = default!; [Dependency] protected readonly GameTicker GameTicker = default!; public override void Initialize() @@ -36,6 +38,7 @@ private void OnGameRuleEnded(EntityUid uid, T component, ref GameRuleEndedEvent Ended(uid, component, ruleData, args); } + /// /// Called when the gamerule is added /// @@ -68,6 +71,36 @@ protected virtual void ActiveTick(EntityUid uid, T component, GameRuleComponent } + protected EntityQueryEnumerator QueryActiveRules() + { + return EntityQueryEnumerator(); + } + + protected bool TryRoundStartAttempt(RoundStartAttemptEvent ev, string localizedPresetName) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out _, out _, out _, out var gameRule)) + { + var minPlayers = gameRule.MinPlayers; + if (!ev.Forced && ev.Players.Length < minPlayers) + { + ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-players", + ("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers), + ("presetName", localizedPresetName))); + ev.Cancel(); + continue; + } + + if (ev.Players.Length == 0) + { + ChatManager.DispatchServerAnnouncement(Loc.GetString("preset-no-one-ready")); + ev.Cancel(); + } + } + + return !ev.Cancelled; + } + public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index df9fbcc1301..3bd3d13d277 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -595,7 +595,7 @@ private void OnPlayersSpawning(RulePlayerSpawningEvent ev) // Basically copied verbatim from traitor code var playersPerOperative = nukeops.PlayersPerOperative; - var maxOperatives = nukeops.MaxOperatives; + var maxOperatives = nukeops.MaxOps; // Dear lord what is happening HERE. var everyone = new List(ev.PlayerPool); @@ -614,15 +614,15 @@ private void OnPlayersSpawning(RulePlayerSpawningEvent ev) } var profile = ev.Profiles[player.UserId]; - if (profile.AntagPreferences.Contains(nukeops.OperativeRoleProto)) + if (profile.AntagPreferences.Contains(nukeops.OperativeRoleProto.Id)) { prefList.Add(player); } - if (profile.AntagPreferences.Contains(nukeops.MedicRoleProto)) + if (profile.AntagPreferences.Contains(nukeops.MedicRoleProto.Id)) { medPrefList.Add(player); } - if (profile.AntagPreferences.Contains(nukeops.CommanderRolePrototype)) + if (profile.AntagPreferences.Contains(nukeops.CommanderRoleProto.Id)) { cmdrPrefList.Add(player); } @@ -808,8 +808,8 @@ private bool SpawnMap(EntityUid uid, NukeopsRuleComponent? component = null) if (!component.SpawnOutpost) return true; - var path = component.NukieOutpostMap; - var shuttlePath = component.NukieShuttleMap; + var path = component.OutpostMap; + var shuttlePath = component.ShuttleMap; var mapId = _mapManager.CreateMap(); var options = new MapLoadOptions @@ -866,18 +866,18 @@ private bool SpawnMap(EntityUid uid, NukeopsRuleComponent? component = null) { case 0: name = Loc.GetString("nukeops-role-commander") + " " + _random.PickAndTake(component.OperativeNames[component.EliteNames]); - role = component.CommanderRolePrototype; - gear = component.CommanderStartGearPrototype; + role = component.CommanderRoleProto; + gear = component.CommanderStartGearProto; break; case 1: name = Loc.GetString("nukeops-role-agent") + " " + _random.PickAndTake(component.OperativeNames[component.NormalNames]); role = component.MedicRoleProto; - gear = component.MedicStartGearPrototype; + gear = component.MedicStartGearProto; break; default: name = Loc.GetString("nukeops-role-operator") + " " + _random.PickAndTake(component.OperativeNames[component.NormalNames]); role = component.OperativeRoleProto; - gear = component.OperativeStartGearPrototype; + gear = component.OperativeStartGearProto; break; } @@ -915,7 +915,7 @@ private void SpawnOperatives(int spawnCount, List sessions, bool // Forgive me for hardcoding prototypes foreach (var (_, meta, xform) in EntityQuery(true)) { - if (meta.EntityPrototype?.ID != component.SpawnPointPrototype) + if (meta.EntityPrototype?.ID != component.SpawnPointProto.Id) continue; if (xform.ParentUid != component.NukieOutpost) @@ -981,7 +981,7 @@ private void SpawnOperativesForGhostRoles(EntityUid uid, NukeopsRuleComponent? c } // Basically copied verbatim from traitor code var playersPerOperative = component.PlayersPerOperative; - var maxOperatives = component.MaxOperatives; + var maxOperatives = component.MaxOps; var playerPool = _playerManager.ServerSessions.ToList(); var numNukies = MathHelper.Clamp(playerPool.Count / playersPerOperative, 1, maxOperatives); @@ -1115,9 +1115,9 @@ protected override void Started(EntityUid uid, NukeopsRuleComponent component, G // TODO: Loot table or something foreach (var proto in new[] { - component.CommanderStartGearPrototype, - component.MedicStartGearPrototype, - component.OperativeStartGearPrototype + component.CommanderStartGearProto, + component.MedicStartGearProto, + component.OperativeStartGearProto }) { component.StartingGearPrototypes.Add(proto, _prototypeManager.Index(proto)); diff --git a/Content.Server/Implants/ImplanterSystem.cs b/Content.Server/Implants/ImplanterSystem.cs index db5602a2bb9..f3072769e4d 100644 --- a/Content.Server/Implants/ImplanterSystem.cs +++ b/Content.Server/Implants/ImplanterSystem.cs @@ -8,7 +8,6 @@ using Content.Shared.Mobs.Components; using Content.Shared.Popups; using Robust.Shared.Containers; -using Robust.Shared.GameStates; namespace Content.Server.Implants; @@ -24,7 +23,6 @@ public override void Initialize() InitializeImplanted(); SubscribeLocalEvent(OnImplanterAfterInteract); - SubscribeLocalEvent(OnImplanterGetState); SubscribeLocalEvent(OnImplant); SubscribeLocalEvent(OnDraw); @@ -109,11 +107,6 @@ public void TryDraw(ImplanterComponent component, EntityUid user, EntityUid targ } - private void OnImplanterGetState(EntityUid uid, ImplanterComponent component, ref ComponentGetState args) - { - args.State = new ImplanterComponentState(component.CurrentMode, component.ImplantOnly); - } - private void OnImplant(EntityUid uid, ImplanterComponent component, ImplantEvent args) { if (args.Cancelled || args.Handled || args.Target == null || args.Used == null) diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index 9761ae57657..309ee583162 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -107,11 +107,11 @@ private void OnGetWhitelist(EntityUid uid, LatheComponent component, ref GetMate { if (args.Storage != uid) return; - var materialWhitelist = new List(); + var materialWhitelist = new List>(); var recipes = GetAllBaseRecipes(component); foreach (var id in recipes) { - if (!_proto.TryIndex(id, out var proto)) + if (!_proto.TryIndex(id, out var proto)) continue; foreach (var (mat, _) in proto.RequiredMaterials) { @@ -127,7 +127,7 @@ private void OnGetWhitelist(EntityUid uid, LatheComponent component, ref GetMate } [PublicAPI] - public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List? recipes, [NotNullWhen(true)] LatheComponent? component = null) + public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List>? recipes, [NotNullWhen(true)] LatheComponent? component = null) { recipes = null; if (!Resolve(uid, ref component)) @@ -136,17 +136,17 @@ public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List GetAvailableRecipes(EntityUid uid, LatheComponent component) + public List> GetAvailableRecipes(EntityUid uid, LatheComponent component) { var ev = new LatheGetRecipesEvent(uid) { - Recipes = new List(component.StaticRecipes) + Recipes = new List>(component.StaticRecipes) }; RaiseLocalEvent(uid, ev); return ev.Recipes; } - public static List GetAllBaseRecipes(LatheComponent component) + public static List> GetAllBaseRecipes(LatheComponent component) { return component.StaticRecipes.Union(component.DynamicRecipes).ToList(); } @@ -300,7 +300,7 @@ private void OnPowerChanged(EntityUid uid, LatheComponent component, ref PowerCh private void OnPartsRefresh(EntityUid uid, LatheComponent component, RefreshPartsEvent args) { - var printTimeRating = args.PartRatings[component.MachinePartPrintTime]; + var printTimeRating = args.PartRatings[component.MachinePartPrintSpeed]; var materialUseRating = args.PartRatings[component.MachinePartMaterialUse]; component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1); diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index 5b990412d8a..9cca5fa32cc 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -16,7 +16,7 @@ using Content.Shared.Magic.Events; using Content.Shared.Maps; using Content.Shared.Physics; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Storage; using Robust.Server.GameObjects; using Robust.Shared.Audio; diff --git a/Content.Server/Morgue/CrematoriumSystem.cs b/Content.Server/Morgue/CrematoriumSystem.cs index 5ef42ea00e8..d713b43f27a 100644 --- a/Content.Server/Morgue/CrematoriumSystem.cs +++ b/Content.Server/Morgue/CrematoriumSystem.cs @@ -156,7 +156,7 @@ private void OnSuicide(EntityUid uid, CrematoriumComponent component, SuicideEve ("victim", Identity.Entity(victim, EntityManager))), victim, Filter.PvsExcept(victim), true, PopupType.LargeCaution); - if (_entityStorage.CanInsert(uid)) + if (_entityStorage.CanInsert(victim, uid)) { _entityStorage.CloseStorage(uid); _standing.Down(victim, false); diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs index 1d9c19de027..87deec9ea9d 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs @@ -113,7 +113,7 @@ private SteeringObstacleStatus TryHandleFlags(EntityUid uid, NPCSteeringComponen // TODO: Use the verb. if (door.State != DoorState.Opening) - _doors.TryPryDoor(ent, uid, uid, door, out id, force: true); + _pryingSystem.TryPry(ent, uid, out id, uid); component.DoAfterId = id; return SteeringObstacleStatus.Continuing; diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs index cbc2ba6d2c4..0fa28f6af79 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs @@ -31,6 +31,7 @@ using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; +using Content.Shared.Prying.Systems; namespace Content.Server.NPC.Systems; @@ -63,6 +64,7 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedCombatModeSystem _combat = default!; + [Dependency] private readonly PryingSystem _pryingSystem = default!; private EntityQuery _fixturesQuery; private EntityQuery _modifierQuery; @@ -148,7 +150,7 @@ public override void Shutdown() private void OnDebugRequest(RequestNPCSteeringDebugEvent msg, EntitySessionEventArgs args) { - if (!_admin.IsAdmin((IPlayerSession) args.SenderSession)) + if (!_admin.IsAdmin((IPlayerSession)args.SenderSession)) return; if (msg.Enabled) @@ -440,7 +442,7 @@ private async void RequestPath(EntityUid uid, NPCSteeringComponent steering, Tra if (targetPoly != null && steering.Coordinates.Position.Equals(Vector2.Zero) && TryComp(uid, out var physics) && - _interaction.InRangeUnobstructed(uid, steering.Coordinates.EntityId, range: 30f, (CollisionGroup) physics.CollisionMask)) + _interaction.InRangeUnobstructed(uid, steering.Coordinates.EntityId, range: 30f, (CollisionGroup)physics.CollisionMask)) { steering.CurrentPath.Clear(); steering.CurrentPath.Enqueue(targetPoly); diff --git a/Content.Server/Nyanotrasen/ReverseEngineering/ActiveReverseEngineeringMachineComponent.cs b/Content.Server/Nyanotrasen/ReverseEngineering/ActiveReverseEngineeringMachineComponent.cs new file mode 100644 index 00000000000..76839956593 --- /dev/null +++ b/Content.Server/Nyanotrasen/ReverseEngineering/ActiveReverseEngineeringMachineComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations; + +namespace Content.Server.ReverseEngineering; + +[RegisterComponent] +public sealed partial class ActiveReverseEngineeringMachineComponent : Component +{ + /// + /// When did the scanning start? + /// + [DataField("startTime", customTypeSerializer: typeof(TimespanSerializer))] + public TimeSpan StartTime; + + /// + /// What is being scanned? + /// + [ViewVariables] + public EntityUid Item; +} diff --git a/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineComponent.cs b/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineComponent.cs new file mode 100644 index 00000000000..4dba64a06f3 --- /dev/null +++ b/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringMachineComponent.cs @@ -0,0 +1,79 @@ +using Content.Shared.ReverseEngineering; +using Content.Shared.Construction.Prototypes; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Audio; + +namespace Content.Server.ReverseEngineering; + +/// +/// This machine can reverse engineer items and get a technology disk from them. +/// +[RegisterComponent] +public sealed partial class ReverseEngineeringMachineComponent : Component +{ + [DataField("diskPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string DiskPrototype = "TechnologyDisk"; + + [DataField("machinePartScanBonus", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachinePartScanBonus = "Capacitor"; + + /// + /// Added to the 3d6, scales off of scanner. + /// + public int ScanBonus = 1; + + + [DataField("machinePartDangerAversionScore", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachinePartDangerAversionScore = "Manipulator"; + + /// + /// If we rolled destruction, this is added to the roll and if it <= 9 it becomes + /// stagnation instead. + /// + public int DangerAversionScore = 1; + + /// + /// Whether the machine is going to receive the danger bonus. + /// + [DataField("dangerBonus")] + public int DangerBonus = 3; + + [DataField("failSound1")] + public SoundSpecifier FailSound1 { get; set; } = new SoundPathSpecifier("/Audio/Effects/spray.ogg"); + + [DataField("failSound2")] + public SoundSpecifier FailSound2 { get; set; } = new SoundPathSpecifier("/Audio/Effects/sparks4.ogg"); + + [DataField("successSound")] + public SoundSpecifier SuccessSound { get; set; } = new SoundPathSpecifier("/Audio/Machines/microwave_done_beep.ogg"); + + [DataField("clickSound")] + public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/machine_switch.ogg"); + public EntityUid? CurrentItem; + + /// + /// Malus from the item's difficulty. + /// + [ViewVariables] + public int CurrentItemDifficulty = 0; + + /// + /// Whether the safety is on. + /// + public bool SafetyOn = true; + + /// + /// Whether autoscan is on. + /// + public bool AutoScan = true; + + public int Progress = 0; + + public TimeSpan AnalysisDuration = TimeSpan.FromSeconds(30); + + public FormattedMessage? CachedMessage; + + public ReverseEngineeringTickResult? LastResult; +} diff --git a/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringSystem.cs b/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringSystem.cs new file mode 100644 index 00000000000..7fc3f8c2d0a --- /dev/null +++ b/Content.Server/Nyanotrasen/ReverseEngineering/ReverseEngineeringSystem.cs @@ -0,0 +1,415 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.ReverseEngineering; +using Content.Shared.Audio; +using Content.Shared.Examine; +using Content.Server.Research.TechnologyDisk.Components; +using Content.Server.UserInterface; +using Content.Server.Power.Components; +using Content.Server.Construction; +using Content.Server.Popups; +using Robust.Shared.Containers; +using Robust.Shared.Random; +using Robust.Shared.Utility; +using Robust.Shared.Timing; +using Robust.Server.GameObjects; + +namespace Content.Server.ReverseEngineering; + +public sealed class ReverseEngineeringSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly ItemSlotsSystem _slots = default!; + [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; + + private const string TargetSlot = "target_slot"; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEntInserted); + SubscribeLocalEvent(OnEntRemoved); + SubscribeLocalEvent(OnRefreshParts); + SubscribeLocalEvent(OnExamineParts); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + + SubscribeLocalEvent(OnScanButtonPressed); + SubscribeLocalEvent(OnSafetyButtonToggled); + SubscribeLocalEvent(OnAutoScanButtonToggled); + SubscribeLocalEvent(OnStopButtonPressed); + SubscribeLocalEvent(OnEjectButtonPressed); + + SubscribeLocalEvent(OnPowerChanged); + + SubscribeLocalEvent(OnExamined); + + SubscribeLocalEvent((e,c,_) => UpdateUserInterface(e,c)); + + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + foreach (var (active, rev) in EntityQuery()) + { + UpdateUserInterface(rev.Owner, rev); + + if (_timing.CurTime - active.StartTime < rev.AnalysisDuration) + continue; + + FinishProbe(rev.Owner, rev, active); + } + } + + private void OnEntInserted(EntityUid uid, ReverseEngineeringMachineComponent component, EntInsertedIntoContainerMessage args) + { + if (args.Container.ID != TargetSlot || !TryComp(args.Entity, out var rev)) + return; + + _slots.SetLock(uid, TargetSlot, true); + component.CurrentItem = args.Entity; + component.CurrentItemDifficulty = rev.Difficulty; + component.CachedMessage = GetReverseEngineeringScanMessage(component); + UpdateUserInterface(uid, component); + + if (TryComp(uid, out var appearance)) + _appearanceSystem.SetData(uid, ReverseEngineeringVisuals.ChamberOpen, false, appearance); + } + + private void OnEntRemoved(EntityUid uid, ReverseEngineeringMachineComponent component, EntRemovedFromContainerMessage args) + { + if (args.Container.ID != TargetSlot) + return; + + component.CurrentItem = null; + component.CurrentItemDifficulty = 0; + component.Progress = 0; + CancelProbe(uid, component); + + if (TryComp(uid, out var appearance)) + _appearanceSystem.SetData(uid, ReverseEngineeringVisuals.ChamberOpen, true, appearance); + } + + private void OnRefreshParts(EntityUid uid, ReverseEngineeringMachineComponent component, RefreshPartsEvent args) + { + var bonusRating = args.PartRatings[component.MachinePartScanBonus]; + var aversionRating = args.PartRatings[component.MachinePartDangerAversionScore]; + + component.ScanBonus = (int) bonusRating; + component.DangerAversionScore = (int) aversionRating; + } + + private void OnExamineParts(EntityUid uid, ReverseEngineeringMachineComponent component, UpgradeExamineEvent args) + { + args.AddNumberUpgrade("reverse-engineering-machine-bonus-upgrade", component.ScanBonus - 1); + args.AddNumberUpgrade("reverse-engineering-machine-aversion-upgrade", component.DangerAversionScore - 1); + } + + private void OnStartup(EntityUid uid, ActiveReverseEngineeringMachineComponent component, ComponentStartup args) + { + _ambientSoundSystem.SetAmbience(uid, true); + } + + private void OnShutdown(EntityUid uid,ActiveReverseEngineeringMachineComponent component, ComponentShutdown args) + { + _ambientSoundSystem.SetAmbience(uid, false); + } + + private void OnScanButtonPressed(EntityUid uid, ReverseEngineeringMachineComponent component, ReverseEngineeringMachineScanButtonPressedMessage args) + { + if (component.CurrentItem == null) + return; + + if (HasComp(uid)) + return; + + _audio.PlayPvs(component.ClickSound, uid); + + component.CachedMessage = null; + var activeComp = EnsureComp(uid); + activeComp.StartTime = _timing.CurTime; + activeComp.Item = component.CurrentItem.Value; + } + + private void OnSafetyButtonToggled(EntityUid uid, ReverseEngineeringMachineComponent component, ReverseEngineeringMachineSafetyButtonToggledMessage args) + { + _audio.PlayPvs(component.ClickSound, uid); + + component.SafetyOn = args.Safety; + component.CachedMessage = null; + UpdateUserInterface(uid, component); + } + + private void OnAutoScanButtonToggled(EntityUid uid, ReverseEngineeringMachineComponent component, ReverseEngineeringMachineAutoScanButtonToggledMessage args) + { + _audio.PlayPvs(component.ClickSound, uid); + + component.AutoScan = args.AutoScan; + } + + private void OnPowerChanged(EntityUid uid, ReverseEngineeringMachineComponent component, ref PowerChangedEvent args) + { + if (!args.Powered) + CancelProbe(uid, component); + } + + private void OnExamined(EntityUid uid, ReverseEngineeringComponent component, ExaminedEvent args) + { + // TODO: Eventually this should probably get shoved into a contextual examine somewhere like health or machine upgrading. + // And this can be predicted I guess if difficulty becomes read only. + args.PushMarkup(Loc.GetString("reverse-engineering-examine", ("diff", component.Difficulty))); + } + + private void OnStopButtonPressed(EntityUid uid, ReverseEngineeringMachineComponent component, ReverseEngineeringMachineStopButtonPressedMessage args) + { + _audio.PlayPvs(component.ClickSound, uid); + + CancelProbe(uid, component); + } + + private void OnEjectButtonPressed(EntityUid uid, ReverseEngineeringMachineComponent component, ReverseEngineeringMachineEjectButtonPressedMessage args) + { + _audio.PlayPvs(component.ClickSound, uid); + + Eject(uid, component); + } + + private void UpdateUserInterface(EntityUid uid, ReverseEngineeringMachineComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + if (!_ui.TryGetUi(uid, ReverseEngineeringMachineUiKey.Key, out var bui)) + return; + + EntityUid? item = component.CurrentItem; + if (component.CachedMessage == null) + component.CachedMessage = GetReverseEngineeringScanMessage(component); + + var totalTime = TimeSpan.Zero; + var scanning = TryComp(uid, out var active); + var canScan = (item != null && !scanning); + var remaining = active != null ? _timing.CurTime - active.StartTime : TimeSpan.Zero; + EntityManager.TryGetNetEntity(item, out var netItem); + + var state = new ReverseEngineeringMachineScanUpdateState(netItem, canScan, component.CachedMessage, scanning, component.SafetyOn, component.AutoScan, component.Progress, remaining, component.AnalysisDuration); + + _ui.SetUiState(bui, state); + } + + private ReverseEngineeringTickResult Roll(ReverseEngineeringMachineComponent component, out int actualRoll) + { + int roll = (_random.Next(1, 6) + _random.Next(1, 6) + _random.Next(1, 6)); + + roll += component.ScanBonus; + + if (!component.SafetyOn) + roll += component.DangerBonus; + + roll -= component.CurrentItemDifficulty; + + actualRoll = roll; + return roll switch + { + <= 9 => ReverseEngineeringTickResult.Destruction, + <= 10 => ReverseEngineeringTickResult.Stagnation, + <= 12 => ReverseEngineeringTickResult.SuccessMinor, + <= 15 => ReverseEngineeringTickResult.SuccessAverage, + <= 17 => ReverseEngineeringTickResult.SuccessMajor, + _ => ReverseEngineeringTickResult.InstantSuccess + }; + } + + private void FinishProbe(EntityUid uid, ReverseEngineeringMachineComponent? component = null, ActiveReverseEngineeringMachineComponent? active = null) + { + if (!Resolve(uid, ref component, ref active)) + return; + + if (!TryComp(component.CurrentItem, out var rev)) + { + Logger.Error("We somehow scanned a " + component.CurrentItem + " for reverse engineering..."); + return; + } + + component.CachedMessage = null; + + var result = Roll(component, out var actualRoll); + + if (result == ReverseEngineeringTickResult.Destruction) + { + if (!component.SafetyOn && actualRoll + component.DangerAversionScore < 9) + { + Del(component.CurrentItem.Value); + component.CurrentItem = null; + if (TryComp(uid, out var appearance)) + _appearanceSystem.SetData(uid, ReverseEngineeringVisuals.ChamberOpen, true, appearance); + _slots.SetLock(uid, TargetSlot, false); + _audio.PlayPvs(component.FailSound1, uid); + _audio.PlayPvs(component.FailSound2, uid); + _popupSystem.PopupEntity(Loc.GetString("reverse-engineering-popup-failure", ("machine", uid)), uid, Shared.Popups.PopupType.MediumCaution); + CancelProbe(uid, component); + } else + { + result = ReverseEngineeringTickResult.Stagnation; + } + } + + component.LastResult = result; + + int bonus = 0; + + switch (result) + { + case ReverseEngineeringTickResult.Stagnation: + { + bonus += 1; + break; + } + case ReverseEngineeringTickResult.SuccessMinor: + { + bonus += 10; + break; + } + case ReverseEngineeringTickResult.SuccessAverage: + { + bonus += 25; + break; + } + case ReverseEngineeringTickResult.SuccessMajor: + { + bonus += 40; + break; + } + case ReverseEngineeringTickResult.InstantSuccess: + { + bonus += 100; + break; + } + } + + component.Progress += bonus; + component.Progress = Math.Clamp(component.Progress, 0, 100); + + if (component.Progress < 100) + { + if (component.AutoScan) + { + active.StartTime = _timing.CurTime; + } + else + { + RemComp(uid); + } + } else + { + CreateDisk(uid, component.DiskPrototype, rev.Recipes); + _audio.PlayPvs(component.SuccessSound, uid); + if (rev.NewItem == null) + { + Eject(uid, component); + } else + { + _slots.SetLock(uid, TargetSlot, false); + Spawn(rev.NewItem, Transform(uid).Coordinates); + if (component.CurrentItem != null) + Del(component.CurrentItem.Value); + } + RemComp(uid); + } + + UpdateUserInterface(uid, component); + } + + private void CreateDisk(EntityUid uid, string diskPrototype, List? recipes) + { + var disk = Spawn(diskPrototype, Transform(uid).Coordinates); + + if (!TryComp(disk, out var diskComponent)) + return; + + diskComponent.Recipes = recipes; + } + + private FormattedMessage? GetReverseEngineeringScanMessage(ReverseEngineeringMachineComponent component) + { + var msg = new FormattedMessage(); + + if (component.CurrentItem == null) + { + msg.AddMarkup(Loc.GetString("reverse-engineering-status-ready")); + return msg; + } + + msg.AddMarkup(Loc.GetString("reverse-engineering-current-item", ("item", component.CurrentItem.Value))); + msg.PushNewline(); + msg.PushNewline(); + + var analysisScore = component.ScanBonus; + if (!component.SafetyOn) + analysisScore += component.DangerBonus; + + msg.AddMarkup(Loc.GetString("reverse-engineering-analysis-score", ("score", analysisScore))); + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("reverse-engineering-item-difficulty", ("difficulty", component.CurrentItemDifficulty))); + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("reverse-engineering-progress", ("progress", component.Progress))); + msg.PushNewline(); + + if (component.LastResult != null) + { + string lastProbe = string.Empty; + + switch (component.LastResult) + { + case ReverseEngineeringTickResult.Destruction: + lastProbe = Loc.GetString("reverse-engineering-failure"); + break; + case ReverseEngineeringTickResult.Stagnation: + lastProbe = Loc.GetString("reverse-engineering-stagnation"); + break; + case ReverseEngineeringTickResult.SuccessMinor: + lastProbe = Loc.GetString("reverse-engineering-minor"); + break; + case ReverseEngineeringTickResult.SuccessAverage: + lastProbe = Loc.GetString("reverse-engineering-average"); + break; + case ReverseEngineeringTickResult.SuccessMajor: + lastProbe = Loc.GetString("reverse-engineering-major"); + break; + case ReverseEngineeringTickResult.InstantSuccess: + lastProbe = Loc.GetString("reverse-engineering-success"); + break; + } + + msg.AddMarkup(Loc.GetString("reverse-engineering-last-attempt-result", ("result", lastProbe))); + } + + return msg; + } + + private void Eject(EntityUid uid, ReverseEngineeringMachineComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + _slots.SetLock(uid, TargetSlot, false); + _slots.TryEject(uid, TargetSlot, null, out var item); + } + + private void CancelProbe(EntityUid uid, ReverseEngineeringMachineComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.CachedMessage = null; + component.LastResult = null; + RemComp(uid); + UpdateUserInterface(uid, component); + } +} diff --git a/Content.Server/Objectives/Components/CarpRiftsConditionComponent.cs b/Content.Server/Objectives/Components/CarpRiftsConditionComponent.cs new file mode 100644 index 00000000000..8e43154e37a --- /dev/null +++ b/Content.Server/Objectives/Components/CarpRiftsConditionComponent.cs @@ -0,0 +1,17 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +/// +/// Requires that the dragon open and fully charge a certain number of rifts. +/// Depends on to function. +/// +[RegisterComponent, Access(typeof(CarpRiftsConditionSystem))] +public sealed partial class CarpRiftsConditionComponent : Component +{ + /// + /// The number of rifts currently charged. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int RiftsCharged; +} diff --git a/Content.Server/Objectives/Systems/CarpRiftsConditionSystem.cs b/Content.Server/Objectives/Systems/CarpRiftsConditionSystem.cs new file mode 100644 index 00000000000..efb2d228d6f --- /dev/null +++ b/Content.Server/Objectives/Systems/CarpRiftsConditionSystem.cs @@ -0,0 +1,56 @@ +using Content.Server.Objectives.Components; +using Content.Server.Roles; +using Content.Shared.Objectives.Components; + +namespace Content.Server.Objectives.Systems; + +public sealed class CarpRiftsConditionSystem : EntitySystem +{ + [Dependency] private readonly NumberObjectiveSystem _number = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetProgress); + } + + private void OnGetProgress(EntityUid uid, CarpRiftsConditionComponent comp, ref ObjectiveGetProgressEvent args) + { + args.Progress = GetProgress(comp, _number.GetTarget(uid)); + } + + private float GetProgress(CarpRiftsConditionComponent comp, int target) + { + // prevent divide-by-zero + if (target == 0) + return 1f; + + if (comp.RiftsCharged >= target) + return 1f; + + return (float) comp.RiftsCharged / (float) target; + } + + /// + /// Increments RiftsCharged, called after a rift fully charges. + /// + public void RiftCharged(EntityUid uid, CarpRiftsConditionComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + comp.RiftsCharged++; + } + + /// + /// Resets RiftsCharged to 0, called after rifts get destroyed. + /// + public void ResetRifts(EntityUid uid, CarpRiftsConditionComponent? comp = null) + { + if (!Resolve(uid, ref comp)) + return; + + comp.RiftsCharged = 0; + } +} diff --git a/Content.Server/Points/PointSystem.cs b/Content.Server/Points/PointSystem.cs index c3265701c07..56831980d0f 100644 --- a/Content.Server/Points/PointSystem.cs +++ b/Content.Server/Points/PointSystem.cs @@ -5,7 +5,6 @@ using Robust.Server.GameObjects; using Robust.Server.GameStates; using Robust.Server.Player; -using Robust.Shared.GameStates; using Robust.Shared.Utility; namespace Content.Server.Points; @@ -22,7 +21,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnStartup); - SubscribeLocalEvent(OnGetState); } private void OnStartup(EntityUid uid, PointManagerComponent component, ComponentStartup args) @@ -30,11 +28,6 @@ private void OnStartup(EntityUid uid, PointManagerComponent component, Component _pvsOverride.AddGlobalOverride(uid); } - private void OnGetState(EntityUid uid, PointManagerComponent component, ref ComponentGetState args) - { - args.State = new PointManagerComponentState(component.Points, component.Scoreboard); - } - /// /// Adds the specified point value to a player. /// diff --git a/Content.Server/Radiation/Systems/GeigerSystem.cs b/Content.Server/Radiation/Systems/GeigerSystem.cs index 050b1698192..640a257694d 100644 --- a/Content.Server/Radiation/Systems/GeigerSystem.cs +++ b/Content.Server/Radiation/Systems/GeigerSystem.cs @@ -5,8 +5,6 @@ using Content.Shared.Inventory.Events; using Content.Shared.Radiation.Components; using Content.Shared.Radiation.Systems; -using Robust.Shared.GameStates; -using Robust.Shared.Player; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -32,7 +30,6 @@ public override void Initialize() SubscribeLocalEvent(OnUnequippedHand); SubscribeLocalEvent(OnUpdate); - SubscribeLocalEvent(OnGetState); } private void OnActivate(EntityUid uid, GeigerComponent component, ActivateInWorldEvent args) @@ -86,17 +83,6 @@ private void OnUpdate(RadiationSystemUpdatedEvent ev) } } - private void OnGetState(EntityUid uid, GeigerComponent component, ref ComponentGetState args) - { - args.State = new GeigerComponentState - { - CurrentRadiation = component.CurrentRadiation, - DangerLevel = component.DangerLevel, - IsEnabled = component.IsEnabled, - User = GetNetEntity(component.User) - }; - } - private void SetCurrentRadiation(EntityUid uid, GeigerComponent component, float rads) { // check that it's approx equal diff --git a/Content.Server/Roles/DragonRoleComponent.cs b/Content.Server/Roles/DragonRoleComponent.cs new file mode 100644 index 00000000000..77fd97acb29 --- /dev/null +++ b/Content.Server/Roles/DragonRoleComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.Dragon; +using Content.Shared.Roles; + +namespace Content.Server.Roles; + +/// +/// Role used to keep track of space dragons for antag purposes. +/// +[RegisterComponent, Access(typeof(DragonSystem))] +public sealed partial class DragonRoleComponent : AntagonistRoleComponent +{ +} diff --git a/Content.Server/Roles/RoleSystem.cs b/Content.Server/Roles/RoleSystem.cs index 4ca6c0ac801..b04f051c6e8 100644 --- a/Content.Server/Roles/RoleSystem.cs +++ b/Content.Server/Roles/RoleSystem.cs @@ -9,6 +9,7 @@ public override void Initialize() // TODO make roles entities base.Initialize(); + SubscribeAntagEvents(); SubscribeAntagEvents(); SubscribeAntagEvents(); SubscribeAntagEvents(); diff --git a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs index 7bbe6ed1081..19779c5cfee 100644 --- a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs +++ b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs @@ -13,7 +13,7 @@ using Content.Shared.Mobs.Components; using Content.Shared.Movement.Components; using Content.Shared.Shuttles.Components; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Content.Shared.Tiles; using Robust.Server.GameObjects; using Robust.Shared.Collections; @@ -22,6 +22,7 @@ using Robust.Shared.Map; using Robust.Shared.Random; using Robust.Shared.Timing; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.Shuttles.Systems; diff --git a/Content.Server/Spawners/EntitySystems/SpawnerSystem.cs b/Content.Server/Spawners/EntitySystems/SpawnerSystem.cs index 1d0e4c397cf..c6e34c18484 100644 --- a/Content.Server/Spawners/EntitySystems/SpawnerSystem.cs +++ b/Content.Server/Spawners/EntitySystems/SpawnerSystem.cs @@ -12,6 +12,7 @@ public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnSpawnerInit); + SubscribeLocalEvent(OnTimedSpawnerShutdown); } private void OnSpawnerInit(EntityUid uid, TimedSpawnerComponent component, ComponentInit args) @@ -35,4 +36,9 @@ private void OnTimerFired(EntityUid uid, TimedSpawnerComponent component) Spawn(entity, coordinates); } } + + private void OnTimedSpawnerShutdown(EntityUid uid, TimedSpawnerComponent component, ComponentShutdown args) + { + component.TokenSource?.Cancel(); + } } diff --git a/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs b/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs deleted file mode 100644 index cadad4633e9..00000000000 --- a/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Content.Server.Spawners.Components; -using Content.Shared.Spawners.EntitySystems; - -namespace Content.Server.Spawners.EntitySystems; - -public sealed class TimedDespawnSystem : SharedTimedDespawnSystem -{ - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnTimedSpawnerShutdown); - } - - private void OnTimedSpawnerShutdown(EntityUid uid, TimedSpawnerComponent component, ComponentShutdown args) - { - component.TokenSource?.Cancel(); - } - - protected override bool CanDelete(EntityUid uid) - { - return true; - } -} diff --git a/Content.Server/StationEvents/Events/ImmovableRodRule.cs b/Content.Server/StationEvents/Events/ImmovableRodRule.cs index b92ac917bc9..a61c6b69e1a 100644 --- a/Content.Server/StationEvents/Events/ImmovableRodRule.cs +++ b/Content.Server/StationEvents/Events/ImmovableRodRule.cs @@ -3,8 +3,9 @@ using Content.Server.ImmovableRod; using Content.Server.StationEvents.Components; using Content.Server.Weapons.Ranged.Systems; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Robust.Shared.Prototypes; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.StationEvents.Events; diff --git a/Content.Server/StationEvents/Events/MeteorSwarmRule.cs b/Content.Server/StationEvents/Events/MeteorSwarmRule.cs index b5408ac982f..5192eef69b1 100644 --- a/Content.Server/StationEvents/Events/MeteorSwarmRule.cs +++ b/Content.Server/StationEvents/Events/MeteorSwarmRule.cs @@ -1,10 +1,11 @@ using System.Numerics; using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents.Components; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Robust.Shared.Map; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; +using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent; namespace Content.Server.StationEvents.Events { diff --git a/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs b/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs index a9e8c437ec0..c3cd719cc4c 100644 --- a/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs +++ b/Content.Server/StationEvents/Events/RandomEntityStorageSpawnRule.cs @@ -2,6 +2,7 @@ using Content.Server.StationEvents.Components; using Content.Server.Storage.Components; using Content.Server.Storage.EntitySystems; +using Robust.Shared.Map; using Robust.Shared.Random; namespace Content.Server.StationEvents.Events; @@ -17,7 +18,8 @@ protected override void Started(EntityUid uid, RandomEntityStorageSpawnRuleCompo if (!TryGetRandomStation(out var station)) return; - var validLockers = new List<(EntityUid, EntityStorageComponent, TransformComponent)>(); + var validLockers = new List<(EntityUid, EntityStorageComponent)>(); + var spawn = Spawn(comp.Prototype, MapCoordinates.Nullspace); var query = EntityQueryEnumerator(); while (query.MoveNext(out var ent, out var storage, out var xform)) @@ -25,17 +27,19 @@ protected override void Started(EntityUid uid, RandomEntityStorageSpawnRuleCompo if (StationSystem.GetOwningStation(ent, xform) != station) continue; - if (!_entityStorage.CanInsert(ent, storage) || storage.Open) + if (!_entityStorage.CanInsert(spawn, ent, storage)) continue; - validLockers.Add((ent, storage, xform)); + validLockers.Add((ent, storage)); } if (validLockers.Count == 0) + { + Del(spawn); return; + } - var (locker, storageComp, xformComp) = RobustRandom.Pick(validLockers); - var spawn = Spawn(comp.Prototype, xformComp.Coordinates); + var (locker, storageComp) = RobustRandom.Pick(validLockers); if (!_entityStorage.Insert(spawn, locker, storageComp)) { Del(spawn); diff --git a/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs b/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs index a828c22d5b9..cbd4883b4cd 100644 --- a/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs @@ -128,7 +128,7 @@ public override void ReleaseGas(EntityUid uid, SharedEntityStorageComponent comp private TileRef? GetOffsetTileRef(EntityUid uid, EntityStorageComponent component) { - var targetCoordinates = new EntityCoordinates(uid, component.EnteringOffset).ToMap(EntityManager); + var targetCoordinates = new EntityCoordinates(uid, component.EnteringOffset).ToMap(EntityManager, TransformSystem); if (_map.TryFindGridAt(targetCoordinates, out _, out var grid)) { diff --git a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs index 67866e6e5a7..fcd42f5a288 100644 --- a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs +++ b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs @@ -110,7 +110,7 @@ private void TurnOff(EntityUid uid, EnergySwordComponent comp, ref EnergySwordDe { weaponComp.HitSound = comp.OnHitOff; if (comp.Secret) - weaponComp.HideFromExamine = true; + weaponComp.Hidden = true; } if (comp.IsSharp) @@ -135,7 +135,7 @@ private void TurnOn(EntityUid uid, EnergySwordComponent comp, ref EnergySwordAct { weaponComp.HitSound = comp.OnHitOn; if (comp.Secret) - weaponComp.HideFromExamine = false; + weaponComp.Hidden = false; } if (TryComp(uid, out var malus)) diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index c4fec25139f..a0a3f6d5d7b 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -8,11 +8,13 @@ using Content.Server.CombatMode.Disarm; using Content.Server.Contests; using Content.Server.Movement.Systems; -using Content.Shared.Administration.Components; using Content.Shared.Actions.Events; +using Content.Shared.Administration.Components; using Content.Shared.CombatMode; using Content.Shared.Damage.Events; +using Content.Shared.Damage.Systems; using Content.Shared.Database; +using Content.Shared.Effects; using Content.Shared.FixedPoint; using Content.Shared.Hands.Components; using Content.Shared.IdentityManagement; @@ -29,8 +31,6 @@ using Robust.Shared.Player; using Robust.Shared.Players; using Robust.Shared.Random; -using Content.Shared.Effects; -using Content.Shared.Damage.Systems; namespace Content.Server.Weapons.Melee; @@ -57,7 +57,7 @@ public override void Initialize() private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args) { - if (component.HideFromExamine) + if (component.Hidden) return; var damageSpec = GetDamage(uid, args.User, component); diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.Ballistic.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.Ballistic.cs index ef3127e39bf..a2990c20376 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.Ballistic.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.Ballistic.cs @@ -22,7 +22,7 @@ protected override void Cycle(EntityUid uid, BallisticAmmoProviderComponent comp else if (component.UnspawnedCount > 0) { component.UnspawnedCount--; - ent = Spawn(component.FillProto, coordinates); + ent = Spawn(component.Proto, coordinates); EnsureShootable(ent.Value); } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index 0acb20f5a24..0859cb94427 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -54,12 +54,12 @@ public override void Initialize() private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent component, ref PriceCalculationEvent args) { - if (string.IsNullOrEmpty(component.FillProto) || component.UnspawnedCount == 0) + if (string.IsNullOrEmpty(component.Proto) || component.UnspawnedCount == 0) return; - if (!ProtoManager.TryIndex(component.FillProto, out var proto)) + if (!ProtoManager.TryIndex(component.Proto, out var proto)) { - Log.Error($"Unable to find fill prototype for price on {component.FillProto} on {ToPrettyString(uid)}"); + Log.Error($"Unable to find fill prototype for price on {component.Proto} on {ToPrettyString(uid)}"); return; } diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs index 5da7c6e8cd7..3014edd1b9a 100644 --- a/Content.Server/Zombies/ZombieSystem.Transform.cs +++ b/Content.Server/Zombies/ZombieSystem.Transform.cs @@ -12,7 +12,6 @@ using Content.Server.NPC.Components; using Content.Server.NPC.HTN; using Content.Server.NPC.Systems; -using Content.Server.Nutrition.Components; using Content.Server.Roles; using Content.Server.Speech.Components; using Content.Server.Temperature.Components; @@ -32,6 +31,7 @@ using Content.Shared.Weapons.Melee; using Content.Shared.Zombies; using Robust.Shared.Audio; +using Content.Shared.Prying.Components; namespace Content.Server.Zombies { @@ -112,7 +112,7 @@ public void ZombifyEntity(EntityUid target, MobStateComponent? mobState = null) //This is the actual damage of the zombie. We assign the visual appearance //and range here because of stuff we'll find out later var melee = EnsureComp(target); - melee.ClickAnimation = zombiecomp.AttackAnimation; + melee.Animation = zombiecomp.AttackAnimation; melee.WideAnimation = zombiecomp.AttackAnimation; melee.Range = 1.2f; @@ -162,11 +162,12 @@ public void ZombifyEntity(EntityUid target, MobStateComponent? mobState = null) melee.Damage = dspec; // humanoid zombies get to pry open doors and shit - var tool = EnsureComp(target); - tool.SpeedModifier = 0.75f; - tool.Qualities = new ("Prying"); - tool.UseSound = new SoundPathSpecifier("/Audio/Items/crowbar.ogg"); - Dirty(tool); + var pryComp = EnsureComp(target); + pryComp.SpeedModifier = 0.75f; + pryComp.PryPowered = true; + pryComp.Force = true; + + Dirty(target, pryComp); } Dirty(melee); @@ -232,7 +233,7 @@ public void ZombifyEntity(EntityUid target, MobStateComponent? mobState = null) else { var htn = EnsureComp(target); - htn.RootTask = new HTNCompoundTask() {Task = "SimpleHostileCompound"}; + htn.RootTask = new HTNCompoundTask() { Task = "SimpleHostileCompound" }; htn.Blackboard.SetValue(NPCBlackboard.Owner, target); _npc.WakeNPC(target, htn); } diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 0d51da03ae8..1f8f5fbd42f 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -255,7 +255,7 @@ public bool UnZombify(EntityUid source, EntityUid target, ZombieComponent? zombi foreach (var (layer, info) in zombiecomp.BeforeZombifiedCustomBaseLayers) { _humanoidAppearance.SetBaseLayerColor(target, layer, info.Color); - _humanoidAppearance.SetBaseLayerId(target, layer, info.ID); + _humanoidAppearance.SetBaseLayerId(target, layer, info.Id); } if(TryComp(target, out var appcomp)) { diff --git a/Content.Shared/Access/Components/AccessComponent.cs b/Content.Shared/Access/Components/AccessComponent.cs index 35521d23db4..6930f2dfd60 100644 --- a/Content.Shared/Access/Components/AccessComponent.cs +++ b/Content.Shared/Access/Components/AccessComponent.cs @@ -22,14 +22,14 @@ public sealed partial class AccessComponent : Component [DataField("tags", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] [Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends - [AutoNetworkedField(true)] + [AutoNetworkedField] public HashSet Tags = new(); /// /// Access Groups. These are added to the tags during map init. After map init this will have no effect. /// [DataField("groups", readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] - [AutoNetworkedField(true)] + [AutoNetworkedField] public HashSet Groups = new(); } diff --git a/Content.Shared/Access/Components/AccessOverriderComponent.cs b/Content.Shared/Access/Components/AccessOverriderComponent.cs index 459cc24f0ca..92c09f1ab71 100644 --- a/Content.Shared/Access/Components/AccessOverriderComponent.cs +++ b/Content.Shared/Access/Components/AccessOverriderComponent.cs @@ -2,22 +2,22 @@ using Content.Shared.Containers.ItemSlots; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Access.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedAccessOverriderSystem))] public sealed partial class AccessOverriderComponent : Component { public static string PrivilegedIdCardSlotId = "AccessOverrider-privilegedId"; - [DataField("privilegedIdSlot")] + [DataField] public ItemSlot PrivilegedIdSlot = new(); [ViewVariables(VVAccess.ReadWrite)] - [DataField("denialSound")] + [DataField] public SoundSpecifier? DenialSound; public EntityUid TargetAccessReaderId = new(); @@ -33,12 +33,12 @@ public WriteToTargetAccessReaderIdMessage(List accessList) } } - [DataField("accessLevels", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List AccessLevels = new(); + [DataField, AutoNetworkedField] + public List> AccessLevels = new(); [ViewVariables(VVAccess.ReadWrite)] - [DataField("doAfter")] - public float DoAfterTime = 0f; + [DataField] + public float DoAfter; [Serializable, NetSerializable] public sealed class AccessOverriderBoundUserInterfaceState : BoundUserInterfaceState diff --git a/Content.Shared/Access/Components/IdCardConsoleComponent.cs b/Content.Shared/Access/Components/IdCardConsoleComponent.cs index 7edd9614f1d..51336a66255 100644 --- a/Content.Shared/Access/Components/IdCardConsoleComponent.cs +++ b/Content.Shared/Access/Components/IdCardConsoleComponent.cs @@ -1,12 +1,12 @@ using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Access.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedIdCardConsoleSystem))] public sealed partial class IdCardConsoleComponent : Component { @@ -16,10 +16,10 @@ public sealed partial class IdCardConsoleComponent : Component public static string PrivilegedIdCardSlotId = "IdCardConsole-privilegedId"; public static string TargetIdCardSlotId = "IdCardConsole-targetId"; - [DataField("privilegedIdSlot")] + [DataField] public ItemSlot PrivilegedIdSlot = new(); - [DataField("targetIdSlot")] + [DataField] public ItemSlot TargetIdSlot = new(); [Serializable, NetSerializable] @@ -41,8 +41,8 @@ public WriteToTargetIdMessage(string fullName, string jobTitle, List acc // Put this on shared so we just send the state once in PVS range rather than every time the UI updates. - [DataField("accessLevels", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List AccessLevels = new() + [DataField, AutoNetworkedField] + public List> AccessLevels = new() { "Armory", "Atmospherics", diff --git a/Content.Shared/Access/Systems/SharedAccessOverriderSystem.cs b/Content.Shared/Access/Systems/SharedAccessOverriderSystem.cs index c19fe697e6c..36c74ed0dd8 100644 --- a/Content.Shared/Access/Systems/SharedAccessOverriderSystem.cs +++ b/Content.Shared/Access/Systems/SharedAccessOverriderSystem.cs @@ -2,7 +2,6 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.DoAfter; using JetBrains.Annotations; -using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.Access.Systems @@ -23,19 +22,6 @@ public override void Initialize() SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnComponentRemove); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnHandleState(EntityUid uid, AccessOverriderComponent component, ref ComponentHandleState args) - { - if (args.Current is not AccessOverriderComponentState state) return; - component.AccessLevels = state.AccessLevels; - } - - private void OnGetState(EntityUid uid, AccessOverriderComponent component, ref ComponentGetState args) - { - args.State = new AccessOverriderComponentState(component.AccessLevels); } private void OnComponentInit(EntityUid uid, AccessOverriderComponent component, ComponentInit args) @@ -48,17 +34,6 @@ private void OnComponentRemove(EntityUid uid, AccessOverriderComponent component _itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot); } - [Serializable, NetSerializable] - private sealed class AccessOverriderComponentState : ComponentState - { - public List AccessLevels; - - public AccessOverriderComponentState(List accessLevels) - { - AccessLevels = accessLevels; - } - } - [Serializable, NetSerializable] public sealed partial class AccessOverriderDoAfterEvent : DoAfterEvent { diff --git a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs index 9abb91de473..12e25e1e229 100644 --- a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs +++ b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs @@ -1,8 +1,6 @@ using Content.Shared.Access.Components; using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Access.Systems { @@ -22,19 +20,6 @@ public override void Initialize() SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnComponentRemove); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnHandleState(EntityUid uid, IdCardConsoleComponent component, ref ComponentHandleState args) - { - if (args.Current is not IdCardConsoleComponentState state) return; - component.AccessLevels = state.AccessLevels; - } - - private void OnGetState(EntityUid uid, IdCardConsoleComponent component, ref ComponentGetState args) - { - args.State = new IdCardConsoleComponentState(component.AccessLevels); } private void OnComponentInit(EntityUid uid, IdCardConsoleComponent component, ComponentInit args) @@ -48,16 +33,5 @@ private void OnComponentRemove(EntityUid uid, IdCardConsoleComponent component, _itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot); _itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot); } - - [Serializable, NetSerializable] - private sealed class IdCardConsoleComponentState : ComponentState - { - public List AccessLevels; - - public IdCardConsoleComponentState(List accessLevels) - { - AccessLevels = accessLevels; - } - } } } diff --git a/Content.Shared/Alert/AlertsComponent.cs b/Content.Shared/Alert/AlertsComponent.cs index 4468db44638..05b11e19efb 100644 --- a/Content.Shared/Alert/AlertsComponent.cs +++ b/Content.Shared/Alert/AlertsComponent.cs @@ -6,11 +6,12 @@ namespace Content.Shared.Alert; /// Handles the icons on the right side of the screen. /// Should only be used for player-controlled entities. /// -[RegisterComponent] -[NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class AlertsComponent : Component { - [ViewVariables] public Dictionary Alerts = new(); + [ViewVariables] + [AutoNetworkedField] + public Dictionary Alerts = new(); public override bool SendOnlyToOwner => true; } diff --git a/Content.Shared/Alert/AlertsComponentState.cs b/Content.Shared/Alert/AlertsComponentState.cs deleted file mode 100644 index c503338ea84..00000000000 --- a/Content.Shared/Alert/AlertsComponentState.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Alert; - -[Serializable, NetSerializable] -public sealed class AlertsComponentState : ComponentState -{ - public Dictionary Alerts; - - public AlertsComponentState(Dictionary alerts) - { - Alerts = alerts; - } -} diff --git a/Content.Shared/Alert/AlertsSystem.cs b/Content.Shared/Alert/AlertsSystem.cs index 37c49a46ce8..db6911f12b2 100644 --- a/Content.Shared/Alert/AlertsSystem.cs +++ b/Content.Shared/Alert/AlertsSystem.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Content.Shared.Alert; @@ -170,7 +169,6 @@ public override void Initialize() SubscribeLocalEvent(HandleComponentStartup); SubscribeLocalEvent(HandleComponentShutdown); - SubscribeLocalEvent(ClientAlertsGetState); SubscribeNetworkEvent(HandleClickAlert); LoadPrototypes(); @@ -243,9 +241,4 @@ private void HandleClickAlert(ClickAlertEvent msg, EntitySessionEventArgs args) alert.OnClick?.AlertClicked(player.Value); } - - private static void ClientAlertsGetState(EntityUid uid, AlertsComponent component, ref ComponentGetState args) - { - args.State = new AlertsComponentState(component.Alerts); - } } diff --git a/Content.Shared/Anomaly/Components/AnomalyComponent.cs b/Content.Shared/Anomaly/Components/AnomalyComponent.cs index e1e15561f81..07fc603e26f 100644 --- a/Content.Shared/Anomaly/Components/AnomalyComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalyComponent.cs @@ -2,7 +2,6 @@ using Content.Shared.Damage; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Anomaly.Components; @@ -14,7 +13,8 @@ namespace Content.Shared.Anomaly.Components; /// /// Anomalies and their related components were designed here: https://hackmd.io/@ss14-design/r1sQbkJOs /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedAnomalySystem))] public sealed partial class AnomalyComponent : Component { /// @@ -27,7 +27,7 @@ public sealed partial class AnomalyComponent : Component /// Note that this doesn't refer to stability as a percentage: This is an arbitrary /// value that only matters in relation to the and /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float Stability = 0f; /// @@ -39,7 +39,7 @@ public sealed partial class AnomalyComponent : Component /// /// Wacky-Stability scale lives on in my heart. - emo /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float Severity = 0f; #region Health @@ -49,7 +49,7 @@ public sealed partial class AnomalyComponent : Component /// When the health of an anomaly reaches 0, it is destroyed without ever /// reaching a supercritical point. /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float Health = 1f; /// @@ -85,25 +85,26 @@ public sealed partial class AnomalyComponent : Component /// /// The time at which the next artifact pulse will occur. /// - [DataField("nextPulseTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public TimeSpan NextPulseTime = TimeSpan.Zero; /// /// The minimum interval between pulses. /// - [DataField("minPulseLength")] + [DataField] public TimeSpan MinPulseLength = TimeSpan.FromMinutes(1); /// /// The maximum interval between pulses. /// - [DataField("maxPulseLength")] + [DataField] public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(2); /// /// A percentage by which the length of a pulse might vary. /// - [DataField("pulseVariation")] + [DataField] public float PulseVariation = 0.1f; /// @@ -112,19 +113,19 @@ public sealed partial class AnomalyComponent : Component /// /// This is more likely to trend upwards than donwards, because that's funny /// - [DataField("pulseStabilityVariation")] + [DataField] public Vector2 PulseStabilityVariation = new(-0.1f, 0.15f); /// /// The sound played when an anomaly pulses /// - [DataField("pulseSound")] + [DataField] public SoundSpecifier? PulseSound = new SoundCollectionSpecifier("RadiationPulse"); /// /// The sound plays when an anomaly goes supercritical /// - [DataField("supercriticalSound")] + [DataField] public SoundSpecifier? SupercriticalSound = new SoundCollectionSpecifier("explosion"); #endregion @@ -134,7 +135,7 @@ public sealed partial class AnomalyComponent : Component /// /// +/- 0.2 from perfect stability (0.5) /// - [DataField("initialStabilityRange")] + [DataField] public (float, float) InitialStabilityRange = (0.4f, 0.6f); /// @@ -143,25 +144,25 @@ public sealed partial class AnomalyComponent : Component /// /// Between 0 and 0.5, which should be all mild effects /// - [DataField("initialSeverityRange")] + [DataField] public (float, float) InitialSeverityRange = (0.1f, 0.5f); /// /// The particle type that increases the severity of the anomaly. /// - [DataField("severityParticleType")] + [DataField] public AnomalousParticleType SeverityParticleType; /// /// The particle type that destabilizes the anomaly. /// - [DataField("destabilizingParticleType")] + [DataField] public AnomalousParticleType DestabilizingParticleType; /// /// The particle type that weakens the anomalys health. /// - [DataField("weakeningParticleType")] + [DataField] public AnomalousParticleType WeakeningParticleType; #region Points and Vessels @@ -197,14 +198,14 @@ public sealed partial class AnomalyComponent : Component /// The amount of damage dealt when either a player touches the anomaly /// directly or by hitting the anomaly. /// - [DataField("anomalyContactDamage", required: true)] + [DataField(required: true)] public DamageSpecifier AnomalyContactDamage = default!; /// /// The sound effect played when a player /// burns themselves on an anomaly via contact. /// - [DataField("anomalyContactDamageSound")] + [DataField] public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg"); #region Floating Animation @@ -226,23 +227,6 @@ public sealed partial class AnomalyComponent : Component #endregion } -[Serializable, NetSerializable] -public sealed class AnomalyComponentState : ComponentState -{ - public float Severity; - public float Stability; - public float Health; - public TimeSpan NextPulseTime; - - public AnomalyComponentState(float severity, float stability, float health, TimeSpan nextPulseTime) - { - Severity = severity; - Stability = stability; - Health = health; - NextPulseTime = nextPulseTime; - } -} - /// /// Event raised at regular intervals on an anomaly to do whatever its effect is. /// diff --git a/Content.Shared/Anomaly/Components/AnomalySupercriticalComponent.cs b/Content.Shared/Anomaly/Components/AnomalySupercriticalComponent.cs index e5101fef667..bd8f40852d8 100644 --- a/Content.Shared/Anomaly/Components/AnomalySupercriticalComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalySupercriticalComponent.cs @@ -1,5 +1,4 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Anomaly.Components; @@ -7,31 +6,27 @@ namespace Content.Shared.Anomaly.Components; /// /// Tracks anomalies going supercritical /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedAnomalySystem))] public sealed partial class AnomalySupercriticalComponent : Component { /// /// The time when the supercritical animation ends and it does whatever effect. /// - [DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public TimeSpan EndTime; /// /// The length of the animation before it goes supercritical. /// + [AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite)] public TimeSpan SupercriticalDuration = TimeSpan.FromSeconds(10); /// /// The maximum size the anomaly scales to while going supercritical /// - [DataField("maxScaleAmount")] + [DataField] public float MaxScaleAmount = 3; } - -[Serializable, NetSerializable] -public sealed class AnomalySupercriticalComponentState : ComponentState -{ - public TimeSpan EndTime; - public TimeSpan Duration; -} diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 12a97fda42a..4b2b3ada70a 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Weapons.Melee.Events; -using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -30,10 +29,6 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnAnomalyGetState); - SubscribeLocalEvent(OnAnomalyHandleState); - SubscribeLocalEvent(OnSupercriticalGetState); - SubscribeLocalEvent(OnSupercriticalHandleState); SubscribeLocalEvent(OnInteractHand); SubscribeLocalEvent(OnAttacked); @@ -44,43 +39,6 @@ public override void Initialize() _sawmill = Logger.GetSawmill("anomaly"); } - private void OnAnomalyGetState(EntityUid uid, AnomalyComponent component, ref ComponentGetState args) - { - args.State = new AnomalyComponentState( - component.Severity, - component.Stability, - component.Health, - component.NextPulseTime); - } - - private void OnAnomalyHandleState(EntityUid uid, AnomalyComponent component, ref ComponentHandleState args) - { - if (args.Current is not AnomalyComponentState state) - return; - component.Severity = state.Severity; - component.Stability = state.Stability; - component.Health = state.Health; - component.NextPulseTime = state.NextPulseTime; - } - - private void OnSupercriticalGetState(EntityUid uid, AnomalySupercriticalComponent component, ref ComponentGetState args) - { - args.State = new AnomalySupercriticalComponentState - { - EndTime = component.EndTime, - Duration = component.SupercriticalDuration - }; - } - - private void OnSupercriticalHandleState(EntityUid uid, AnomalySupercriticalComponent component, ref ComponentHandleState args) - { - if (args.Current is not AnomalySupercriticalComponentState state) - return; - - component.EndTime = state.EndTime; - component.SupercriticalDuration = state.Duration; - } - private void OnInteractHand(EntityUid uid, AnomalyComponent component, InteractHandEvent args) { DoAnomalyBurnDamage(uid, args.User, component); diff --git a/Content.Shared/Armor/ArmorComponent.cs b/Content.Shared/Armor/ArmorComponent.cs new file mode 100644 index 00000000000..a1bb75923f7 --- /dev/null +++ b/Content.Shared/Armor/ArmorComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Utility; + +namespace Content.Shared.Armor; + +/// +/// Used for clothing that reduces damage when worn. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SharedArmorSystem))] +public sealed partial class ArmorComponent : Component +{ + /// + /// The damage reduction + /// + [DataField(required: true)] + public DamageModifierSet Modifiers = default!; +} + +/// +/// Event raised on an armor entity to get additional examine text relating to its armor. +/// +/// +[ByRefEvent] +public record struct ArmorExamineEvent(FormattedMessage Msg); diff --git a/Content.Shared/Armor/SharedArmorSystem.cs b/Content.Shared/Armor/SharedArmorSystem.cs new file mode 100644 index 00000000000..89141fcbd3d --- /dev/null +++ b/Content.Shared/Armor/SharedArmorSystem.cs @@ -0,0 +1,78 @@ +using Content.Shared.Damage; +using Content.Shared.Examine; +using Content.Shared.Inventory; +using Content.Shared.Silicons.Borgs; +using Content.Shared.Verbs; +using Robust.Shared.Utility; + +namespace Content.Shared.Armor; + +/// +/// This handles logic relating to +/// +public abstract class SharedArmorSystem : EntitySystem +{ + [Dependency] private readonly ExamineSystemShared _examine = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnDamageModify); + SubscribeLocalEvent>(OnBorgDamageModify); + SubscribeLocalEvent>(OnArmorVerbExamine); + } + + private void OnDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent args) + { + args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); + } + + private void OnBorgDamageModify(EntityUid uid, ArmorComponent component, ref BorgModuleRelayedEvent args) + { + args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); + } + + private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + var examineMarkup = GetArmorExamine(component.Modifiers); + + var ev = new ArmorExamineEvent(examineMarkup); + RaiseLocalEvent(uid, ref ev); + + _examine.AddDetailedExamineVerb(args, component, examineMarkup, + Loc.GetString("armor-examinable-verb-text"), "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", + Loc.GetString("armor-examinable-verb-message")); + } + + private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers) + { + var msg = new FormattedMessage(); + + msg.AddMarkup(Loc.GetString("armor-examine")); + + foreach (var coefficientArmor in armorModifiers.Coefficients) + { + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("armor-coefficient-value", + ("type", coefficientArmor.Key), + ("value", MathF.Round((1f - coefficientArmor.Value) * 100,1)) + )); + } + + foreach (var flatArmor in armorModifiers.FlatReduction) + { + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("armor-reduction-value", + ("type", flatArmor.Key), + ("value", flatArmor.Value) + )); + } + + return msg; + } +} diff --git a/Content.Shared/Atmos/Piping/Binary/Visuals/GasVolumePumpVisuals.cs b/Content.Shared/Atmos/Piping/Binary/Visuals/GasVolumePumpVisuals.cs new file mode 100644 index 00000000000..1cc73e9038d --- /dev/null +++ b/Content.Shared/Atmos/Piping/Binary/Visuals/GasVolumePumpVisuals.cs @@ -0,0 +1,18 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos.Visuals +{ + [Serializable, NetSerializable] + public enum GasVolumePumpVisuals : byte + { + State, + } + + [Serializable, NetSerializable] + public enum GasVolumePumpState : byte + { + Off, + On, + Blocked, + } +} diff --git a/Content.Shared/BarSign/BarSignComponent.cs b/Content.Shared/BarSign/BarSignComponent.cs index 182597ba2e6..d50726216e6 100644 --- a/Content.Shared/BarSign/BarSignComponent.cs +++ b/Content.Shared/BarSign/BarSignComponent.cs @@ -1,24 +1,10 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Prototypes; -namespace Content.Shared.BarSign -{ - [RegisterComponent, NetworkedComponent] - public sealed partial class BarSignComponent : Component - { - [DataField("current", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string? CurrentSign; - } - - [Serializable, NetSerializable] - public sealed class BarSignComponentState : ComponentState - { - public string? CurrentSign; +namespace Content.Shared.BarSign; - public BarSignComponentState(string? current) - { - CurrentSign = current; - } - } +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class BarSignComponent : Component +{ + [DataField, AutoNetworkedField] public ProtoId? Current; } diff --git a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs index ce6ae4795cd..2ac1c372ca6 100644 --- a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs +++ b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.Actions; using Content.Shared.Bed.Sleep; +using Content.Shared.Damage.ForceSay; using Content.Shared.Eye.Blinding.Systems; using Content.Shared.Speech; using Robust.Shared.Network; @@ -54,6 +55,13 @@ private void OnShutdown(EntityUid uid, SleepingComponent component, ComponentShu private void OnSpeakAttempt(EntityUid uid, SleepingComponent component, SpeakAttemptEvent args) { + // TODO reduce duplication of this behavior with MobStateSystem somehow + if (HasComp(uid)) + { + RemCompDeferred(uid); + return; + } + args.Cancel(); } diff --git a/Content.Shared/Body/Components/BodyComponent.cs b/Content.Shared/Body/Components/BodyComponent.cs index a93f1e2fd80..481e22150b0 100644 --- a/Content.Shared/Body/Components/BodyComponent.cs +++ b/Content.Shared/Body/Components/BodyComponent.cs @@ -4,18 +4,17 @@ using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; namespace Content.Shared.Body.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedBodySystem))] public sealed partial class BodyComponent : Component { /// /// Relevant template to spawn for this body. /// - [DataField] + [DataField, AutoNetworkedField] public ProtoId? Prototype; /// @@ -29,35 +28,17 @@ public sealed partial class BodyComponent : Component [ViewVariables] public string RootPartSlot => RootContainer.ID; - [DataField] public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib"); + [DataField, AutoNetworkedField] + public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib"); /// /// The amount of legs required to move at full speed. /// If 0, then legs do not impact speed. /// - [DataField] public int RequiredLegs; + [DataField, AutoNetworkedField] + public int RequiredLegs; [ViewVariables] - [DataField] + [DataField, AutoNetworkedField] public HashSet LegEntities = new(); } - -[Serializable, NetSerializable] -public sealed class BodyComponentState : ComponentState -{ - public string? Prototype; - public string? RootPartSlot; - public SoundSpecifier GibSound; - public int RequiredLegs; - public HashSet LegNetEntities; - - public BodyComponentState(string? prototype, string? rootPartSlot, SoundSpecifier gibSound, - int requiredLegs, HashSet legNetEntities) - { - Prototype = prototype; - RootPartSlot = rootPartSlot; - GibSound = gibSound; - RequiredLegs = requiredLegs; - LegNetEntities = legNetEntities; - } -} diff --git a/Content.Shared/Body/Events/MechanismBodyEvents.cs b/Content.Shared/Body/Events/MechanismBodyEvents.cs index 917d687a0fa..b52a333613f 100644 --- a/Content.Shared/Body/Events/MechanismBodyEvents.cs +++ b/Content.Shared/Body/Events/MechanismBodyEvents.cs @@ -3,19 +3,6 @@ // All of these events are raised on a mechanism entity when added/removed to a body in different // ways. - /// - /// Raised on a mechanism when it is added to a body. - /// - public sealed class AddedToBodyEvent : EntityEventArgs - { - public EntityUid Body; - - public AddedToBodyEvent(EntityUid body) - { - Body = body; - } - } - /// /// Raised on a mechanism when it is added to a body part. /// @@ -44,29 +31,16 @@ public AddedToPartInBodyEvent(EntityUid body, EntityUid part) } } - /// - /// Raised on a mechanism when it is removed from a body. - /// - public sealed class RemovedFromBodyEvent : EntityEventArgs - { - public EntityUid Old; - - public RemovedFromBodyEvent(EntityUid old) - { - Old = old; - } - } - /// /// Raised on a mechanism when it is removed from a body part. /// public sealed class RemovedFromPartEvent : EntityEventArgs { - public EntityUid Old; + public EntityUid OldPart; - public RemovedFromPartEvent(EntityUid old) + public RemovedFromPartEvent(EntityUid oldPart) { - Old = old; + OldPart = oldPart; } } diff --git a/Content.Shared/Body/Part/BodyPartComponent.cs b/Content.Shared/Body/Part/BodyPartComponent.cs index cbbfef4d73e..4f838d98983 100644 --- a/Content.Shared/Body/Part/BodyPartComponent.cs +++ b/Content.Shared/Body/Part/BodyPartComponent.cs @@ -34,13 +34,13 @@ public sealed partial class BodyPartComponent : Component /// /// Child body parts attached to this body part. /// - [DataField, AutoNetworkedField(CloneData = true)] + [DataField, AutoNetworkedField] public Dictionary Children = new(); /// /// Organs attached to this body part. /// - [DataField, AutoNetworkedField(CloneData = true)] + [DataField, AutoNetworkedField] public Dictionary Organs = new(); /// diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index 9356224f412..9cdeb8dcfad 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -6,9 +6,7 @@ using Content.Shared.Body.Prototypes; using Content.Shared.DragDrop; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Map; -using MapInitEvent = Robust.Shared.GameObjects.MapInitEvent; namespace Content.Shared.Body.Systems; @@ -30,8 +28,6 @@ private void InitializeBody() SubscribeLocalEvent(OnBodyInit); SubscribeLocalEvent(OnBodyMapInit); SubscribeLocalEvent(OnBodyCanDrag); - SubscribeLocalEvent(OnBodyGetState); - SubscribeLocalEvent(OnBodyHandleState); } private void OnBodyInserted(EntityUid uid, BodyComponent component, EntInsertedIntoContainerMessage args) @@ -78,32 +74,10 @@ private void OnBodyRemoved(EntityUid uid, BodyComponent component, EntRemovedFro if (TryComp(entity, out OrganComponent? organ)) { - RemoveOrgan(entity, uid, uid, organ); + RemoveOrgan(entity, uid, organ); } } - private void OnBodyHandleState(EntityUid uid, BodyComponent component, ref ComponentHandleState args) - { - if (args.Current is not BodyComponentState state) - return; - - component.Prototype = state.Prototype != null ? state.Prototype : null!; - component.GibSound = state.GibSound; - component.RequiredLegs = state.RequiredLegs; - component.LegEntities = EntityManager.EnsureEntitySet(state.LegNetEntities, uid); - } - - private void OnBodyGetState(EntityUid uid, BodyComponent component, ref ComponentGetState args) - { - args.State = new BodyComponentState( - component.Prototype, - component.RootPartSlot, - component.GibSound, - component.RequiredLegs, - EntityManager.GetNetEntitySet(component.LegEntities) - ); - } - private void OnBodyInit(EntityUid bodyId, BodyComponent body, ComponentInit args) { // Setup the initial container. diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs index 7ee39da00ba..d2a7b7256ae 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs @@ -12,7 +12,7 @@ public partial class SharedBodySystem private void AddOrgan(EntityUid uid, EntityUid bodyUid, EntityUid parentPartUid, OrganComponent component) { component.Body = bodyUid; - RaiseLocalEvent(uid, new AddedToPartEvent(bodyUid)); + RaiseLocalEvent(uid, new AddedToPartEvent(parentPartUid)); if (component.Body != null) RaiseLocalEvent(uid, new AddedToPartInBodyEvent(component.Body.Value, parentPartUid)); @@ -20,12 +20,14 @@ private void AddOrgan(EntityUid uid, EntityUid bodyUid, EntityUid parentPartUid, Dirty(uid, component); } - private void RemoveOrgan(EntityUid uid, EntityUid bodyUid, EntityUid parentPartUid, OrganComponent component) + private void RemoveOrgan(EntityUid uid, EntityUid parentPartUid, OrganComponent component) { - RaiseLocalEvent(uid, new RemovedFromPartEvent(bodyUid)); + RaiseLocalEvent(uid, new RemovedFromPartEvent(parentPartUid)); if (component.Body != null) + { RaiseLocalEvent(uid, new RemovedFromPartInBodyEvent(component.Body.Value, parentPartUid)); + } component.Body = null; Dirty(uid, component); diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index 2d96c148637..d2ec8c7f18e 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.Body.Components; +using Content.Shared.Body.Events; using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Content.Shared.Damage; @@ -61,7 +62,7 @@ private void OnBodyPartRemoved(EntityUid uid, BodyPartComponent component, EntRe if (TryComp(entity, out OrganComponent? organ)) { - RemoveOrgan(entity, organ); + RemoveOrgan(entity, uid, organ); } } @@ -85,7 +86,20 @@ private void RecursiveBodyUpdate(EntityUid uid, EntityUid? bodyUid, BodyPartComp { if (TryComp(organ, out OrganComponent? organComp)) { + var oldBody = organComp.Body; organComp.Body = bodyUid; + + if (bodyUid != null) + { + var ev = new AddedToPartInBodyEvent(bodyUid.Value, children.Id); + RaiseLocalEvent(organ, ev); + } + else if (oldBody != null) + { + var ev = new RemovedFromPartInBodyEvent(oldBody.Value, children.Id); + RaiseLocalEvent(organ, ev); + } + Dirty(organ, organComp); } } diff --git a/Content.Shared/Buckle/Components/BuckleComponent.cs b/Content.Shared/Buckle/Components/BuckleComponent.cs index 8f44c7fead3..cf28b56d51f 100644 --- a/Content.Shared/Buckle/Components/BuckleComponent.cs +++ b/Content.Shared/Buckle/Components/BuckleComponent.cs @@ -4,7 +4,7 @@ namespace Content.Shared.Buckle.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] [Access(typeof(SharedBuckleSystem))] public sealed partial class BuckleComponent : Component { @@ -13,7 +13,7 @@ public sealed partial class BuckleComponent : Component /// Separated from normal interaction range to fix the "someone buckled to a strap /// across a table two tiles away" problem. /// - [DataField("range")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public float Range = SharedInteractionSystem.InteractionRange / 1.4f; @@ -21,32 +21,34 @@ public sealed partial class BuckleComponent : Component /// True if the entity is buckled, false otherwise. /// [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] public bool Buckled; [ViewVariables] + [AutoNetworkedField] public EntityUid? LastEntityBuckledTo; /// /// Whether or not collisions should be possible with the entity we are strapped to /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("dontCollide")] + [DataField, AutoNetworkedField] public bool DontCollide; /// /// Whether or not we should be allowed to pull the entity we are strapped to /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("pullStrap")] + [DataField] public bool PullStrap; /// /// The amount of time that must pass for this entity to /// be able to unbuckle after recently buckling. /// - [DataField("delay")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] - public TimeSpan UnbuckleDelay = TimeSpan.FromSeconds(0.25f); + public TimeSpan Delay = TimeSpan.FromSeconds(0.25f); /// /// The time that this entity buckled at. @@ -58,39 +60,21 @@ public sealed partial class BuckleComponent : Component /// The strap that this component is buckled to. /// [ViewVariables] + [AutoNetworkedField] public EntityUid? BuckledTo; /// /// The amount of space that this entity occupies in a /// . /// - [DataField("size")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public int Size = 100; /// /// Used for client rendering /// - [ViewVariables] - public int? OriginalDrawDepth; -} - -[Serializable, NetSerializable] -public sealed class BuckleComponentState : ComponentState -{ - public BuckleComponentState(bool buckled, NetEntity? buckledTo, NetEntity? lastEntityBuckledTo, - bool dontCollide) - { - Buckled = buckled; - BuckledTo = buckledTo; - LastEntityBuckledTo = lastEntityBuckledTo; - DontCollide = dontCollide; - } - - public readonly bool Buckled; - public readonly NetEntity? BuckledTo; - public readonly NetEntity? LastEntityBuckledTo; - public readonly bool DontCollide; + [ViewVariables] public int? OriginalDrawDepth; } [ByRefEvent] diff --git a/Content.Shared/Buckle/Components/StrapComponent.cs b/Content.Shared/Buckle/Components/StrapComponent.cs index 8cb11ddd435..46f260741a7 100644 --- a/Content.Shared/Buckle/Components/StrapComponent.cs +++ b/Content.Shared/Buckle/Components/StrapComponent.cs @@ -8,28 +8,29 @@ namespace Content.Shared.Buckle.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedBuckleSystem), typeof(SharedVehicleSystem))] public sealed partial class StrapComponent : Component { /// /// The entities that are currently buckled /// + [AutoNetworkedField] [ViewVariables] // TODO serialization - public readonly HashSet BuckledEntities = new(); + public HashSet BuckledEntities = new(); /// /// Entities that this strap accepts and can buckle /// If null it accepts any entity /// - [DataField("allowedEntities")] + [DataField] [ViewVariables] public EntityWhitelist? AllowedEntities; /// /// The change in position to the strapped mob /// - [DataField("position")] + [DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite)] public StrapPosition Position = StrapPosition.None; @@ -43,7 +44,7 @@ public sealed partial class StrapComponent : Component /// whereas the server doesnt, thus the client tries to unbuckle like 15 times because it passes the strap null check /// This is why this needs to be above 0.1 to make the InRange check fail in both client and server. /// - [DataField("maxBuckleDistance", required: false)] + [DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite)] public float MaxBuckleDistance = 0.2f; @@ -51,8 +52,8 @@ public sealed partial class StrapComponent : Component /// Gets and clamps the buckle offset to MaxBuckleDistance /// [ViewVariables] - public Vector2 BuckleOffset => Vector2.Clamp( - BuckleOffsetUnclamped, + public Vector2 BuckleOffsetClamped => Vector2.Clamp( + BuckleOffset, Vector2.One * -MaxBuckleDistance, Vector2.One * MaxBuckleDistance); @@ -60,21 +61,21 @@ public sealed partial class StrapComponent : Component /// The buckled entity will be offset by this amount from the center of the strap object. /// If this offset it too big, it will be clamped to /// - [DataField("buckleOffset", required: false)] + [DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite)] - public Vector2 BuckleOffsetUnclamped = Vector2.Zero; + public Vector2 BuckleOffset = Vector2.Zero; /// /// The angle in degrees to rotate the player by when they get strapped /// - [DataField("rotation")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public int Rotation; /// /// The size of the strap which is compared against when buckling entities /// - [DataField("size")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public int Size = 100; @@ -87,58 +88,39 @@ public sealed partial class StrapComponent : Component /// /// You can specify the offset the entity will have after unbuckling. /// - [DataField("unbuckleOffset", required: false)] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public Vector2 UnbuckleOffset = Vector2.Zero; /// /// The sound to be played when a mob is buckled /// - [DataField("buckleSound")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier BuckleSound = new SoundPathSpecifier("/Audio/Effects/buckle.ogg"); /// /// The sound to be played when a mob is unbuckled /// - [DataField("unbuckleSound")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier UnbuckleSound = new SoundPathSpecifier("/Audio/Effects/unbuckle.ogg"); /// /// ID of the alert to show when buckled /// - [DataField("buckledAlertType")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public AlertType BuckledAlertType = AlertType.Buckled; /// /// The sum of the sizes of all the buckled entities in this strap /// + [AutoNetworkedField] [ViewVariables] public int OccupiedSize; } -[Serializable, NetSerializable] -public sealed class StrapComponentState : ComponentState -{ - public readonly StrapPosition Position; - public readonly float MaxBuckleDistance; - public readonly Vector2 BuckleOffsetClamped; - public readonly HashSet BuckledEntities; - public readonly int OccupiedSize; - - public StrapComponentState(StrapPosition position, Vector2 offset, HashSet buckled, - float maxBuckleDistance, int occupiedSize) - { - Position = position; - BuckleOffsetClamped = offset; - BuckledEntities = buckled; - MaxBuckleDistance = maxBuckleDistance; - OccupiedSize = occupiedSize; - } -} - public enum StrapPosition { /// diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index 3fb77df97d7..020b47f7081 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -12,14 +12,12 @@ using Content.Shared.Movement.Events; using Content.Shared.Popups; using Content.Shared.Pulling.Components; -using Content.Shared.Pulling.Events; using Content.Shared.Standing; using Content.Shared.Storage.Components; using Content.Shared.Stunnable; using Content.Shared.Throwing; using Content.Shared.Vehicle.Components; using Content.Shared.Verbs; -using Robust.Shared.GameStates; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; using Robust.Shared.Utility; @@ -32,7 +30,6 @@ private void InitializeBuckle() { SubscribeLocalEvent(OnBuckleComponentStartup); SubscribeLocalEvent(OnBuckleComponentShutdown); - SubscribeLocalEvent(OnBuckleComponentGetState); SubscribeLocalEvent(OnBuckleMove); SubscribeLocalEvent(OnBuckleInteractHand); SubscribeLocalEvent>(AddUnbuckleVerb); @@ -58,11 +55,6 @@ private void OnBuckleComponentShutdown(EntityUid uid, BuckleComponent component, component.BuckleTime = default; } - private void OnBuckleComponentGetState(EntityUid uid, BuckleComponent component, ref ComponentGetState args) - { - args.State = new BuckleComponentState(component.Buckled, GetNetEntity(component.BuckledTo), GetNetEntity(component.LastEntityBuckledTo), component.DontCollide); - } - private void OnBuckleMove(EntityUid uid, BuckleComponent component, ref MoveEvent ev) { if (component.BuckledTo is not {} strapUid) @@ -434,7 +426,7 @@ public bool TryUnbuckle(EntityUid buckleUid, EntityUid userUid, bool force = fal if (attemptEvent.Cancelled) return false; - if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.UnbuckleDelay) + if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.Delay) return false; if (!_interaction.InRangeUnobstructed(userUid, strapUid, buckleComp.Range, popup: true)) diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Strap.cs b/Content.Shared/Buckle/SharedBuckleSystem.Strap.cs index 7ffbfd3a42b..8616546480b 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Strap.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Strap.cs @@ -7,7 +7,6 @@ using Content.Shared.Storage; using Content.Shared.Verbs; using Robust.Shared.Containers; -using Robust.Shared.GameStates; namespace Content.Shared.Buckle; @@ -19,9 +18,6 @@ private void InitializeStrap() SubscribeLocalEvent(OnStrapShutdown); SubscribeLocalEvent((_, c, _) => StrapRemoveAll(c)); - SubscribeLocalEvent(OnStrapGetState); - SubscribeLocalEvent(OnStrapHandleState); - SubscribeLocalEvent(OnStrapEntModifiedFromContainer); SubscribeLocalEvent(OnStrapEntModifiedFromContainer); SubscribeLocalEvent>(AddStrapVerbs); @@ -50,24 +46,6 @@ private void OnStrapShutdown(EntityUid uid, StrapComponent component, ComponentS StrapRemoveAll(component); } - private void OnStrapGetState(EntityUid uid, StrapComponent component, ref ComponentGetState args) - { - args.State = new StrapComponentState(component.Position, component.BuckleOffset, GetNetEntitySet(component.BuckledEntities), component.MaxBuckleDistance, component.OccupiedSize); - } - - private void OnStrapHandleState(EntityUid uid, StrapComponent component, ref ComponentHandleState args) - { - if (args.Current is not StrapComponentState state) - return; - - component.Position = state.Position; - component.BuckleOffsetUnclamped = state.BuckleOffsetClamped; - component.BuckledEntities.Clear(); - component.BuckledEntities.UnionWith(EnsureEntitySet(state.BuckledEntities, uid)); - component.MaxBuckleDistance = state.MaxBuckleDistance; - component.OccupiedSize = state.OccupiedSize; - } - private void OnStrapEntModifiedFromContainer(EntityUid uid, StrapComponent component, ContainerModifiedMessage message) { if (_gameTiming.ApplyingState) diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 3c9cb1f9744..81d479ca34c 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -65,7 +65,7 @@ private void ReAttach( || !Resolve(buckleUid, ref buckleComp, false)) return; - _transform.SetCoordinates(buckleUid, new EntityCoordinates(strapUid, strapComp.BuckleOffset)); + _transform.SetCoordinates(buckleUid, new EntityCoordinates(strapUid, strapComp.BuckleOffsetClamped)); var buckleTransform = Transform(buckleUid); diff --git a/Content.Shared/Cabinet/ItemCabinetComponent.cs b/Content.Shared/Cabinet/ItemCabinetComponent.cs index 4f49badfa99..71367e8de68 100644 --- a/Content.Shared/Cabinet/ItemCabinetComponent.cs +++ b/Content.Shared/Cabinet/ItemCabinetComponent.cs @@ -1,65 +1,43 @@ using Content.Shared.Containers.ItemSlots; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Cabinet; /// /// Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ItemCabinetComponent : Component { /// /// Sound to be played when the cabinet door is opened. /// - [DataField("doorSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier? DoorSound; /// /// The that stores the actual item. The entity whitelist, sounds, and other /// behaviours are specified by this definition. /// - [DataField("cabinetSlot"), ViewVariables] + [DataField, ViewVariables] public ItemSlot CabinetSlot = new(); /// /// Whether the cabinet is currently open or not. /// - [DataField("opened")] + [DataField, AutoNetworkedField] public bool Opened; /// /// The state for when the cabinet is open /// - [DataField("openState"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public string? OpenState; /// /// The state for when the cabinet is closed /// - [DataField("closedState"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public string? ClosedState; } - -[Serializable, NetSerializable] -public sealed class ItemCabinetComponentState : ComponentState -{ - public SoundSpecifier? DoorSound; - - public bool Opened; - - public string? OpenState; - - public string? ClosedState; - - public ItemCabinetComponentState(SoundSpecifier? doorSound, bool opened, string? openState, string? closedState) - { - DoorSound = doorSound; - Opened = opened; - OpenState = openState; - ClosedState = closedState; - } -} - diff --git a/Content.Shared/Cabinet/SharedItemCabinetSystem.cs b/Content.Shared/Cabinet/SharedItemCabinetSystem.cs index 96461f22497..f2f03c13349 100644 --- a/Content.Shared/Cabinet/SharedItemCabinetSystem.cs +++ b/Content.Shared/Cabinet/SharedItemCabinetSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.Verbs; using Robust.Shared.Audio; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -19,9 +18,6 @@ public abstract class SharedItemCabinetSystem : EntitySystem /// public override void Initialize() { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnComponentRemove); SubscribeLocalEvent(OnComponentStartup); @@ -35,24 +31,6 @@ public override void Initialize() SubscribeLocalEvent(OnLockToggleAttempt); } - private void OnGetState(EntityUid uid, ItemCabinetComponent component, ref ComponentGetState args) - { - args.State = new ItemCabinetComponentState(component.DoorSound, - component.Opened, - component.OpenState, - component.ClosedState); - } - - private void OnHandleState(EntityUid uid, ItemCabinetComponent component, ref ComponentHandleState args) - { - if (args.Current is not ItemCabinetComponentState state) - return; - component.DoorSound = state.DoorSound; - component.Opened = state.Opened; - component.OpenState = state.OpenState; - component.ClosedState = state.ClosedState; - } - private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args) { _itemSlots.AddItemSlot(uid, "ItemCabinet", cabinet.CabinetSlot); diff --git a/Content.Shared/CartridgeLoader/CartridgeComponent.cs b/Content.Shared/CartridgeLoader/CartridgeComponent.cs index 775cc33d810..ba7e6fe2d58 100644 --- a/Content.Shared/CartridgeLoader/CartridgeComponent.cs +++ b/Content.Shared/CartridgeLoader/CartridgeComponent.cs @@ -7,25 +7,19 @@ namespace Content.Shared.CartridgeLoader; /// /// This is used for defining values used for displaying in the program ui in yaml /// -[NetworkedComponent] -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class CartridgeComponent : Component { - [DataField("programName", required: true)] + [DataField(required: true)] public string ProgramName = "default-program-name"; - [DataField("icon")] + [DataField] public SpriteSpecifier? Icon; + [AutoNetworkedField] public InstallationStatus InstallationStatus = InstallationStatus.Cartridge; } -[Serializable, NetSerializable] -public sealed class CartridgeComponentState : ComponentState -{ - public InstallationStatus InstallationStatus; -} - [Serializable, NetSerializable] public enum InstallationStatus { diff --git a/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs b/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs index 15d29689b84..806723de1e6 100644 --- a/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs +++ b/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs @@ -1,7 +1,5 @@ using Content.Shared.Containers.ItemSlots; using Robust.Shared.Containers; -using Robust.Shared.GameStates; -using Robust.Shared.Map; using Robust.Shared.Network; namespace Content.Shared.CartridgeLoader; @@ -24,10 +22,6 @@ public override void Initialize() SubscribeLocalEvent(OnItemInserted); SubscribeLocalEvent(OnItemRemoved); - - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } private void OnComponentInit(EntityUid uid, CartridgeLoaderComponent loader, ComponentInit args) @@ -55,22 +49,6 @@ protected virtual void OnItemRemoved(EntityUid uid, CartridgeLoaderComponent loa UpdateAppearanceData(uid, loader); } - private void OnGetState(EntityUid uid, CartridgeComponent component, ref ComponentGetState args) - { - var state = new CartridgeComponentState(); - state.InstallationStatus = component.InstallationStatus; - - args.State = state; - } - - private void OnHandleState(EntityUid uid, CartridgeComponent component, ref ComponentHandleState args) - { - if (args.Current is not CartridgeComponentState state) - return; - - component.InstallationStatus = state.InstallationStatus; - } - private void UpdateAppearanceData(EntityUid uid, CartridgeLoaderComponent loader) { _appearanceSystem.SetData(uid, CartridgeLoaderVisuals.CartridgeInserted, loader.CartridgeSlot.HasItem); diff --git a/Content.Shared/Chemistry/Components/MovespeedModifierMetabolismComponent.cs b/Content.Shared/Chemistry/Components/MovespeedModifierMetabolismComponent.cs index f0a0c22ba57..62127ab5337 100644 --- a/Content.Shared/Chemistry/Components/MovespeedModifierMetabolismComponent.cs +++ b/Content.Shared/Chemistry/Components/MovespeedModifierMetabolismComponent.cs @@ -1,39 +1,22 @@ -using Robust.Shared.Serialization; using Robust.Shared.GameStates; namespace Content.Shared.Chemistry.Components { //TODO: refactor movement modifier component because this is a pretty poor solution - [RegisterComponent] - [NetworkedComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MovespeedModifierMetabolismComponent : Component { - [ViewVariables] + [AutoNetworkedField, ViewVariables] public float WalkSpeedModifier { get; set; } - [ViewVariables] + [AutoNetworkedField, ViewVariables] public float SprintSpeedModifier { get; set; } /// /// When the current modifier is expected to end. /// - [ViewVariables] + [AutoNetworkedField, ViewVariables] public TimeSpan ModifierTimer { get; set; } = TimeSpan.Zero; - - [Serializable, NetSerializable] - public sealed class MovespeedModifierMetabolismComponentState : ComponentState - { - public float WalkSpeedModifier { get; } - public float SprintSpeedModifier { get; } - public TimeSpan ModifierTimer { get; } - - public MovespeedModifierMetabolismComponentState(float walkSpeedModifier, float sprintSpeedModifier, TimeSpan modifierTimer) - { - WalkSpeedModifier = walkSpeedModifier; - SprintSpeedModifier = sprintSpeedModifier; - ModifierTimer = modifierTimer; - } - } } } diff --git a/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs b/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs index cfa7446caa5..6b7c75514fc 100644 --- a/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs +++ b/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs @@ -1,9 +1,6 @@ using Content.Shared.Chemistry.Components; -using Robust.Shared.GameStates; -using Robust.Shared.Timing; -using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; -using static Content.Shared.Chemistry.Components.MovespeedModifierMetabolismComponent; +using Robust.Shared.Timing; namespace Content.Shared.Chemistry { @@ -21,30 +18,10 @@ public override void Initialize() UpdatesOutsidePrediction = true; - SubscribeLocalEvent(OnMovespeedHandleState); - SubscribeLocalEvent(OnGetState); SubscribeLocalEvent(AddComponent); SubscribeLocalEvent(OnRefreshMovespeed); } - private void OnGetState(EntityUid uid, MovespeedModifierMetabolismComponent component, ref ComponentGetState args) - { - args.State = new MovespeedModifierMetabolismComponentState( - component.WalkSpeedModifier, - component.SprintSpeedModifier, - component.ModifierTimer); - } - - private void OnMovespeedHandleState(EntityUid uid, MovespeedModifierMetabolismComponent component, ref ComponentHandleState args) - { - if (args.Current is not MovespeedModifierMetabolismComponentState cast) - return; - - component.WalkSpeedModifier = cast.WalkSpeedModifier; - component.SprintSpeedModifier = cast.SprintSpeedModifier; - component.ModifierTimer = cast.ModifierTimer; - } - private void OnRefreshMovespeed(EntityUid uid, MovespeedModifierMetabolismComponent component, RefreshMovementSpeedModifiersEvent args) { args.ModifySpeed(component.WalkSpeedModifier, component.SprintSpeedModifier); diff --git a/Content.Shared/Climbing/ClimbingComponent.cs b/Content.Shared/Climbing/ClimbingComponent.cs index 40e192d8ef0..cd443af6aad 100644 --- a/Content.Shared/Climbing/ClimbingComponent.cs +++ b/Content.Shared/Climbing/ClimbingComponent.cs @@ -1,21 +1,20 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Climbing; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ClimbingComponent : Component { /// /// Whether the owner is climbing on a climbable entity. /// - [ViewVariables] + [ViewVariables, AutoNetworkedField] public bool IsClimbing { get; set; } /// /// Whether the owner is being moved onto the climbed entity. /// - [ViewVariables] + [ViewVariables, AutoNetworkedField] public bool OwnerIsTransitioning { get; set; } /// @@ -25,17 +24,4 @@ public sealed partial class ClimbingComponent : Component [ViewVariables] public Dictionary DisabledFixtureMasks { get; } = new(); - - [Serializable, NetSerializable] - public sealed class ClimbModeComponentState : ComponentState - { - public ClimbModeComponentState(bool climbing, bool isTransitioning) - { - Climbing = climbing; - IsTransitioning = isTransitioning; - } - - public bool Climbing { get; } - public bool IsTransitioning { get; } - } } diff --git a/Content.Shared/Clothing/Components/ChameleonClothingComponent.cs b/Content.Shared/Clothing/Components/ChameleonClothingComponent.cs index d2f2138670f..def4254304f 100644 --- a/Content.Shared/Clothing/Components/ChameleonClothingComponent.cs +++ b/Content.Shared/Clothing/Components/ChameleonClothingComponent.cs @@ -3,14 +3,13 @@ using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Clothing.Components; /// /// Allow players to change clothing sprite to any other clothing prototype. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] [Access(typeof(SharedChameleonClothingSystem))] public sealed partial class ChameleonClothingComponent : Component { @@ -18,15 +17,15 @@ public sealed partial class ChameleonClothingComponent : Component /// Filter possible chameleon options by their slot flag. /// [ViewVariables(VVAccess.ReadOnly)] - [DataField("slot", required: true)] + [DataField(required: true)] public SlotFlags Slot; /// /// EntityPrototype id that chameleon item is trying to mimic. /// [ViewVariables(VVAccess.ReadOnly)] - [DataField("default", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? SelectedId; + [DataField(required: true), AutoNetworkedField] + public EntProtoId? Default; /// /// Current user that wears chameleon clothing. @@ -35,12 +34,6 @@ public sealed partial class ChameleonClothingComponent : Component public EntityUid? User; } -[Serializable, NetSerializable] -public sealed class ChameleonClothingComponentState : ComponentState -{ - public string? SelectedId; -} - [Serializable, NetSerializable] public sealed class ChameleonBoundUserInterfaceState : BoundUserInterfaceState { diff --git a/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs index 34b48bc2926..beac22270c8 100644 --- a/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/SharedChameleonClothingSystem.cs @@ -38,8 +38,8 @@ private void OnGotUnequipped(EntityUid uid, ChameleonClothingComponent component // This 100% makes sure that server and client have exactly same data. protected void UpdateVisuals(EntityUid uid, ChameleonClothingComponent component) { - if (string.IsNullOrEmpty(component.SelectedId) || - !_proto.TryIndex(component.SelectedId, out EntityPrototype? proto)) + if (string.IsNullOrEmpty(component.Default) || + !_proto.TryIndex(component.Default, out EntityPrototype? proto)) return; // world sprite icon diff --git a/Content.Shared/Communications/CommsHackerComponent.cs b/Content.Shared/Communications/CommsHackerComponent.cs index fdd1876c1d7..810058f1ce5 100644 --- a/Content.Shared/Communications/CommsHackerComponent.cs +++ b/Content.Shared/Communications/CommsHackerComponent.cs @@ -29,8 +29,8 @@ public sealed partial class CommsHackerComponent : Component /// Generally some kind of mid-round minor antag, though you could make it call in scrubber backflow if you wanted to. /// You wouldn't do that, right? /// -[Prototype("threat")] -public sealed class ThreatPrototype : IPrototype +[Prototype("ninjaHackingThreat")] +public sealed class NinjaHackingThreatPrototype : IPrototype { [IdDataField] public string ID { get; private set; } = default!; @@ -38,12 +38,12 @@ public sealed class ThreatPrototype : IPrototype /// /// Locale id for the announcement to be made from CentCom. /// - [DataField] - public string Announcement = default!; + [DataField(required: true)] + public LocId Announcement; /// /// The game rule for the threat to be added, it should be able to work when added mid-round otherwise this will do nothing. /// - [DataField] - public EntProtoId Rule = default!; + [DataField(required: true)] + public EntProtoId Rule; } diff --git a/Content.Shared/Conveyor/ConveyorComponent.cs b/Content.Shared/Conveyor/ConveyorComponent.cs index 2af859b4a1d..6c95d68c982 100644 --- a/Content.Shared/Conveyor/ConveyorComponent.cs +++ b/Content.Shared/Conveyor/ConveyorComponent.cs @@ -1,66 +1,49 @@ using Content.Shared.DeviceLinking; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Conveyor; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ConveyorComponent : Component { /// /// The angle to move entities by in relation to the owner's rotation. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("angle")] + [DataField, AutoNetworkedField] public Angle Angle = Angle.Zero; /// /// The amount of units to move the entity by per second. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("speed")] + [DataField, AutoNetworkedField] public float Speed = 2f; /// /// The current state of this conveyor /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public ConveyorState State; - [ViewVariables] + [ViewVariables, AutoNetworkedField] public bool Powered; - [DataField("forwardPort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string ForwardPort = "Forward"; + [DataField] + public ProtoId ForwardPort = "Forward"; - [DataField("reversePort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string ReversePort = "Reverse"; + [DataField] + public ProtoId ReversePort = "Reverse"; - [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string OffPort = "Off"; + [DataField] + public ProtoId OffPort = "Off"; [ViewVariables] public readonly HashSet Intersecting = new(); } -[Serializable, NetSerializable] -public sealed class ConveyorComponentState : ComponentState -{ - public bool Powered; - public Angle Angle; - public float Speed; - public ConveyorState State; - - public ConveyorComponentState(Angle angle, float speed, ConveyorState state, bool powered) - { - Angle = angle; - Speed = speed; - State = state; - Powered = powered; - } -} - [Serializable, NetSerializable] public enum ConveyorVisuals : byte { diff --git a/Content.Shared/Cuffs/Components/HandcuffComponent.cs b/Content.Shared/Cuffs/Components/HandcuffComponent.cs index da44ee01ff7..b43bf18bf8f 100644 --- a/Content.Shared/Cuffs/Components/HandcuffComponent.cs +++ b/Content.Shared/Cuffs/Components/HandcuffComponent.cs @@ -2,53 +2,50 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Robust.Shared.Utility; namespace Content.Shared.Cuffs.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedCuffableSystem))] public sealed partial class HandcuffComponent : Component { /// /// The time it takes to cuff an entity. /// - [DataField("cuffTime"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float CuffTime = 3.5f; /// /// The time it takes to uncuff an entity. /// - [DataField("uncuffTime"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float UncuffTime = 3.5f; /// /// The time it takes for a cuffed entity to uncuff itself. /// - [DataField("breakoutTime"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float BreakoutTime = 30f; /// /// If an entity being cuffed is stunned, this amount of time is subtracted from the time it takes to add/remove their cuffs. /// - [DataField("stunBonus"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float StunBonus = 2f; /// /// Will the cuffs break when removed? /// - [DataField("breakOnRemove"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool BreakOnRemove; /// /// Will the cuffs break when removed? /// - [DataField("brokenPrototype", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)] - public string? BrokenPrototype; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public EntProtoId? BrokenPrototype; - [DataField("damageOnResist"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier DamageOnResist = new() { DamageDict = new() @@ -60,48 +57,37 @@ public sealed partial class HandcuffComponent : Component /// /// The path of the RSI file used for the player cuffed overlay. /// - [DataField("cuffedRSI"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public string? CuffedRSI = "Objects/Misc/handcuffs.rsi"; /// /// The iconstate used with the RSI file for the player cuffed overlay. /// - [DataField("bodyIconState"), ViewVariables(VVAccess.ReadWrite)] - public string? OverlayIconState = "body-overlay"; + [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public string? BodyIconState = "body-overlay"; /// - /// An opptional color specification for + /// An opptional color specification for /// - [DataField("color"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public Color Color = Color.White; - [DataField("startCuffSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier StartCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_start.ogg"); - [DataField("endCuffSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier EndCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_end.ogg"); - [DataField("startBreakoutSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier StartBreakoutSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_breakout_start.ogg"); - [DataField("startUncuffSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier StartUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_start.ogg"); - [DataField("endUncuffSound"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier EndUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_end.ogg"); } -[Serializable, NetSerializable] -public sealed class HandcuffComponentState : ComponentState -{ - public readonly string? IconState; - - public HandcuffComponentState(string? iconState) - { - IconState = iconState; - } -} - /// /// Event fired on the User when the User attempts to cuff the Target. /// Should generate popups on the User. diff --git a/Content.Shared/Damage/Components/StaminaComponent.cs b/Content.Shared/Damage/Components/StaminaComponent.cs index 3cdc90ecb1e..74e0f6c8529 100644 --- a/Content.Shared/Damage/Components/StaminaComponent.cs +++ b/Content.Shared/Damage/Components/StaminaComponent.cs @@ -6,48 +6,48 @@ namespace Content.Shared.Damage.Components; /// /// Add to an entity to paralyze it whenever it reaches critical amounts of Stamina DamageType. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class StaminaComponent : Component { /// /// Have we reached peak stamina damage and been paralyzed? /// - [ViewVariables(VVAccess.ReadWrite), DataField("critical")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public bool Critical; /// /// How much stamina reduces per second. /// - [ViewVariables(VVAccess.ReadWrite), DataField("decay")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float Decay = 3f; /// /// How much time after receiving damage until stamina starts decreasing. /// - [ViewVariables(VVAccess.ReadWrite), DataField("cooldown")] - public float DecayCooldown = 3f; + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public float Cooldown = 3f; /// /// How much stamina damage this entity has taken. /// - [ViewVariables(VVAccess.ReadWrite), DataField("staminaDamage")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float StaminaDamage; /// /// How much stamina damage is required to entire stam crit. /// - [ViewVariables(VVAccess.ReadWrite), DataField("critThreshold")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float CritThreshold = 100f; /// /// How long will this mob be stunned for? /// - [ViewVariables(VVAccess.ReadWrite), DataField("stunTime")] + [ViewVariables(VVAccess.ReadWrite), DataField] public TimeSpan StunTime = TimeSpan.FromSeconds(6); /// /// To avoid continuously updating our data we track the last time we updated so we can extrapolate our current stamina. /// - [DataField("nextUpdate", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] public TimeSpan NextUpdate = TimeSpan.Zero; } diff --git a/Content.Shared/Damage/ForceSay/AllowNextCritSpeechComponent.cs b/Content.Shared/Damage/ForceSay/AllowNextCritSpeechComponent.cs new file mode 100644 index 00000000000..66a57860b2e --- /dev/null +++ b/Content.Shared/Damage/ForceSay/AllowNextCritSpeechComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.Mobs.Components; +using Content.Shared.Mobs.Systems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Damage.ForceSay; + +/// +/// The reason for this component's existence is slightly unintuitive, so for context: this is put on an entity +/// to allow its next speech attempt to bypass checks. The reason for this is to allow +/// 'force saying'--for instance, with deathgasping or with . +/// +/// This component is either removed in the speech attempt check, or after +/// has passed. This is to allow a player-submitted forced message in the case of , +/// while also ensuring that it isn't valid forever. It has to work this way, because the server is not a keylogger and doesn't +/// have any knowledge of what the client might actually have typed, so it gives them some leeway for ping. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class AllowNextCritSpeechComponent : Component +{ + /// + /// Should be set when adding the component to specify the time that this should be valid for, + /// if it should stay valid for some amount of time. + /// + public TimeSpan? Timeout = null; +} diff --git a/Content.Shared/Damage/ForceSay/DamageForceSayComponent.cs b/Content.Shared/Damage/ForceSay/DamageForceSayComponent.cs new file mode 100644 index 00000000000..dc2617bc93e --- /dev/null +++ b/Content.Shared/Damage/ForceSay/DamageForceSayComponent.cs @@ -0,0 +1,66 @@ +using Content.Shared.Damage.Prototypes; +using Content.Shared.FixedPoint; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; + +namespace Content.Shared.Damage.ForceSay; + +/// +/// This is used for forcing clients to send messages with a suffix attached (like -GLORF) when taking large amounts +/// of damage, or things like entering crit or being stunned. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class DamageForceSayComponent : Component +{ + /// + /// The localization string that the message & suffix will be passed into + /// + [DataField] + public LocId ForceSayMessageWrap = "damage-force-say-message-wrap"; + + /// + /// Same as but for cases where no suffix is used, + /// such as when going into crit. + /// + [DataField] + public LocId ForceSayMessageWrapNoSuffix = "damage-force-say-message-wrap-no-suffix"; + + /// + /// The fluent string prefix to use when picking a random suffix + /// + [DataField] + public string ForceSayStringPrefix = "damage-force-say-"; + + /// + /// The number of suffixes that exist for use with . + /// i.e. (prefix)-1 through (prefix)-(count) + /// + [DataField] + public int ForceSayStringCount = 7; + + /// + /// The amount of total damage between that needs to be taken before + /// a force say occurs. + /// + [DataField] + public FixedPoint2 DamageThreshold = FixedPoint2.New(10); + + /// + /// A list of damage group types that are considered when checking . + /// + [DataField] + public HashSet>? ValidDamageGroups = new() + { + "Brute", + "Burn", + }; + + /// + /// The time enforced between force says to avoid spam. + /// + [DataField] + public TimeSpan Cooldown = TimeSpan.FromSeconds(5.0); + + public TimeSpan? NextAllowedTime = null; +} diff --git a/Content.Shared/Damage/ForceSay/DamageForceSayEvent.cs b/Content.Shared/Damage/ForceSay/DamageForceSayEvent.cs new file mode 100644 index 00000000000..a8ed9288a68 --- /dev/null +++ b/Content.Shared/Damage/ForceSay/DamageForceSayEvent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Damage.ForceSay; + +/// +/// Sent to clients as a network event when their entity contains +/// that COMMANDS them to speak the current message in their chatbox +/// +[Serializable, NetSerializable] +public sealed class DamageForceSayEvent : EntityEventArgs +{ + public string? Suffix; +} diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index 7bf2941dacf..40c4f7eb8f2 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -16,11 +16,9 @@ using Content.Shared.Weapons.Melee.Events; using JetBrains.Annotations; using Robust.Shared.Audio; -using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Player; using Robust.Shared.Random; -using Robust.Shared.Serialization; using Robust.Shared.Timing; namespace Content.Shared.Damage.Systems; @@ -52,8 +50,7 @@ public override void Initialize() SubscribeLocalEvent(OnStamUnpaused); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnStamGetState); - SubscribeLocalEvent(OnStamHandleState); + SubscribeLocalEvent(OnStamHandleState); SubscribeLocalEvent(OnDisarmed); SubscribeLocalEvent(OnRejuvenate); @@ -67,31 +64,8 @@ private void OnStamUnpaused(EntityUid uid, StaminaComponent component, ref Entit component.NextUpdate += args.PausedTime; } - private void OnStamGetState(EntityUid uid, StaminaComponent component, ref ComponentGetState args) + private void OnStamHandleState(EntityUid uid, StaminaComponent component, ref AfterAutoHandleStateEvent args) { - args.State = new StaminaComponentState() - { - Critical = component.Critical, - Decay = component.Decay, - CritThreshold = component.CritThreshold, - DecayCooldown = component.DecayCooldown, - LastUpdate = component.NextUpdate, - StaminaDamage = component.StaminaDamage, - }; - } - - private void OnStamHandleState(EntityUid uid, StaminaComponent component, ref ComponentHandleState args) - { - if (args.Current is not StaminaComponentState state) - return; - - component.Critical = state.Critical; - component.Decay = state.Decay; - component.CritThreshold = state.CritThreshold; - component.DecayCooldown = state.DecayCooldown; - component.NextUpdate = state.LastUpdate; - component.StaminaDamage = state.StaminaDamage; - if (component.Critical) EnterStamCrit(uid, component); else @@ -283,7 +257,7 @@ public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? comp // Reset the decay cooldown upon taking damage. if (oldDamage < component.StaminaDamage) { - var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.DecayCooldown); + var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.Cooldown); if (component.NextUpdate < nextUpdate) component.NextUpdate = nextUpdate; @@ -419,18 +393,6 @@ private void ExitStamCrit(EntityUid uid, StaminaComponent? component = null) Dirty(component); _adminLogger.Add(LogType.Stamina, LogImpact.Low, $"{ToPrettyString(uid):user} recovered from stamina crit"); } - - [Serializable, NetSerializable] - private sealed class StaminaComponentState : ComponentState - { - public bool Critical; - public float Decay; - public float DecayCooldown; - public float StaminaDamage; - public float CritThreshold; - public TimeSpan LastUpdate; - } - } /// diff --git a/Content.Shared/DeltaV/Hologram/HologramComponent.cs b/Content.Shared/DeltaV/Hologram/HologramComponent.cs new file mode 100644 index 00000000000..d11332946b4 --- /dev/null +++ b/Content.Shared/DeltaV/Hologram/HologramComponent.cs @@ -0,0 +1,21 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.DeltaV.Hologram; + +[RegisterComponent, NetworkedComponent] +[Access(typeof(SharedHologramSystem))] +public sealed partial class HologramComponent : Component +{ + /// + /// To save the state of whatever the component was added to, in case it occludes when the component is added. + /// + [DataField("occludes")] + public bool Occludes = false; + + /// + /// Do we stop disarms or not? + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("preventDisarm")] + public bool PreventDisarm = false; +} diff --git a/Content.Shared/DeltaV/Hologram/SharedHologramSystem.cs b/Content.Shared/DeltaV/Hologram/SharedHologramSystem.cs new file mode 100644 index 00000000000..823a9f1d253 --- /dev/null +++ b/Content.Shared/DeltaV/Hologram/SharedHologramSystem.cs @@ -0,0 +1,5 @@ +namespace Content.Shared.DeltaV.Hologram; + +public abstract class SharedHologramSystem : EntitySystem +{ +} diff --git a/Content.Shared/DeviceNetwork/Components/DeviceListComponent.cs b/Content.Shared/DeviceNetwork/Components/DeviceListComponent.cs index e7fee450d12..82217102926 100644 --- a/Content.Shared/DeviceNetwork/Components/DeviceListComponent.cs +++ b/Content.Shared/DeviceNetwork/Components/DeviceListComponent.cs @@ -1,53 +1,36 @@ using Content.Shared.DeviceNetwork.Systems; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.DeviceNetwork.Components; -[RegisterComponent] -[NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedDeviceListSystem))] public sealed partial class DeviceListComponent : Component { /// /// The list of devices can or can't connect to, depending on the field. /// - [DataField("devices")] + [DataField, AutoNetworkedField] public HashSet Devices = new(); /// /// The limit of devices that can be linked to this device list. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("deviceLimit")] + [DataField] public int DeviceLimit = 32; /// /// Whether the device list is used as an allow or deny list /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("isAllowList")] + [DataField, AutoNetworkedField] public bool IsAllowList = true; /// /// Whether this device list also handles incoming device net packets /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("handleIncoming")] - public bool HandleIncomingPackets = false; -} - -[Serializable, NetSerializable] -public sealed class DeviceListComponentState : ComponentState -{ - public readonly HashSet Devices; - public readonly bool IsAllowList; - public readonly bool HandleIncomingPackets; - - public DeviceListComponentState(HashSet devices, bool isAllowList, bool handleIncomingPackets) - { - Devices = devices; - IsAllowList = isAllowList; - HandleIncomingPackets = handleIncomingPackets; - } + [DataField, AutoNetworkedField] + public bool HandleIncomingPackets; } diff --git a/Content.Shared/DeviceNetwork/Components/NetworkConfiguratorComponent.cs b/Content.Shared/DeviceNetwork/Components/NetworkConfiguratorComponent.cs index 910aff4a149..7202b803f81 100644 --- a/Content.Shared/DeviceNetwork/Components/NetworkConfiguratorComponent.cs +++ b/Content.Shared/DeviceNetwork/Components/NetworkConfiguratorComponent.cs @@ -2,72 +2,57 @@ using Content.Shared.DeviceNetwork.Systems; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.DeviceNetwork.Components; -[RegisterComponent] -[NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedNetworkConfiguratorSystem))] public sealed partial class NetworkConfiguratorComponent : Component { /// /// Determines whether the configurator is in linking mode or list mode /// - [DataField("linkModeActive")] + [DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite)] public bool LinkModeActive = true; /// /// The entity containing a this configurator is currently interacting with /// - [DataField("activeDeviceList")] - public EntityUid? ActiveDeviceList = null; + [DataField, AutoNetworkedField] + public EntityUid? ActiveDeviceList; /// /// The entity containing a or this configurator is currently interacting with.
/// If this is set the configurator is in linking mode. ///
- [DataField("activeDeviceLink")] - public EntityUid? ActiveDeviceLink = null; + [DataField] + public EntityUid? ActiveDeviceLink; /// /// The target device this configurator is currently linking with the /// - [DataField("deviceLinkTarget")] - public EntityUid? DeviceLinkTarget = null; + [DataField] + public EntityUid? DeviceLinkTarget; /// /// The list of devices stored in the configurator /// - [DataField("devices")] + [DataField] public Dictionary Devices = new(); - [DataField("useDelay")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public TimeSpan UseDelay = TimeSpan.FromSeconds(0.5); - [DataField("lastUseAttempt", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] [ViewVariables(VVAccess.ReadWrite)] public TimeSpan LastUseAttempt; - [DataField("soundNoAccess")] + [DataField] public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg"); - [DataField("soundSwitchMode")] + [DataField] public SoundSpecifier SoundSwitchMode = new SoundPathSpecifier("/Audio/Machines/quickbeep.ogg"); } - -[Serializable, NetSerializable] -public sealed class NetworkConfiguratorComponentState : ComponentState -{ - public readonly NetEntity? ActiveDeviceList; - public readonly bool LinkModeActive; - - public NetworkConfiguratorComponentState(NetEntity? activeDeviceList, bool linkModeActive) - { - ActiveDeviceList = activeDeviceList; - LinkModeActive = linkModeActive; - } -} diff --git a/Content.Shared/DeviceNetwork/Systems/SharedDeviceListSystem.cs b/Content.Shared/DeviceNetwork/Systems/SharedDeviceListSystem.cs index c4d5d688c61..a15d942ad62 100644 --- a/Content.Shared/DeviceNetwork/Systems/SharedDeviceListSystem.cs +++ b/Content.Shared/DeviceNetwork/Systems/SharedDeviceListSystem.cs @@ -1,17 +1,10 @@ using System.Linq; using Content.Shared.DeviceNetwork.Components; -using Robust.Shared.GameStates; namespace Content.Shared.DeviceNetwork.Systems; public abstract class SharedDeviceListSystem : EntitySystem { - public override void Initialize() - { - SubscribeLocalEvent(GetDeviceListState); - SubscribeLocalEvent(HandleDeviceListState); - } - /// /// Updates the device list stored on this entity. /// @@ -57,23 +50,6 @@ public IEnumerable GetAllDevices(EntityUid uid, DeviceListComponent? protected virtual void UpdateShutdownSubscription(EntityUid uid, List devicesList, List oldDevices) { } - - private void GetDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentGetState args) - { - args.State = new DeviceListComponentState(GetNetEntitySet(comp.Devices), comp.IsAllowList, comp.HandleIncomingPackets); - } - - private void HandleDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentHandleState args) - { - if (args.Current is not DeviceListComponentState state) - { - return; - } - - comp.Devices = EnsureEntitySet(state.Devices, uid); - comp.HandleIncomingPackets = state.HandleIncomingPackets; - comp.IsAllowList = state.IsAllowList; - } } public sealed class DeviceListUpdateEvent : EntityEventArgs diff --git a/Content.Shared/DeviceNetwork/Systems/SharedNetworkConfiguratorSystem.cs b/Content.Shared/DeviceNetwork/Systems/SharedNetworkConfiguratorSystem.cs index 87f77c8f0a2..4aa9db199dc 100644 --- a/Content.Shared/DeviceNetwork/Systems/SharedNetworkConfiguratorSystem.cs +++ b/Content.Shared/DeviceNetwork/Systems/SharedNetworkConfiguratorSystem.cs @@ -1,37 +1,10 @@ using Content.Shared.Actions; -using Content.Shared.DeviceNetwork.Components; -using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.DeviceNetwork.Systems; public abstract class SharedNetworkConfiguratorSystem : EntitySystem { - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(GetNetworkConfiguratorState); - SubscribeLocalEvent(HandleNetworkConfiguratorState); - } - - private void GetNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp, - ref ComponentGetState args) - { - args.State = new NetworkConfiguratorComponentState(GetNetEntity(comp.ActiveDeviceList), comp.LinkModeActive); - } - - private void HandleNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp, - ref ComponentHandleState args) - { - if (args.Current is not NetworkConfiguratorComponentState state) - { - return; - } - - comp.ActiveDeviceList = EnsureEntity(state.ActiveDeviceList, uid); - comp.LinkModeActive = state.LinkModeActive; - } } public sealed partial class ClearAllOverlaysEvent : InstantActionEvent diff --git a/Content.Shared/Doors/Components/AirlockComponent.cs b/Content.Shared/Doors/Components/AirlockComponent.cs index c64e1ac518d..486efa8c519 100644 --- a/Content.Shared/Doors/Components/AirlockComponent.cs +++ b/Content.Shared/Doors/Components/AirlockComponent.cs @@ -1,7 +1,6 @@ using Content.Shared.DeviceLinking; using Content.Shared.Doors.Systems; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Doors.Components; @@ -9,16 +8,17 @@ namespace Content.Shared.Doors.Components; /// /// Companion component to DoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedAirlockSystem), Friend = AccessPermissions.ReadWriteExecute, Other = AccessPermissions.Read)] public sealed partial class AirlockComponent : Component { + // Need to network airlock safety state to avoid mis-predicts when a door auto-closes as the client walks through the door. [ViewVariables(VVAccess.ReadWrite)] - [DataField("safety")] + [DataField, AutoNetworkedField] public bool Safety = true; [ViewVariables(VVAccess.ReadWrite)] - [DataField("emergencyAccess")] + [DataField] public bool EmergencyAccess = false; /// @@ -26,20 +26,20 @@ public sealed partial class AirlockComponent : Component /// Most anything that can pry powered has a pry speed bonus, /// so this default is closer to 6 effectively on e.g. jaws (9 seconds when applied to other default.) /// - [DataField("poweredPryModifier")] + [DataField] public float PoweredPryModifier = 9f; /// /// Whether the maintenance panel should be visible even if the airlock is opened. /// - [DataField("openPanelVisible")] + [DataField] public bool OpenPanelVisible = false; /// /// Whether the airlock should stay open if the airlock was clicked. /// If the airlock was bumped into it will still auto close. /// - [DataField("keepOpenIfClicked")] + [DataField] public bool KeepOpenIfClicked = false; /// @@ -51,7 +51,7 @@ public sealed partial class AirlockComponent : Component /// /// Delay until an open door automatically closes. /// - [DataField("autoCloseDelay")] + [DataField] public TimeSpan AutoCloseDelay = TimeSpan.FromSeconds(5f); /// @@ -64,7 +64,7 @@ public sealed partial class AirlockComponent : Component /// /// The receiver port for turning off automatic closing. /// - [DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] public string AutoClosePort = "AutoClose"; #region Graphics @@ -72,79 +72,68 @@ public sealed partial class AirlockComponent : Component /// /// Whether the door lights should be visible. /// - [DataField("openUnlitVisible")] + [DataField] public bool OpenUnlitVisible = false; /// /// Whether the door should display emergency access lights. /// - [DataField("emergencyAccessLayer")] + [DataField] public bool EmergencyAccessLayer = true; /// /// Whether or not to animate the panel when the door opens or closes. /// - [DataField("animatePanel")] + [DataField] public bool AnimatePanel = true; /// /// The sprite state used to animate the airlock frame when the airlock opens. /// - [DataField("openingSpriteState")] + [DataField] public string OpeningSpriteState = "opening_unlit"; /// /// The sprite state used to animate the airlock panel when the airlock opens. /// - [DataField("openingPanelSpriteState")] + [DataField] public string OpeningPanelSpriteState = "panel_opening"; /// /// The sprite state used to animate the airlock frame when the airlock closes. /// - [DataField("closingSpriteState")] + [DataField] public string ClosingSpriteState = "closing_unlit"; /// /// The sprite state used to animate the airlock panel when the airlock closes. /// - [DataField("closingPanelSpriteState")] + [DataField] public string ClosingPanelSpriteState = "panel_closing"; /// /// The sprite state used for the open airlock lights. /// - [DataField("openSpriteState")] + [DataField] public string OpenSpriteState = "open_unlit"; /// /// The sprite state used for the closed airlock lights. /// - [DataField("closedSpriteState")] + [DataField] public string ClosedSpriteState = "closed_unlit"; /// /// The sprite state used for the 'access denied' lights animation. /// - [DataField("denySpriteState")] + [DataField] public string DenySpriteState = "deny_unlit"; /// /// How long the animation played when the airlock denies access is in seconds. /// - [DataField("denyAnimationTime")] + [DataField] public float DenyAnimationTime = 0.3f; #endregion Graphics } - -[Serializable, NetSerializable] -public sealed class AirlockComponentState : ComponentState -{ - public readonly bool Safety; - - public AirlockComponentState(bool safety) - { - Safety = safety; - } -} diff --git a/Content.Shared/Doors/Components/DoorComponent.cs b/Content.Shared/Doors/Components/DoorComponent.cs index 567afa07701..d4d121a87a6 100644 --- a/Content.Shared/Doors/Components/DoorComponent.cs +++ b/Content.Shared/Doors/Components/DoorComponent.cs @@ -1,20 +1,18 @@ -using System.Runtime.InteropServices; using Content.Shared.Damage; using Content.Shared.Doors.Systems; using Content.Shared.Tools; using JetBrains.Annotations; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Timing; using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth; namespace Content.Shared.Doors.Components; -[NetworkedComponent] -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class DoorComponent : Component { /// @@ -24,7 +22,7 @@ public sealed partial class DoorComponent : Component /// This should never be set directly, use instead. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("state")] + [DataField, AutoNetworkedField] [Access(typeof(SharedDoorSystem))] public DoorState State = DoorState.Closed; @@ -35,46 +33,47 @@ public sealed partial class DoorComponent : Component /// /// Closing time until impassable. Total time is this plus . /// - [DataField("closeTimeOne")] + [DataField] public TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.4f); /// /// Closing time until fully closed. Total time is this plus . /// - [DataField("closeTimeTwo")] + [DataField] public TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.2f); /// /// Opening time until passable. Total time is this plus . /// - [DataField("openTimeOne")] + [DataField] public TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.4f); /// /// Opening time until fully open. Total time is this plus . /// - [DataField("openTimeTwo")] + [DataField] public TimeSpan OpenTimeTwo = TimeSpan.FromSeconds(0.2f); /// /// Interval between deny sounds & visuals; /// - [DataField("denyDuration")] + [DataField] public TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f); - [DataField("emagDuration")] + [DataField] public TimeSpan EmagDuration = TimeSpan.FromSeconds(0.8f); /// /// When the door is active, this is the time when the state will next update. /// + [AutoNetworkedField] public TimeSpan? NextStateChange; /// /// Whether the door is currently partially closed or open. I.e., when the door is "closing" and is already opaque, /// but not yet actually closed. /// - [DataField("partial")] + [DataField, AutoNetworkedField] public bool Partial; #endregion @@ -115,30 +114,30 @@ public sealed partial class DoorComponent : Component /// This is how long a door-crush will stun you. This also determines how long it takes the door to open up /// again. Total stun time is actually given by this plus . /// - [DataField("doorStunTime")] + [DataField] public TimeSpan DoorStunTime = TimeSpan.FromSeconds(2f); - [DataField("crushDamage")] + [DataField] public DamageSpecifier? CrushDamage; /// /// If false, this door is incapable of crushing entities. This just determines whether it will apply damage and /// stun, not whether it can close despite entities being in the way. /// - [DataField("canCrush")] + [DataField] public bool CanCrush = true; /// /// Whether to check for colliding entities before closing. This may be overridden by other system by subscribing to /// . For example, hacked airlocks will set this to false. /// - [DataField("performCollisionCheck")] + [DataField] public bool PerformCollisionCheck = true; /// /// List of EntityUids of entities we're currently crushing. Cleared in OnPartialOpen(). /// - [DataField("currentlyCrushing")] + [DataField, AutoNetworkedField] public HashSet CurrentlyCrushing = new(); #endregion @@ -152,7 +151,7 @@ public sealed partial class DoorComponent : Component /// /// The sprite state used for the door when it's open. /// - [DataField("openSpriteState")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public string OpenSpriteState = "open"; @@ -165,7 +164,7 @@ public sealed partial class DoorComponent : Component /// /// The sprite state used for the door when it's closed. /// - [DataField("closedSpriteState")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public string ClosedSpriteState = "closed"; @@ -178,37 +177,37 @@ public sealed partial class DoorComponent : Component /// /// The sprite state used for the door when it's opening. /// - [DataField("openingSpriteState")] + [DataField] public string OpeningSpriteState = "opening"; /// /// The sprite state used for the door when it's closing. /// - [DataField("closingSpriteState")] + [DataField] public string ClosingSpriteState = "closing"; /// /// The sprite state used for the door when it's being emagged. /// - [DataField("emaggingSpriteState")] + [DataField] public string EmaggingSpriteState = "emagging"; /// /// The sprite state used for the door when it's open. /// - [DataField("openingAnimationTime")] + [DataField] public float OpeningAnimationTime = 0.8f; /// /// The sprite state used for the door when it's open. /// - [DataField("closingAnimationTime")] + [DataField] public float ClosingAnimationTime = 0.8f; /// /// The sprite state used for the door when it's open. /// - [DataField("emaggingAnimationTime")] + [DataField] public float EmaggingAnimationTime = 1.5f; /// @@ -237,7 +236,7 @@ public sealed partial class DoorComponent : Component /// /// Time until next state change. Because apparently might not get saved/restored. /// - [DataField("SecondsUntilStateChange")] + [DataField] private float? SecondsUntilStateChange { [UsedImplicitly] @@ -249,7 +248,7 @@ private float? SecondsUntilStateChange } var curTime = IoCManager.Resolve().CurTime; - return (float) (NextStateChange.Value - curTime).TotalSeconds; + return (float)(NextStateChange.Value - curTime).TotalSeconds; } set { @@ -262,46 +261,46 @@ private float? SecondsUntilStateChange } #endregion - [DataField("canPry"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool CanPry = true; - [DataField("pryingQuality", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string PryingQuality = "Prying"; + [DataField] + public ProtoId PryingQuality = "Prying"; /// /// Default time that the door should take to pry open. /// - [DataField("pryTime"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float PryTime = 1.5f; - [DataField("changeAirtight")] + [DataField] public bool ChangeAirtight = true; /// /// Whether the door blocks light. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("occludes")] + [DataField] public bool Occludes = true; /// /// Whether the door will open when it is bumped into. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("bumpOpen")] + [DataField] public bool BumpOpen = true; /// /// Whether the door will open when it is activated or clicked. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("clickOpen")] + [DataField] public bool ClickOpen = true; - [DataField("openDrawDepth", customTypeSerializer: typeof(ConstantSerializer))] + [DataField(customTypeSerializer: typeof(ConstantSerializer))] public int OpenDrawDepth = (int) DrawDepth.DrawDepth.Doors; - [DataField("closedDrawDepth", customTypeSerializer: typeof(ConstantSerializer))] + [DataField(customTypeSerializer: typeof(ConstantSerializer))] public int ClosedDrawDepth = (int) DrawDepth.DrawDepth.Doors; } @@ -335,20 +334,3 @@ public enum DoorVisualLayers : byte BaseBolted, BaseEmergencyAccess, } - -[Serializable, NetSerializable] -public sealed class DoorComponentState : ComponentState -{ - public readonly DoorState DoorState; - public readonly HashSet CurrentlyCrushing; - public readonly TimeSpan? NextStateChange; - public readonly bool Partial; - - public DoorComponentState(DoorComponent door, HashSet currentlyCrushing) - { - DoorState = door.State; - CurrentlyCrushing = currentlyCrushing; - NextStateChange = door.NextStateChange; - Partial = door.Partial; - } -} diff --git a/Content.Shared/Doors/DoorEvents.cs b/Content.Shared/Doors/DoorEvents.cs index 5b0ca71ede7..08a2c8b18b1 100644 --- a/Content.Shared/Doors/DoorEvents.cs +++ b/Content.Shared/Doors/DoorEvents.cs @@ -62,35 +62,4 @@ public sealed class BeforeDoorDeniedEvent : CancellableEntityEventArgs public sealed class BeforeDoorAutoCloseEvent : CancellableEntityEventArgs { } - - /// - /// Raised to determine how long the door's pry time should be modified by. - /// Multiply PryTimeModifier by the desired amount. - /// - public sealed class DoorGetPryTimeModifierEvent : EntityEventArgs - { - public readonly EntityUid User; - public float PryTimeModifier = 1.0f; - - public DoorGetPryTimeModifierEvent(EntityUid user) - { - User = user; - } - } - - /// - /// Raised when an attempt to pry open the door is made. - /// Cancel to stop the door from being pried open. - /// - public sealed class BeforeDoorPryEvent : CancellableEntityEventArgs - { - public readonly EntityUid User; - public readonly EntityUid Tool; - - public BeforeDoorPryEvent(EntityUid user, EntityUid tool) - { - User = user; - Tool = tool; - } - } } diff --git a/Content.Shared/Doors/Systems/SharedAirlockSystem.cs b/Content.Shared/Doors/Systems/SharedAirlockSystem.cs index 1274e339859..9e1273b7843 100644 --- a/Content.Shared/Doors/Systems/SharedAirlockSystem.cs +++ b/Content.Shared/Doors/Systems/SharedAirlockSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Doors.Components; using Content.Shared.Popups; -using Robust.Shared.GameStates; namespace Content.Shared.Doors.Systems; @@ -14,32 +13,15 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnBeforeDoorClosed); } - private void OnGetState(EntityUid uid, AirlockComponent airlock, ref ComponentGetState args) - { - // Need to network airlock safety state to avoid mis-predicts when a door auto-closes as the client walks through the door. - args.State = new AirlockComponentState(airlock.Safety); - } - - private void OnHandleState(EntityUid uid, AirlockComponent airlock, ref ComponentHandleState args) - { - if (args.Current is not AirlockComponentState state) - return; - - airlock.Safety = state.Safety; - } - protected virtual void OnBeforeDoorClosed(EntityUid uid, AirlockComponent airlock, BeforeDoorClosedEvent args) { if (!airlock.Safety) args.PerformCollisionCheck = false; } - public void UpdateEmergencyLightStatus(EntityUid uid, AirlockComponent component) { Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess); diff --git a/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs b/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs index e8be596b060..1deb6e3f7c0 100644 --- a/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorBoltSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.Doors.Components; using Content.Shared.Popups; +using Content.Shared.Prying.Components; namespace Content.Shared.Doors.Systems; @@ -16,16 +17,16 @@ public override void Initialize() SubscribeLocalEvent(OnBeforeDoorOpened); SubscribeLocalEvent(OnBeforeDoorClosed); SubscribeLocalEvent(OnBeforeDoorDenied); - SubscribeLocalEvent(OnDoorPry); + SubscribeLocalEvent(OnDoorPry); } - private void OnDoorPry(EntityUid uid, DoorBoltComponent component, BeforeDoorPryEvent args) + private void OnDoorPry(EntityUid uid, DoorBoltComponent component, ref BeforePryEvent args) { - if (component.BoltsDown) + if (component.BoltsDown && !args.Force) { - Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-bolted-message"), uid, args.User); - args.Cancel(); + Popup.PopupClient(Loc.GetString("airlock-component-cannot-pry-is-bolted-message"), uid, args.User); + args.Cancelled = true; } } diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 3fc912deba9..4a241ba3763 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -10,12 +10,12 @@ using Content.Shared.Stunnable; using Content.Shared.Tag; using Robust.Shared.Audio; -using Robust.Shared.GameStates; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; using Robust.Shared.Timing; +using Content.Shared.Prying.Components; namespace Content.Shared.Doors.Systems; @@ -23,14 +23,14 @@ public abstract partial class SharedDoorSystem : EntitySystem { [Dependency] protected readonly IGameTiming GameTiming = default!; [Dependency] protected readonly SharedPhysicsSystem PhysicsSystem = default!; - [Dependency] private readonly DamageableSystem _damageableSystem = default!; - [Dependency] private readonly SharedStunSystem _stunSystem = default!; + [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly SharedStunSystem _stunSystem = default!; [Dependency] protected readonly TagSystem Tags = default!; [Dependency] protected readonly SharedAudioSystem Audio = default!; - [Dependency] private readonly EntityLookupSystem _entityLookup = default!; + [Dependency] private readonly EntityLookupSystem _entityLookup = default!; [Dependency] protected readonly SharedAppearanceSystem AppearanceSystem = default!; - [Dependency] private readonly OccluderSystem _occluder = default!; - [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!; + [Dependency] private readonly OccluderSystem _occluder = default!; + [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!; /// /// A body must have an intersection percentage larger than this in order to be considered as colliding with a @@ -54,13 +54,14 @@ public override void Initialize() SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnRemove); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); + SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnActivate); SubscribeLocalEvent(HandleCollide); SubscribeLocalEvent(PreventCollision); + SubscribeLocalEvent(OnPryTimeModifier); + } protected virtual void OnComponentInit(EntityUid uid, DoorComponent door, ComponentInit args) @@ -99,29 +100,14 @@ private void OnRemove(EntityUid uid, DoorComponent door, ComponentRemove args) } #region StateManagement - private void OnGetState(EntityUid uid, DoorComponent door, ref ComponentGetState args) + private void OnHandleState(EntityUid uid, DoorComponent door, ref AfterAutoHandleStateEvent args) { - args.State = new DoorComponentState(door, GetNetEntitySet(door.CurrentlyCrushing)); - } - - private void OnHandleState(EntityUid uid, DoorComponent door, ref ComponentHandleState args) - { - if (args.Current is not DoorComponentState state) - return; - - door.CurrentlyCrushing.Clear(); - door.CurrentlyCrushing.UnionWith(EnsureEntitySet(state.CurrentlyCrushing, uid)); - - door.State = state.DoorState; - door.NextStateChange = state.NextStateChange; - door.Partial = state.Partial; - - if (state.NextStateChange == null) + if (door.NextStateChange == null) _activeDoors.Remove(door); else _activeDoors.Add(door); - RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State), false); + RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State)); AppearanceSystem.SetData(uid, DoorVisuals.State, door.State); } @@ -182,6 +168,11 @@ protected virtual void OnActivate(EntityUid uid, DoorComponent door, ActivateInW args.Handled = true; } + private void OnPryTimeModifier(EntityUid uid, DoorComponent door, ref GetPryTimeModifierEvent args) + { + args.BaseTime = door.PryTime; + } + /// /// Update the door state/visuals and play an access denied sound when a user without access interacts with the /// door. @@ -206,6 +197,7 @@ public void Deny(EntityUid uid, DoorComponent? door = null, EntityUid? user = nu PlaySound(uid, door.DenySound, AudioParams.Default.WithVolume(-3), user, predicted); } + public bool TryToggleDoor(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false) { if (!Resolve(uid, ref door)) @@ -246,7 +238,7 @@ public bool CanOpen(EntityUid uid, DoorComponent? door = null, EntityUid? user = if (door.State == DoorState.Welded) return false; - var ev = new BeforeDoorOpenedEvent(){User=user}; + var ev = new BeforeDoorOpenedEvent() { User = user }; RaiseLocalEvent(uid, ev, false); if (ev.Cancelled) return false; @@ -261,6 +253,14 @@ public bool CanOpen(EntityUid uid, DoorComponent? door = null, EntityUid? user = return true; } + /// + /// Immediately start opening a door + /// + /// The uid of the door + /// The doorcomponent of the door + /// The user (if any) opening the door + /// Whether the interaction would have been + /// predicted. See comments in the PlaySound method on the Server system for details public virtual void StartOpening(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false) { if (!Resolve(uid, ref door)) @@ -309,6 +309,14 @@ public bool TryClose(EntityUid uid, DoorComponent? door = null, EntityUid? user return true; } + /// + /// Immediately start closing a door + /// + /// The uid of the door + /// The doorcomponent of the door + /// The user (if any) opening the door + /// Whether the interaction would have been + /// predicted. See comments in the PlaySound method on the Server system for details public bool CanClose(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool quiet = true) { if (!Resolve(uid, ref door)) @@ -444,11 +452,11 @@ public IEnumerable GetColliding(EntityUid uid, PhysicsComponent? phys //TODO: Make only shutters ignore these objects upon colliding instead of all airlocks // Excludes Glasslayer for windows, GlassAirlockLayer for windoors, TableLayer for tables - if (!otherPhysics.CanCollide || otherPhysics.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.CollisionLayer == (int) CollisionGroup.TableLayer) + if (!otherPhysics.CanCollide || otherPhysics.CollisionLayer == (int)CollisionGroup.GlassLayer || otherPhysics.CollisionLayer == (int)CollisionGroup.GlassAirlockLayer || otherPhysics.CollisionLayer == (int)CollisionGroup.TableLayer) continue; //If the colliding entity is a slippable item ignore it by the airlock - if (otherPhysics.CollisionLayer == (int) CollisionGroup.SlipLayer && otherPhysics.CollisionMask == (int) CollisionGroup.ItemMask) + if (otherPhysics.CollisionLayer == (int)CollisionGroup.SlipLayer && otherPhysics.CollisionMask == (int)CollisionGroup.ItemMask) continue; if ((physics.CollisionMask & otherPhysics.CollisionLayer) == 0 && (otherPhysics.CollisionMask & physics.CollisionLayer) == 0) @@ -598,7 +606,7 @@ public override void Update(float frameTime) } } - protected virtual void CheckDoorBump(DoorComponent component, PhysicsComponent body) {} + protected virtual void CheckDoorBump(DoorComponent component, PhysicsComponent body) { } /// /// Makes a door proceed to the next state (if applicable). @@ -659,9 +667,4 @@ private void NextState(DoorComponent door, TimeSpan time) #endregion protected abstract void PlaySound(EntityUid uid, SoundSpecifier soundSpecifier, AudioParams audioParams, EntityUid? predictingPlayer, bool predicted); - - [Serializable, NetSerializable] - protected sealed partial class DoorPryDoAfterEvent : SimpleDoAfterEvent - { - } } diff --git a/Content.Shared/Electrocution/InsulatedComponent.cs b/Content.Shared/Electrocution/InsulatedComponent.cs index cd4e5e32c5c..72c6ebcef0c 100644 --- a/Content.Shared/Electrocution/InsulatedComponent.cs +++ b/Content.Shared/Electrocution/InsulatedComponent.cs @@ -1,29 +1,17 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Electrocution { + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedElectrocutionSystem))] - [RegisterComponent, NetworkedComponent] public sealed partial class InsulatedComponent : Component { + // Technically, people could cheat and figure out which budget insulated gloves are gud and which ones are bad. + // We might want to rethink this a little bit. /// /// Siemens coefficient. Zero means completely insulated. /// - [DataField("coefficient")] - public float SiemensCoefficient { get; set; } = 0f; - } - - // Technically, people could cheat and figure out which budget insulated gloves are gud and which ones are bad. - // We might want to rethink this a little bit. - [NetSerializable, Serializable] - public sealed class InsulatedComponentState : ComponentState - { - public float SiemensCoefficient { get; private set; } - - public InsulatedComponentState(float siemensCoefficient) - { - SiemensCoefficient = siemensCoefficient; - } + [DataField, AutoNetworkedField] + public float Coefficient { get; set; } = 0f; } } diff --git a/Content.Shared/Electrocution/SharedElectrocutionSystem.cs b/Content.Shared/Electrocution/SharedElectrocutionSystem.cs index 67a395bb81c..5031d8a9115 100644 --- a/Content.Shared/Electrocution/SharedElectrocutionSystem.cs +++ b/Content.Shared/Electrocution/SharedElectrocutionSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Inventory; using Content.Shared.StatusEffect; -using Robust.Shared.GameStates; namespace Content.Shared.Electrocution { @@ -13,8 +12,6 @@ public override void Initialize() SubscribeLocalEvent(OnInsulatedElectrocutionAttempt); // as long as legally distinct electric-mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer). SubscribeLocalEvent>((e, c, ev) => OnInsulatedElectrocutionAttempt(e, c, ev.Args)); - SubscribeLocalEvent(OnInsulatedGetState); - SubscribeLocalEvent(OnInsulatedHandleState); } public void SetInsulatedSiemensCoefficient(EntityUid uid, float siemensCoefficient, InsulatedComponent? insulated = null) @@ -22,7 +19,7 @@ public void SetInsulatedSiemensCoefficient(EntityUid uid, float siemensCoefficie if (!Resolve(uid, ref insulated)) return; - insulated.SiemensCoefficient = siemensCoefficient; + insulated.Coefficient = siemensCoefficient; Dirty(insulated); } @@ -45,21 +42,7 @@ public virtual bool TryDoElectrocution( private void OnInsulatedElectrocutionAttempt(EntityUid uid, InsulatedComponent insulated, ElectrocutionAttemptEvent args) { - args.SiemensCoefficient *= insulated.SiemensCoefficient; + args.SiemensCoefficient *= insulated.Coefficient; } - - private void OnInsulatedGetState(EntityUid uid, InsulatedComponent insulated, ref ComponentGetState args) - { - args.State = new InsulatedComponentState(insulated.SiemensCoefficient); - } - - private void OnInsulatedHandleState(EntityUid uid, InsulatedComponent insulated, ref ComponentHandleState args) - { - if (args.Current is not InsulatedComponentState state) - return; - - insulated.SiemensCoefficient = state.SiemensCoefficient; - } - } } diff --git a/Content.Shared/Emoting/EmoteSystem.cs b/Content.Shared/Emoting/EmoteSystem.cs index 942c6b9de02..fd6361245b1 100644 --- a/Content.Shared/Emoting/EmoteSystem.cs +++ b/Content.Shared/Emoting/EmoteSystem.cs @@ -1,60 +1,30 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; +namespace Content.Shared.Emoting; -namespace Content.Shared.Emoting +public sealed class EmoteSystem : EntitySystem { - public sealed class EmoteSystem : EntitySystem + public override void Initialize() { - public override void Initialize() - { - base.Initialize(); + base.Initialize(); - SubscribeLocalEvent(OnEmoteAttempt); - SubscribeLocalEvent(OnEmotingGetState); - SubscribeLocalEvent(OnEmotingHandleState); - } - - public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null) - { - if (value && !Resolve(uid, ref component)) - return; - - component = EnsureComp(uid); - - if (component.Enabled == value) - return; - - Dirty(component); - } - - private void OnEmotingHandleState(EntityUid uid, EmotingComponent component, ref ComponentHandleState args) - { - if (args.Current is not EmotingComponentState state) - return; + SubscribeLocalEvent(OnEmoteAttempt); + } - component.Enabled = state.Enabled; - } + public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null) + { + if (value && !Resolve(uid, ref component)) + return; - private void OnEmotingGetState(EntityUid uid, EmotingComponent component, ref ComponentGetState args) - { - args.State = new EmotingComponentState(component.Enabled); - } + component = EnsureComp(uid); - private void OnEmoteAttempt(EmoteAttemptEvent args) - { - if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled) - args.Cancel(); - } + if (component.Enabled == value) + return; - [Serializable, NetSerializable] - private sealed class EmotingComponentState : ComponentState - { - public bool Enabled { get; } + Dirty(component); + } - public EmotingComponentState(bool enabled) - { - Enabled = enabled; - } - } + private void OnEmoteAttempt(EmoteAttemptEvent args) + { + if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled) + args.Cancel(); } } diff --git a/Content.Shared/Emoting/EmotingComponent.cs b/Content.Shared/Emoting/EmotingComponent.cs index a7a1542a91d..873f906f4b8 100644 --- a/Content.Shared/Emoting/EmotingComponent.cs +++ b/Content.Shared/Emoting/EmotingComponent.cs @@ -1,12 +1,11 @@ using Robust.Shared.GameStates; -namespace Content.Shared.Emoting +namespace Content.Shared.Emoting; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class EmotingComponent : Component { - [RegisterComponent, NetworkedComponent] - public sealed partial class EmotingComponent : Component - { - [DataField("enabled"), Access(typeof(EmoteSystem), - Friend = AccessPermissions.ReadWrite, - Other = AccessPermissions.Read)] public bool Enabled = true; - } + [DataField, AutoNetworkedField] + [Access(typeof(EmoteSystem), Friend = AccessPermissions.ReadWrite, Other = AccessPermissions.Read)] + public bool Enabled = true; } diff --git a/Content.Shared/Follower/Components/FollowedComponent.cs b/Content.Shared/Follower/Components/FollowedComponent.cs index 83e486668eb..7c2ca0efbfe 100644 --- a/Content.Shared/Follower/Components/FollowedComponent.cs +++ b/Content.Shared/Follower/Components/FollowedComponent.cs @@ -6,10 +6,10 @@ namespace Content.Shared.Follower.Components; /// /// Attached to entities that are currently being followed by a ghost. /// -[RegisterComponent, Access(typeof(FollowerSystem))] -[NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(FollowerSystem))] public sealed partial class FollowedComponent : Component { - [DataField("following")] + [DataField, AutoNetworkedField] public HashSet Following = new(); } diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 10e7a7be1d0..38c0e5ada3f 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -8,14 +8,12 @@ using Content.Shared.Tag; using Content.Shared.Verbs; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Map.Events; using Robust.Shared.Network; -using Robust.Shared.Utility; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Serialization; +using Robust.Shared.Utility; namespace Content.Shared.Follower; @@ -35,28 +33,11 @@ public override void Initialize() SubscribeLocalEvent>(OnGetAlternativeVerbs); SubscribeLocalEvent(OnFollowerMove); SubscribeLocalEvent(OnPullStarted); + SubscribeLocalEvent(OnFollowerTerminating); + SubscribeLocalEvent(OnGotEquippedHand); SubscribeLocalEvent(OnFollowedTerminating); SubscribeLocalEvent(OnBeforeSave); - - SubscribeLocalEvent(OnFollowedGetState); - SubscribeLocalEvent(OnFollowedHandleState); - } - - private void OnFollowedGetState(EntityUid uid, FollowedComponent component, ref ComponentGetState args) - { - args.State = new FollowedComponentState() - { - Following = GetNetEntitySet(component.Following), - }; - } - - private void OnFollowedHandleState(EntityUid uid, FollowedComponent component, ref ComponentHandleState args) - { - if (args.Current is not FollowedComponentState state) - return; - - component.Following = EnsureEntitySet(state.Following, uid); } private void OnBeforeSave(BeforeSaveEvent ev) @@ -128,6 +109,11 @@ private void OnGotEquippedHand(EntityUid uid, FollowerComponent component, GotEq StopFollowingEntity(uid, component.Following, deparent:false); } + private void OnFollowerTerminating(EntityUid uid, FollowerComponent component, ref EntityTerminatingEvent args) + { + StopFollowingEntity(uid, component.Following, deparent: false); + } + // Since we parent our observer to the followed entity, we need to detach // before they get deleted so that we don't get recursively deleted too. private void OnFollowedTerminating(EntityUid uid, FollowedComponent component, ref EntityTerminatingEvent args) @@ -207,7 +193,7 @@ public void StopFollowingEntity(EntityUid uid, EntityUid target, FollowedCompone RaiseLocalEvent(uid, uidEv, true); RaiseLocalEvent(target, targetEv, false); - Dirty(followed); + Dirty(target, followed); RaiseLocalEvent(uid, uidEv); RaiseLocalEvent(target, targetEv); @@ -242,12 +228,6 @@ public void StopAllFollowers(EntityUid uid, StopFollowingEntity(player, uid, followed); } } - - [Serializable, NetSerializable] - private sealed class FollowedComponentState : ComponentState - { - public HashSet Following = new(); - } } public abstract class FollowEvent : EntityEventArgs diff --git a/Content.Shared/Gravity/FloatingVisualsComponent.cs b/Content.Shared/Gravity/FloatingVisualsComponent.cs index 7cf6331e9ef..67650baecda 100644 --- a/Content.Shared/Gravity/FloatingVisualsComponent.cs +++ b/Content.Shared/Gravity/FloatingVisualsComponent.cs @@ -1,10 +1,9 @@ using System.Numerics; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Gravity; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedFloatingVisualizerSystem))] public sealed partial class FloatingVisualsComponent : Component { @@ -12,33 +11,19 @@ public sealed partial class FloatingVisualsComponent : Component /// How long it takes to go from the bottom of the animation to the top. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("animationTime")] + [DataField, AutoNetworkedField] public float AnimationTime = 2f; /// /// How far it goes in any direction. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("offset")] + [DataField, AutoNetworkedField] public Vector2 Offset = new(0, 0.2f); [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] public bool CanFloat = false; - public readonly string AnimationKey = "gravity"; -} - -[Serializable, NetSerializable] -public sealed class SharedFloatingVisualsComponentState : ComponentState -{ - public float AnimationTime; - public Vector2 Offset; - public bool HasGravity; - - public SharedFloatingVisualsComponentState(float animationTime, Vector2 offset, bool hasGravity) - { - AnimationTime = animationTime; - Offset = offset; - HasGravity = hasGravity; - } + public readonly string AnimationKey = "gravity"; } diff --git a/Content.Shared/Gravity/GravityShakeComponent.cs b/Content.Shared/Gravity/GravityShakeComponent.cs index 5fc1e902304..e8608a9681c 100644 --- a/Content.Shared/Gravity/GravityShakeComponent.cs +++ b/Content.Shared/Gravity/GravityShakeComponent.cs @@ -6,12 +6,12 @@ namespace Content.Shared.Gravity; /// /// Indicates this entity is shaking due to gravity changes. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class GravityShakeComponent : Component { - [ViewVariables(VVAccess.ReadWrite), DataField("shakeTimes")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public int ShakeTimes; - [DataField("nextShake", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] public TimeSpan NextShake; } diff --git a/Content.Shared/Gravity/SharedFloatingVisualizerSystem.cs b/Content.Shared/Gravity/SharedFloatingVisualizerSystem.cs index 204f3978011..0f06d72192e 100644 --- a/Content.Shared/Gravity/SharedFloatingVisualizerSystem.cs +++ b/Content.Shared/Gravity/SharedFloatingVisualizerSystem.cs @@ -1,5 +1,4 @@ using System.Numerics; -using Robust.Shared.GameStates; using Robust.Shared.Map; namespace Content.Shared.Gravity; @@ -18,8 +17,6 @@ public override void Initialize() SubscribeLocalEvent(OnComponentStartup); SubscribeLocalEvent(OnGravityChanged); SubscribeLocalEvent(OnEntParentChanged); - SubscribeLocalEvent(OnComponentGetState); - SubscribeLocalEvent(OnComponentHandleState); } /// @@ -71,19 +68,4 @@ private void OnEntParentChanged(EntityUid uid, FloatingVisualsComponent componen if (CanFloat(uid, component, transform)) FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime); } - - private void OnComponentGetState(EntityUid uid, FloatingVisualsComponent component, ref ComponentGetState args) - { - args.State = new SharedFloatingVisualsComponentState(component.AnimationTime, component.Offset, component.CanFloat); - } - - private void OnComponentHandleState(EntityUid uid, FloatingVisualsComponent component, ref ComponentHandleState args) - { - if (args.Current is not SharedFloatingVisualsComponentState state) - return; - - component.AnimationTime = state.AnimationTime; - component.Offset = state.Offset; - component.CanFloat = state.HasGravity; - } } diff --git a/Content.Shared/Gravity/SharedGravitySystem.Shake.cs b/Content.Shared/Gravity/SharedGravitySystem.Shake.cs index f265dedc150..e590baae44c 100644 --- a/Content.Shared/Gravity/SharedGravitySystem.Shake.cs +++ b/Content.Shared/Gravity/SharedGravitySystem.Shake.cs @@ -1,6 +1,3 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - namespace Content.Shared.Gravity; public abstract partial class SharedGravitySystem @@ -11,8 +8,6 @@ public abstract partial class SharedGravitySystem private void InitializeShake() { SubscribeLocalEvent(OnShakeUnpaused); - SubscribeLocalEvent(OnShakeGetState); - SubscribeLocalEvent(OnShakeHandleState); } private void OnShakeUnpaused(EntityUid uid, GravityShakeComponent component, ref EntityUnpausedEvent args) @@ -63,29 +58,4 @@ public void StartGridShake(EntityUid uid, GravityComponent? gravity = null) } protected virtual void ShakeGrid(EntityUid uid, GravityComponent? comp = null) {} - - private void OnShakeHandleState(EntityUid uid, GravityShakeComponent component, ref ComponentHandleState args) - { - if (args.Current is not GravityShakeComponentState state) - return; - - component.ShakeTimes = state.ShakeTimes; - component.NextShake = state.NextShake; - } - - private void OnShakeGetState(EntityUid uid, GravityShakeComponent component, ref ComponentGetState args) - { - args.State = new GravityShakeComponentState() - { - ShakeTimes = component.ShakeTimes, - NextShake = component.NextShake, - }; - } - - [Serializable, NetSerializable] - protected sealed class GravityShakeComponentState : ComponentState - { - public int ShakeTimes; - public TimeSpan NextShake; - } } diff --git a/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs b/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs index 82d5750aa5c..82d6964522c 100644 --- a/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs +++ b/Content.Shared/Humanoid/HumanoidAppearanceComponent.cs @@ -4,31 +4,31 @@ using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Utility; -using static Content.Shared.Humanoid.HumanoidAppearanceState; namespace Content.Shared.Humanoid; -[NetworkedComponent, RegisterComponent] +[NetworkedComponent, RegisterComponent, AutoGenerateComponentState(true)] public sealed partial class HumanoidAppearanceComponent : Component { - [DataField("markingSet")] + public MarkingSet ClientOldMarkings = new(); + + [DataField, AutoNetworkedField] public MarkingSet MarkingSet = new(); - [DataField("baseLayers")] + [DataField] public Dictionary BaseLayers = new(); - [DataField("permanentlyHidden")] + [DataField, AutoNetworkedField] public HashSet PermanentlyHidden = new(); // Couldn't these be somewhere else? - [DataField("gender")] - [ViewVariables] public Gender Gender = default!; + [DataField, AutoNetworkedField] + public Gender Gender; - [DataField("age")] - [ViewVariables] public int Age = 18; + [DataField, AutoNetworkedField] + public int Age = 18; /// /// Any custom base layers this humanoid might have. See: @@ -36,39 +36,39 @@ public sealed partial class HumanoidAppearanceComponent : Component /// Stored on the server, this is merged in the client into /// all layer settings. /// - [DataField("customBaseLayers")] + [DataField, AutoNetworkedField] public Dictionary CustomBaseLayers = new(); /// /// Current species. Dictates things like base body sprites, /// base humanoid to spawn, etc. /// - [DataField("species", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] - public string Species { get; set; } = default!; + [DataField(required: true), AutoNetworkedField] + public ProtoId Species { get; set; } /// /// The initial profile and base layers to apply to this humanoid. /// - [DataField("initial", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? Initial { get; private set; } + [DataField] + public ProtoId? Initial { get; private set; } /// /// Skin color of this humanoid. /// - [DataField("skinColor")] + [DataField, AutoNetworkedField] public Color SkinColor { get; set; } = Color.FromHex("#C0967F"); /// /// Visual layers currently hidden. This will affect the base sprite /// on this humanoid layer, and any markings that sit above it. /// - [DataField("hiddenLayers")] + [DataField, AutoNetworkedField] public HashSet HiddenLayers = new(); - [DataField("sex")] + [DataField, AutoNetworkedField] public Sex Sex = Sex.Male; - [DataField("eyeColor")] + [DataField, AutoNetworkedField] public Color EyeColor = Color.Brown; /// @@ -84,65 +84,26 @@ public sealed partial class HumanoidAppearanceComponent : Component public Color? CachedFacialHairColor; } +[DataDefinition] [Serializable, NetSerializable] -public sealed partial class HumanoidAppearanceState : ComponentState +public readonly partial struct CustomBaseLayerInfo { - public readonly MarkingSet Markings; - public readonly HashSet PermanentlyHidden; - public readonly HashSet HiddenLayers; - public readonly Dictionary CustomBaseLayers; - public readonly Sex Sex; - public readonly Gender Gender; - public readonly int Age = 18; - public readonly string Species; - public readonly Color SkinColor; - public readonly Color EyeColor; - - public HumanoidAppearanceState( - MarkingSet currentMarkings, - HashSet permanentlyHidden, - HashSet hiddenLayers, - Dictionary customBaseLayers, - Sex sex, - Gender gender, - int age, - string species, - Color skinColor, - Color eyeColor) + public CustomBaseLayerInfo(string? id, Color? color = null) { - Markings = currentMarkings; - PermanentlyHidden = permanentlyHidden; - HiddenLayers = hiddenLayers; - CustomBaseLayers = customBaseLayers; - Sex = sex; - Gender = gender; - Age = age; - Species = species; - SkinColor = skinColor; - EyeColor = eyeColor; + DebugTools.Assert(id == null || IoCManager.Resolve().HasIndex(id)); + Id = id; + Color = color; } - [DataDefinition] - [Serializable, NetSerializable] - public readonly partial struct CustomBaseLayerInfo - { - public CustomBaseLayerInfo(string? id, Color? color = null) - { - DebugTools.Assert(id == null || IoCManager.Resolve().HasIndex(id)); - ID = id; - Color = color; - } - - /// - /// ID of this custom base layer. Must be a . - /// - [DataField("id", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? ID { init; get; } - - /// - /// Color of this custom base layer. Null implies skin colour if the corresponding is set to match skin. - /// - [DataField("color")] - public Color? Color { init; get; } - } + /// + /// ID of this custom base layer. Must be a . + /// + [DataField] + public ProtoId? Id { get; init; } + + /// + /// Color of this custom base layer. Null implies skin colour if the corresponding is set to match skin. + /// + [DataField] + public Color? Color { get; init; } } diff --git a/Content.Shared/Humanoid/Prototypes/HumanoidProfilePrototype.cs b/Content.Shared/Humanoid/Prototypes/HumanoidProfilePrototype.cs index 5752e57c93b..7755e3113c0 100644 --- a/Content.Shared/Humanoid/Prototypes/HumanoidProfilePrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/HumanoidProfilePrototype.cs @@ -1,6 +1,5 @@ using Content.Shared.Preferences; using Robust.Shared.Prototypes; -using static Content.Shared.Humanoid.HumanoidAppearanceState; namespace Content.Shared.Humanoid.Prototypes; diff --git a/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs b/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs index e7e7b5a6728..a61470bfdfb 100644 --- a/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs +++ b/Content.Shared/Humanoid/SharedHumanoidAppearanceSystem.cs @@ -1,11 +1,10 @@ +using System.Linq; using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Prototypes; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; -using System.Linq; using Content.Shared.Preferences; using Robust.Shared.GameObjects.Components.Localization; using Robust.Shared.Network; +using Robust.Shared.Prototypes; namespace Content.Shared.Humanoid; @@ -31,7 +30,6 @@ public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnGetState); } private void OnInit(EntityUid uid, HumanoidAppearanceComponent humanoid, ComponentInit args) @@ -57,20 +55,6 @@ private void OnInit(EntityUid uid, HumanoidAppearanceComponent humanoid, Compone LoadProfile(uid, startingSet.Profile, humanoid); } - private void OnGetState(EntityUid uid, HumanoidAppearanceComponent component, ref ComponentGetState args) - { - args.State = new HumanoidAppearanceState(component.MarkingSet, - component.PermanentlyHidden, - component.HiddenLayers, - component.CustomBaseLayers, - component.Sex, - component.Gender, - component.Age, - component.Species, - component.SkinColor, - component.EyeColor); - } - /// /// Toggles a humanoid's sprite layer visibility. /// @@ -211,7 +195,7 @@ public void SetBaseLayerId(EntityUid uid, HumanoidVisualLayers layer, string? id return; if (humanoid.CustomBaseLayers.TryGetValue(layer, out var info)) - humanoid.CustomBaseLayers[layer] = info with { ID = id }; + humanoid.CustomBaseLayers[layer] = info with { Id = id }; else humanoid.CustomBaseLayers[layer] = new(id); diff --git a/Content.Shared/Humanoid/SharedHumanoidMarkingModifierSystem.cs b/Content.Shared/Humanoid/SharedHumanoidMarkingModifierSystem.cs index bd0bad96703..68b3533bd4d 100644 --- a/Content.Shared/Humanoid/SharedHumanoidMarkingModifierSystem.cs +++ b/Content.Shared/Humanoid/SharedHumanoidMarkingModifierSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Humanoid.Markings; using Robust.Shared.Serialization; -using static Content.Shared.Humanoid.HumanoidAppearanceState; namespace Content.Shared.Humanoid; diff --git a/Content.Shared/Implants/Components/ImplanterComponent.cs b/Content.Shared/Implants/Components/ImplanterComponent.cs index e681cab0473..85891826f90 100644 --- a/Content.Shared/Implants/Components/ImplanterComponent.cs +++ b/Content.Shared/Implants/Components/ImplanterComponent.cs @@ -1,10 +1,7 @@ -using System.Threading; -using Content.Shared.Containers.ItemSlots; -using Content.Shared.DoAfter; +using Content.Shared.Containers.ItemSlots; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Implants.Components; /// @@ -12,7 +9,7 @@ namespace Content.Shared.Implants.Components; /// Some can be single use (implant only) or some can draw out an implant /// //TODO: Rework drawing to work with implant cases when surgery is in -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class ImplanterComponent : Component { public const string ImplanterSlotId = "implanter_slot"; @@ -21,15 +18,14 @@ public sealed partial class ImplanterComponent : Component /// /// Used for implanters that start with specific implants /// - [ViewVariables] - [DataField("implant", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? Implant; + [DataField] + public EntProtoId? Implant; /// /// The time it takes to implant someone else /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("implantTime")] + [DataField] public float ImplantTime = 5f; //TODO: Remove when surgery is a thing @@ -38,54 +34,37 @@ public sealed partial class ImplanterComponent : Component /// It's excessively long to deter from implant checking any antag /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("drawTime")] + [DataField] public float DrawTime = 60f; /// /// Good for single-use injectors /// - [ViewVariables] - [DataField("implantOnly")] - public bool ImplantOnly = false; + [DataField, AutoNetworkedField] + public bool ImplantOnly; /// /// The current mode of the implanter /// Mode is changed automatically depending if it implants or draws /// - [ViewVariables] - [DataField("currentMode")] + [DataField, AutoNetworkedField] public ImplanterToggleMode CurrentMode; /// /// The name and description of the implant to show on the implanter /// - [ViewVariables] - [DataField("implantData")] + [DataField] public (string, string) ImplantData; /// /// The for this implanter /// - [ViewVariables] - [DataField("implanterSlot", required:true)] + [DataField(required: true)] public ItemSlot ImplanterSlot = new(); public bool UiUpdateNeeded; } -[Serializable, NetSerializable] -public sealed class ImplanterComponentState : ComponentState -{ - public ImplanterToggleMode CurrentMode; - public bool ImplantOnly; - - public ImplanterComponentState(ImplanterToggleMode currentMode, bool implantOnly) - { - CurrentMode = currentMode; - ImplantOnly = implantOnly; - } -} - [Serializable, NetSerializable] public enum ImplanterToggleMode : byte { diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs index c50531e2958..840320b0d3b 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -44,6 +44,7 @@ public static class ContentKeyFunctions public static readonly BoundKeyFunction OpenAdminMenu = "OpenAdminMenu"; public static readonly BoundKeyFunction TakeScreenshot = "TakeScreenshot"; public static readonly BoundKeyFunction TakeScreenshotNoUI = "TakeScreenshotNoUI"; + public static readonly BoundKeyFunction ToggleFullscreen = "ToggleFullscreen"; public static readonly BoundKeyFunction Point = "Point"; public static readonly BoundKeyFunction ZoomOut = "ZoomOut"; public static readonly BoundKeyFunction ZoomIn = "ZoomIn"; diff --git a/Content.Shared/Interaction/Components/InteractionRelayComponent.cs b/Content.Shared/Interaction/Components/InteractionRelayComponent.cs index 1f8b4468ad1..2ac9c1e4ef1 100644 --- a/Content.Shared/Interaction/Components/InteractionRelayComponent.cs +++ b/Content.Shared/Interaction/Components/InteractionRelayComponent.cs @@ -1,5 +1,4 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Interaction.Components; @@ -10,27 +9,13 @@ namespace Content.Shared.Interaction.Components; /// /// Note that extreme caution should be taken when using this, as this will probably bypass many normal can-interact checks. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedInteractionSystem))] public sealed partial class InteractionRelayComponent : Component { /// /// The entity the interactions are being relayed to. /// - [ViewVariables] + [ViewVariables, AutoNetworkedField] public EntityUid? RelayEntity; } - -/// -/// Contains network state for -/// -[Serializable, NetSerializable] -public sealed class InteractionRelayComponentState : ComponentState -{ - public NetEntity? RelayEntity; - - public InteractionRelayComponentState(NetEntity? relayEntity) - { - RelayEntity = relayEntity; - } -} diff --git a/Content.Shared/Interaction/SharedInteractionSystem.Relay.cs b/Content.Shared/Interaction/SharedInteractionSystem.Relay.cs index f82b8f78760..77e283b93d1 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.Relay.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.Relay.cs @@ -1,35 +1,15 @@ using Content.Shared.Interaction.Components; -using Robust.Shared.GameStates; namespace Content.Shared.Interaction; public abstract partial class SharedInteractionSystem { - public void InitializeRelay() - { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnGetState(EntityUid uid, InteractionRelayComponent component, ref ComponentGetState args) - { - args.State = new InteractionRelayComponentState(GetNetEntity(component.RelayEntity)); - } - - private void OnHandleState(EntityUid uid, InteractionRelayComponent component, ref ComponentHandleState args) - { - if (args.Current is not InteractionRelayComponentState state) - return; - - component.RelayEntity = EnsureEntity(state.RelayEntity, uid); - } - public void SetRelay(EntityUid uid, EntityUid? relayEntity, InteractionRelayComponent? component = null) { if (!Resolve(uid, ref component)) return; component.RelayEntity = relayEntity; - Dirty(component); + Dirty(uid, component); } } diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 00c357814d7..d79a892c711 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -1,4 +1,3 @@ -using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.ActionBlocker; @@ -7,7 +6,6 @@ using Content.Shared.Administration.Managers; using Content.Shared.CombatMode; using Content.Shared.Database; -using Content.Shared.Ghost; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Input; @@ -28,7 +26,6 @@ using Content.Shared.Wall; using JetBrains.Annotations; using Robust.Shared.Containers; -using Robust.Shared.GameObjects; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Map; @@ -99,7 +96,6 @@ public override void Initialize() new PointerInputCmdHandler(HandleTryPullObject)) .Register(); - InitializeRelay(); InitializeBlocking(); } diff --git a/Content.Shared/Jittering/JitteringComponent.cs b/Content.Shared/Jittering/JitteringComponent.cs index cd8e3aeea79..237629f291b 100644 --- a/Content.Shared/Jittering/JitteringComponent.cs +++ b/Content.Shared/Jittering/JitteringComponent.cs @@ -1,33 +1,20 @@ using System.Numerics; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -namespace Content.Shared.Jittering -{ - [Access(typeof(SharedJitteringSystem))] - [RegisterComponent, NetworkedComponent] - public sealed partial class JitteringComponent : Component - { - [ViewVariables(VVAccess.ReadWrite)] - public float Amplitude { get; set; } - - [ViewVariables(VVAccess.ReadWrite)] - public float Frequency { get; set; } +namespace Content.Shared.Jittering; - [ViewVariables(VVAccess.ReadWrite)] - public Vector2 LastJitter { get; set; } - } +[Access(typeof(SharedJitteringSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class JitteringComponent : Component +{ + [AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] + public float Amplitude { get; set; } - [Serializable, NetSerializable] - public sealed class JitteringComponentState : ComponentState - { - public float Amplitude { get; } - public float Frequency { get; } + [AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] + public float Frequency { get; set; } - public JitteringComponentState(float amplitude, float frequency) - { - Amplitude = amplitude; - Frequency = frequency; - } - } + [ViewVariables(VVAccess.ReadWrite)] + public Vector2 LastJitter { get; set; } } diff --git a/Content.Shared/Jittering/SharedJitteringSystem.cs b/Content.Shared/Jittering/SharedJitteringSystem.cs index e0cb2463f98..327a4521752 100644 --- a/Content.Shared/Jittering/SharedJitteringSystem.cs +++ b/Content.Shared/Jittering/SharedJitteringSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Rejuvenate; using Content.Shared.StatusEffect; -using Robust.Shared.GameStates; using Robust.Shared.Timing; namespace Content.Shared.Jittering @@ -21,25 +20,9 @@ public abstract class SharedJitteringSystem : EntitySystem public override void Initialize() { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnRejuvenate); } - private void OnGetState(EntityUid uid, JitteringComponent component, ref ComponentGetState args) - { - args.State = new JitteringComponentState(component.Amplitude, component.Frequency); - } - - private void OnHandleState(EntityUid uid, JitteringComponent component, ref ComponentHandleState args) - { - if (args.Current is not JitteringComponentState jitteringState) - return; - - component.Amplitude = jitteringState.Amplitude; - component.Frequency = jitteringState.Frequency; - } - private void OnRejuvenate(EntityUid uid, JitteringComponent component, RejuvenateEvent args) { EntityManager.RemoveComponentDeferred(uid); diff --git a/Content.Shared/Lathe/LatheComponent.cs b/Content.Shared/Lathe/LatheComponent.cs index 411695b46d5..410db3c86f9 100644 --- a/Content.Shared/Lathe/LatheComponent.cs +++ b/Content.Shared/Lathe/LatheComponent.cs @@ -2,42 +2,42 @@ using Content.Shared.Research.Prototypes; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.Prototypes; namespace Content.Shared.Lathe { - [RegisterComponent, NetworkedComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class LatheComponent : Component { /// /// All of the recipes that the lathe has by default /// - [DataField("staticRecipes", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List StaticRecipes = new(); + [DataField] + public List> StaticRecipes = new(); /// /// All of the recipes that the lathe is capable of researching /// - [DataField("dynamicRecipes", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List DynamicRecipes = new(); + [DataField] + public List> DynamicRecipes = new(); /// /// The lathe's construction queue /// - [DataField("queue")] + [DataField] public List Queue = new(); /// /// The sound that plays when the lathe is producing an item, if any /// - [DataField("producingSound")] + [DataField] public SoundSpecifier? ProducingSound; + #region Visualizer info - [DataField("idleState", required: true)] + [DataField(required: true)] public string IdleState = default!; - [DataField("runningState", required: true)] + [DataField(required: true)] public string RunningState = default!; #endregion @@ -50,7 +50,7 @@ public sealed partial class LatheComponent : Component /// /// Whether the lathe can eject the materials stored within it /// - [DataField("canEjectStoredMaterials")] + [DataField] public bool CanEjectStoredMaterials = true; #region MachineUpgrading @@ -63,31 +63,31 @@ public sealed partial class LatheComponent : Component /// /// The machine part that reduces how long it takes to print a recipe. /// - [DataField("machinePartPrintSpeed", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MachinePartPrintTime = "Manipulator"; + [DataField] + public ProtoId MachinePartPrintSpeed = "Manipulator"; /// /// The value that is used to calculate the modified /// - [DataField("partRatingPrintTimeMultiplier")] + [DataField] public float PartRatingPrintTimeMultiplier = 0.5f; /// /// A modifier that changes how much of a material is needed to print a recipe /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float MaterialUseMultiplier = 1; /// /// The machine part that reduces how much material it takes to print a recipe. /// - [DataField("machinePartMaterialUse", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MachinePartMaterialUse = "MatterBin"; + [DataField] + public ProtoId MachinePartMaterialUse = "MatterBin"; /// /// The value that is used to calculate the modifier /// - [DataField("partRatingMaterialUseMultiplier")] + [DataField] public float PartRatingMaterialUseMultiplier = DefaultPartRatingMaterialUseMultiplier; public const float DefaultPartRatingMaterialUseMultiplier = 0.85f; @@ -98,7 +98,7 @@ public sealed class LatheGetRecipesEvent : EntityEventArgs { public readonly EntityUid Lathe; - public List Recipes = new(); + public List> Recipes = new(); public LatheGetRecipesEvent(EntityUid lathe) { diff --git a/Content.Shared/Lathe/LatheMessages.cs b/Content.Shared/Lathe/LatheMessages.cs index 7b28c3f5b09..820c496d30c 100644 --- a/Content.Shared/Lathe/LatheMessages.cs +++ b/Content.Shared/Lathe/LatheMessages.cs @@ -1,4 +1,5 @@ using Content.Shared.Research.Prototypes; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Lathe; @@ -6,13 +7,13 @@ namespace Content.Shared.Lathe; [Serializable, NetSerializable] public sealed class LatheUpdateState : BoundUserInterfaceState { - public List Recipes; + public List> Recipes; public List Queue; public LatheRecipePrototype? CurrentlyProducing; - public LatheUpdateState(List recipes, List queue, LatheRecipePrototype? currentlyProducing = null) + public LatheUpdateState(List> recipes, List queue, LatheRecipePrototype? currentlyProducing = null) { Recipes = recipes; Queue = queue; diff --git a/Content.Shared/Lathe/SharedLatheSystem.cs b/Content.Shared/Lathe/SharedLatheSystem.cs index e31925ec6d8..e9482d24d15 100644 --- a/Content.Shared/Lathe/SharedLatheSystem.cs +++ b/Content.Shared/Lathe/SharedLatheSystem.cs @@ -2,10 +2,7 @@ using Content.Shared.Materials; using Content.Shared.Research.Prototypes; using JetBrains.Annotations; -using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; -using System.Net.Mail; namespace Content.Shared.Lathe; @@ -21,23 +18,9 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnEmagged); } - private void OnGetState(EntityUid uid, LatheComponent component, ref ComponentGetState args) - { - args.State = new LatheComponentState(component.MaterialUseMultiplier); - } - - private void OnHandleState(EntityUid uid, LatheComponent component, ref ComponentHandleState args) - { - if (args.Current is not LatheComponentState state) - return; - component.MaterialUseMultiplier = state.MaterialUseMultiplier; - } - [PublicAPI] public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null) { @@ -71,14 +54,3 @@ public static int AdjustMaterial(int original, bool reduce, float multiplier) protected abstract bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component); } - -[Serializable, NetSerializable] -public sealed class LatheComponentState : ComponentState -{ - public float MaterialUseMultiplier; - - public LatheComponentState(float materialUseMultiplier) - { - MaterialUseMultiplier = materialUseMultiplier; - } -} diff --git a/Content.Shared/Materials/InsertingMaterialStorageComponent.cs b/Content.Shared/Materials/InsertingMaterialStorageComponent.cs index e841853c8e1..007dc73345d 100644 --- a/Content.Shared/Materials/InsertingMaterialStorageComponent.cs +++ b/Content.Shared/Materials/InsertingMaterialStorageComponent.cs @@ -1,31 +1,18 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Materials; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class InsertingMaterialStorageComponent : Component { /// /// The time when insertion ends. /// - [DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public TimeSpan EndTime; - [ViewVariables] + [ViewVariables, AutoNetworkedField] public Color? MaterialColor; } - -[Serializable, NetSerializable] -public sealed class InsertingMaterialStorageComponentState : ComponentState -{ - public TimeSpan EndTime; - public Color? MaterialColor; - - public InsertingMaterialStorageComponentState(TimeSpan endTime, Color? materialColor) - { - EndTime = endTime; - MaterialColor = materialColor; - } -} diff --git a/Content.Shared/Materials/MaterialReclaimerComponent.cs b/Content.Shared/Materials/MaterialReclaimerComponent.cs index 61081763528..761469f99aa 100644 --- a/Content.Shared/Materials/MaterialReclaimerComponent.cs +++ b/Content.Shared/Materials/MaterialReclaimerComponent.cs @@ -3,9 +3,9 @@ using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Materials; @@ -13,27 +13,28 @@ namespace Content.Shared.Materials; /// This is a machine that handles converting entities /// into the raw materials and chemicals that make them up. /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedMaterialReclaimerSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedMaterialReclaimerSystem))] public sealed partial class MaterialReclaimerComponent : Component { /// /// Whether or not the machine has power. We put it here /// so we can network and predict it. /// - [DataField("powered"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public bool Powered; /// /// An "enable" toggle for things like interfacing with machine linking /// - [DataField("enabled"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public bool Enabled = true; /// /// How efficiently the materials are reclaimed. /// In practice, a multiplier per material when calculating the output of the reclaimer. /// - [DataField("efficiency"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float Efficiency = 1f; /// @@ -41,46 +42,46 @@ public sealed partial class MaterialReclaimerComponent : Component /// speed scales with the amount of materials being processed /// or if it's just /// - [DataField("scaleProcessSpeed")] + [DataField] public bool ScaleProcessSpeed = true; /// /// How quickly it takes to consume X amount of materials per second. /// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process. /// - [DataField("baseMaterialProcessRate"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float BaseMaterialProcessRate = 100f; /// /// How quickly it takes to consume X amount of materials per second. /// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process. /// - [DataField("materialProcessRate"), ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public float MaterialProcessRate = 100f; /// /// Machine part whose rating modifies /// - [DataField("machinePartProcessRate", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)] - public string MachinePartProcessRate = "Manipulator"; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public ProtoId MachinePartProcessRate = "Manipulator"; /// /// How much the machine part quality affects the /// - [DataField("partRatingProcessRateMultiplier"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float PartRatingProcessRateMultiplier = 1.5f; /// /// The minimum amount fo time it can take to process an entity. /// this value supercedes the calculated one using /// - [DataField("minimumProcessDuration"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public TimeSpan MinimumProcessDuration = TimeSpan.FromSeconds(0.5f); /// /// The id of our output solution /// - [DataField("solutionContainerId"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public string SolutionContainerId = "output"; /// @@ -92,37 +93,37 @@ public sealed partial class MaterialReclaimerComponent : Component /// /// a whitelist for what entities can be inserted into this reclaimer /// - [DataField("whitelist")] + [DataField] public EntityWhitelist? Whitelist; /// /// a blacklist for what entities cannot be inserted into this reclaimer /// - [DataField("blacklist")] + [DataField] public EntityWhitelist? Blacklist; /// /// The sound played when something is being processed. /// - [DataField("sound")] + [DataField] public SoundSpecifier? Sound; /// /// whether or not we cut off the sound early when the reclaiming ends. /// - [DataField("cutOffSound")] + [DataField] public bool CutOffSound = true; /// /// When the next sound will be allowed to be played. Used to prevent spam. /// - [DataField("nextSound", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan NextSound; /// /// Minimum time inbetween each /// - [DataField("soundCooldown")] + [DataField] public TimeSpan SoundCooldown = TimeSpan.FromSeconds(0.8f); public IPlayingAudioStream? Stream; @@ -133,30 +134,10 @@ public sealed partial class MaterialReclaimerComponent : Component /// /// I saw this on the recycler and i'm porting it because it's cute af /// - [DataField("itemsProcessed")] + [DataField, AutoNetworkedField] public int ItemsProcessed; } -[Serializable, NetSerializable] -public sealed class MaterialReclaimerComponentState : ComponentState -{ - public bool Powered; - - public bool Enabled; - - public float MaterialProcessRate; - - public int ItemsProcessed; - - public MaterialReclaimerComponentState(bool powered, bool enabled, float materialProcessRate, int itemsProcessed) - { - Powered = powered; - Enabled = enabled; - MaterialProcessRate = materialProcessRate; - ItemsProcessed = itemsProcessed; - } -} - [NetSerializable, Serializable] public enum RecyclerVisuals { diff --git a/Content.Shared/Materials/MaterialStorageComponent.cs b/Content.Shared/Materials/MaterialStorageComponent.cs index 50935bcd474..c905478bca3 100644 --- a/Content.Shared/Materials/MaterialStorageComponent.cs +++ b/Content.Shared/Materials/MaterialStorageComponent.cs @@ -1,67 +1,65 @@ using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Materials; +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedMaterialStorageSystem))] -[RegisterComponent, NetworkedComponent] public sealed partial class MaterialStorageComponent : Component { - [DataField("storage", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] - public Dictionary Storage { get; set; } = new(); + [DataField, AutoNetworkedField] + public Dictionary, int> Storage { get; set; } = new(); /// /// Whether or not interacting with the materialstorage inserts the material in hand. /// - [DataField("insertOnInteract")] + [DataField] public bool InsertOnInteract = true; /// /// How much material the storage can store in total. /// - [ViewVariables(VVAccess.ReadWrite), DataField("storageLimit")] + [ViewVariables(VVAccess.ReadWrite), DataField] public int? StorageLimit; /// /// Whitelist for specifying the kind of items that can be insert into this entity. /// - [DataField("whitelist")] - public EntityWhitelist? EntityWhitelist; + [DataField] + public EntityWhitelist? Whitelist; /// /// Whether or not to drop contained materials when deconstructed. /// - [DataField("dropOnDeconstruct")] + [DataField] public bool DropOnDeconstruct = true; /// /// Whitelist generated on runtime for what specific materials can be inserted into this entity. /// - [DataField("materialWhiteList", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List? MaterialWhiteList; + [DataField, AutoNetworkedField] + public List>? MaterialWhiteList; /// /// Whether or not the visualization for the insertion animation /// should ignore the color of the material being inserted. /// - [DataField("ignoreColor")] + [DataField] public bool IgnoreColor; /// /// The sound that plays when inserting an item into the storage /// - [DataField("insertingSound")] + [DataField] public SoundSpecifier? InsertingSound; /// /// How long the inserting animation will play /// - [DataField("insertionTime")] + [DataField] public TimeSpan InsertionTime = TimeSpan.FromSeconds(0.79f); // 0.01 off for animation timing } @@ -94,19 +92,5 @@ public record struct GetMaterialWhitelistEvent(EntityUid Storage) { public readonly EntityUid Storage = Storage; - public List Whitelist = new(); -} - -[Serializable, NetSerializable] -public sealed class MaterialStorageComponentState : ComponentState -{ - public Dictionary Storage; - - public List? MaterialWhitelist; - - public MaterialStorageComponentState(Dictionary storage, List? materialWhitelist) - { - Storage = storage; - MaterialWhitelist = materialWhitelist; - } + public List> Whitelist = new(); } diff --git a/Content.Shared/Materials/SharedMaterialReclaimerSystem.cs b/Content.Shared/Materials/SharedMaterialReclaimerSystem.cs index 54ddc912896..3f5832f69a9 100644 --- a/Content.Shared/Materials/SharedMaterialReclaimerSystem.cs +++ b/Content.Shared/Materials/SharedMaterialReclaimerSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Mobs.Components; using Content.Shared.Stacks; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Physics.Events; using Robust.Shared.Timing; @@ -32,8 +31,6 @@ public abstract class SharedMaterialReclaimerSystem : EntitySystem /// public override void Initialize() { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnUnpaused); SubscribeLocalEvent(OnExamined); @@ -43,24 +40,6 @@ public override void Initialize() SubscribeLocalEvent(OnActiveUnpaused); } - private void OnGetState(EntityUid uid, MaterialReclaimerComponent component, ref ComponentGetState args) - { - args.State = new MaterialReclaimerComponentState(component.Powered, - component.Enabled, - component.MaterialProcessRate, - component.ItemsProcessed); - } - - private void OnHandleState(EntityUid uid, MaterialReclaimerComponent component, ref ComponentHandleState args) - { - if (args.Current is not MaterialReclaimerComponentState state) - return; - component.Powered = state.Powered; - component.Enabled = state.Enabled; - component.MaterialProcessRate = state.MaterialProcessRate; - component.ItemsProcessed = state.ItemsProcessed; - } - private void OnShutdown(EntityUid uid, MaterialReclaimerComponent component, ComponentShutdown args) { component.Stream?.Stop(); diff --git a/Content.Shared/Materials/SharedMaterialStorageSystem.cs b/Content.Shared/Materials/SharedMaterialStorageSystem.cs index e54ff3faa3e..9e6e000d622 100644 --- a/Content.Shared/Materials/SharedMaterialStorageSystem.cs +++ b/Content.Shared/Materials/SharedMaterialStorageSystem.cs @@ -3,7 +3,6 @@ using Content.Shared.Interaction.Components; using Content.Shared.Stacks; using JetBrains.Annotations; -using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -26,10 +25,6 @@ public override void Initialize() SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnInteractUsing); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - SubscribeLocalEvent(OnGetInsertingState); - SubscribeLocalEvent(OnHandleInsertingState); SubscribeLocalEvent(OnUnpaused); } @@ -52,36 +47,6 @@ private void OnMapInit(EntityUid uid, MaterialStorageComponent component, MapIni _appearance.SetData(uid, MaterialStorageVisuals.Inserting, false); } - private void OnGetState(EntityUid uid, MaterialStorageComponent component, ref ComponentGetState args) - { - args.State = new MaterialStorageComponentState(component.Storage, component.MaterialWhiteList); - } - - private void OnHandleState(EntityUid uid, MaterialStorageComponent component, ref ComponentHandleState args) - { - if (args.Current is not MaterialStorageComponentState state) - return; - - component.Storage = new Dictionary(state.Storage); - - if (state.MaterialWhitelist != null) - component.MaterialWhiteList = new List(state.MaterialWhitelist); - } - - private void OnGetInsertingState(EntityUid uid, InsertingMaterialStorageComponent component, ref ComponentGetState args) - { - args.State = new InsertingMaterialStorageComponentState(component.EndTime, component.MaterialColor); - } - - private void OnHandleInsertingState(EntityUid uid, InsertingMaterialStorageComponent component, ref ComponentHandleState args) - { - if (args.Current is not InsertingMaterialStorageComponentState state) - return; - - component.EndTime = state.EndTime; - component.MaterialColor = state.MaterialColor; - } - private void OnUnpaused(EntityUid uid, InsertingMaterialStorageComponent component, ref EntityUnpausedEvent args) { component.EndTime += args.PausedTime; @@ -222,7 +187,7 @@ public virtual bool TryInsertMaterialEntity(EntityUid user, if (!Resolve(toInsert, ref material, ref composition, false)) return false; - if (storage.EntityWhitelist?.IsValid(toInsert) == false) + if (storage.Whitelist?.IsValid(toInsert) == false) return false; if (HasComp(toInsert)) diff --git a/Content.Shared/Mech/Components/MechComponent.cs b/Content.Shared/Mech/Components/MechComponent.cs index ec8fc62dfba..9bf25f41644 100644 --- a/Content.Shared/Mech/Components/MechComponent.cs +++ b/Content.Shared/Mech/Components/MechComponent.cs @@ -3,9 +3,6 @@ using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Mech.Components; @@ -13,33 +10,33 @@ namespace Content.Shared.Mech.Components; /// A large, pilotable machine that has equipment that is /// powered via an internal battery. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MechComponent : Component { /// /// How much "health" the mech has left. /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public FixedPoint2 Integrity; /// /// The maximum amount of damage the mech can take. /// - [DataField("maxIntegrity")] + [DataField, AutoNetworkedField] public FixedPoint2 MaxIntegrity = 250; /// /// How much energy the mech has. /// Derived from the currently inserted battery. /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public FixedPoint2 Energy = 0; /// /// The maximum amount of energy the mech can have. /// Derived from the currently inserted battery. /// - [DataField("maxEnergy")] + [DataField, AutoNetworkedField] public FixedPoint2 MaxEnergy = 0; /// @@ -55,13 +52,13 @@ public sealed partial class MechComponent : Component /// A multiplier used to calculate how much of the damage done to a mech /// is transfered to the pilot /// - [DataField("mechToPilotDamageMultiplier")] + [DataField] public float MechToPilotDamageMultiplier; /// /// Whether the mech has been destroyed and is no longer pilotable. /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public bool Broken = false; /// @@ -77,7 +74,7 @@ public sealed partial class MechComponent : Component /// The current selected equipment of the mech. /// If null, the mech is using just its fists. /// - [ViewVariables] + [ViewVariables, AutoNetworkedField] public EntityUid? CurrentSelectedEquipment; /// @@ -89,10 +86,10 @@ public sealed partial class MechComponent : Component /// /// A whitelist for inserting equipment items. /// - [DataField("equipmentWhitelist")] + [DataField] public EntityWhitelist? EquipmentWhitelist; - [DataField("pilotWhitelist")] + [DataField] public EntityWhitelist? PilotWhitelist; /// @@ -107,20 +104,20 @@ public sealed partial class MechComponent : Component /// /// How long it takes to enter the mech. /// - [DataField("entryDelay")] + [DataField] public float EntryDelay = 3; /// /// How long it takes to pull *another person* /// outside of the mech. You can exit instantly yourself. /// - [DataField("exitDelay")] + [DataField] public float ExitDelay = 3; /// /// How long it takes to pull out the battery. /// - [DataField("batteryRemovalDelay")] + [DataField] public float BatteryRemovalDelay = 2; /// @@ -130,31 +127,31 @@ public sealed partial class MechComponent : Component /// This needs to be redone /// when mech internals are added /// - [DataField("airtight"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool Airtight; /// /// The equipment that the mech initially has when it spawns. /// Good for things like nukie mechs that start with guns. /// - [DataField("startingEquipment", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List StartingEquipment = new(); + [DataField] + public List StartingEquipment = new(); #region Action Prototypes - [DataField("mechCycleAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MechCycleAction = "ActionMechCycleEquipment"; - [DataField("mechUiAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MechUiAction = "ActionMechOpenUI"; - [DataField("mechEjectAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MechEjectAction = "ActionMechEject"; + [DataField] + public EntProtoId MechCycleAction = "ActionMechCycleEquipment"; + [DataField] + public EntProtoId MechUiAction = "ActionMechOpenUI"; + [DataField] + public EntProtoId MechEjectAction = "ActionMechEject"; #endregion #region Visualizer States - [DataField("baseState")] + [DataField] public string? BaseState; - [DataField("openState")] + [DataField] public string? OpenState; - [DataField("brokenState")] + [DataField] public string? BrokenState; #endregion @@ -162,17 +159,3 @@ public sealed partial class MechComponent : Component [DataField] public EntityUid? MechUiActionEntity; [DataField] public EntityUid? MechEjectActionEntity; } - -/// -/// Contains network state for . -/// -[Serializable, NetSerializable] -public sealed class MechComponentState : ComponentState -{ - public FixedPoint2 Integrity; - public FixedPoint2 MaxIntegrity; - public FixedPoint2 Energy; - public FixedPoint2 MaxEnergy; - public NetEntity? CurrentSelectedEquipment; - public bool Broken; -} diff --git a/Content.Shared/Mech/Components/MechPilotComponent.cs b/Content.Shared/Mech/Components/MechPilotComponent.cs index 364bd0bf14b..64bf7082b71 100644 --- a/Content.Shared/Mech/Components/MechPilotComponent.cs +++ b/Content.Shared/Mech/Components/MechPilotComponent.cs @@ -1,5 +1,4 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Mech.Components; @@ -9,18 +8,12 @@ namespace Content.Shared.Mech.Components; /// /// Get in the robot, Shinji /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MechPilotComponent : Component { /// /// The mech being piloted /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public EntityUid Mech; } - -[Serializable, NetSerializable] -public sealed class MechPilotComponentState : ComponentState -{ - public NetEntity Mech; -} diff --git a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs index 7111c67779a..1cb08e1a253 100644 --- a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs +++ b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs @@ -16,7 +16,6 @@ using Content.Shared.Popups; using Content.Shared.Weapons.Melee; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Serialization; using Robust.Shared.Timing; @@ -42,11 +41,6 @@ public abstract class SharedMechSystem : EntitySystem /// public override void Initialize() { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - SubscribeLocalEvent(OnPilotGetState); - SubscribeLocalEvent(OnPilotHandleState); - SubscribeLocalEvent(OnToggleEquipmentAction); SubscribeLocalEvent(OnEjectPilotEvent); SubscribeLocalEvent(RelayInteractionEvent); @@ -59,52 +53,6 @@ public override void Initialize() SubscribeLocalEvent(OnAttackAttempt); } - #region State Handling - - private void OnGetState(EntityUid uid, MechComponent component, ref ComponentGetState args) - { - args.State = new MechComponentState - { - Integrity = component.Integrity, - MaxIntegrity = component.MaxIntegrity, - Energy = component.Energy, - MaxEnergy = component.MaxEnergy, - CurrentSelectedEquipment = GetNetEntity(component.CurrentSelectedEquipment), - Broken = component.Broken - }; - } - - private void OnHandleState(EntityUid uid, MechComponent component, ref ComponentHandleState args) - { - if (args.Current is not MechComponentState state) - return; - - component.Integrity = state.Integrity; - component.MaxIntegrity = state.MaxIntegrity; - component.Energy = state.Energy; - component.MaxEnergy = state.MaxEnergy; - component.CurrentSelectedEquipment = EnsureEntity(state.CurrentSelectedEquipment, uid); - component.Broken = state.Broken; - } - - private void OnPilotGetState(EntityUid uid, MechPilotComponent component, ref ComponentGetState args) - { - args.State = new MechPilotComponentState - { - Mech = GetNetEntity(component.Mech) - }; - } - - private void OnPilotHandleState(EntityUid uid, MechPilotComponent component, ref ComponentHandleState args) - { - if (args.Current is not MechPilotComponentState state) - return; - - component.Mech = EnsureEntity(state.Mech, uid); - } - - #endregion - private void OnToggleEquipmentAction(EntityUid uid, MechComponent component, MechToggleEquipmentEvent args) { if (args.Handled) diff --git a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs index 340a1627d6d..4442d87d885 100644 --- a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs +++ b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs @@ -1,4 +1,5 @@ using Content.Shared.Bed.Sleep; +using Content.Shared.Damage.ForceSay; using Content.Shared.Emoting; using Content.Shared.Hands; using Content.Shared.Interaction; @@ -27,7 +28,7 @@ private void SubscribeEvents() SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); - SubscribeLocalEvent(CheckAct); + SubscribeLocalEvent(OnSpeakAttempt); SubscribeLocalEvent(OnEquipAttempt); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(OnUnequipAttempt); @@ -116,6 +117,17 @@ private void OnGettingStripped(EntityUid target, MobStateComponent component, Be args.Multiplier /= 2; } + private void OnSpeakAttempt(EntityUid uid, MobStateComponent component, SpeakAttemptEvent args) + { + if (HasComp(uid)) + { + RemCompDeferred(uid); + return; + } + + CheckAct(uid, component, args); + } + private void CheckAct(EntityUid target, MobStateComponent component, CancellableEntityEventArgs args) { switch (component.CurrentState) diff --git a/Content.Shared/Mobs/Systems/MobThresholdSystem.cs b/Content.Shared/Mobs/Systems/MobThresholdSystem.cs index 1cb32543ebb..f34240d8fe3 100644 --- a/Content.Shared/Mobs/Systems/MobThresholdSystem.cs +++ b/Content.Shared/Mobs/Systems/MobThresholdSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.FixedPoint; using Content.Shared.Mobs.Components; using Robust.Shared.GameStates; -using Robust.Shared.Utility; namespace Content.Shared.Mobs.Systems; @@ -52,6 +51,38 @@ private void OnHandleState(EntityUid uid, MobThresholdsComponent component, ref #region Public API + /// + /// Gets the next available state for a mob. + /// + /// Target entity + /// Supplied MobState + /// The following MobState. Can be null if there isn't one. + /// Threshold Component Owned by the target + /// True if the next mob state exists + public bool TryGetNextState( + EntityUid target, + MobState mobState, + [NotNullWhen(true)] out MobState? nextState, + MobThresholdsComponent? thresholdsComponent = null) + { + nextState = null; + if (!Resolve(target, ref thresholdsComponent)) + return false; + + MobState? min = null; + foreach (var state in thresholdsComponent.Thresholds.Values) + { + if (state <= mobState) + continue; + + if (min == null || state < min) + min = state; + } + + nextState = min; + return nextState != null; + } + /// /// Get the Damage Threshold for the appropriate state if it exists /// @@ -261,7 +292,7 @@ public void SetMobStateThreshold(EntityUid target, FixedPoint2 damage, MobState threshold.Thresholds.Remove(damageThreshold); } threshold.Thresholds[damage] = mobState; - Dirty(threshold); + Dirty(target, threshold); VerifyThresholds(target, threshold); } @@ -291,7 +322,7 @@ public void SetAllowRevives(EntityUid uid, bool val, MobThresholdsComponent? com if (!Resolve(uid, ref component, false)) return; component.AllowRevives = val; - Dirty(component); + Dirty(uid, component); VerifyThresholds(uid, component); } @@ -344,42 +375,37 @@ private void UpdateAlerts(EntityUid target, MobState currentMobState, MobThresho if (!threshold.TriggersAlerts) return; - var dict = threshold.StateAlertDict; - var healthAlert = AlertType.HumanHealth; - var critAlert = AlertType.HumanCrit; - var deadAlert = AlertType.HumanDead; + if (!threshold.StateAlertDict.TryGetValue(currentMobState, out var currentAlert)) + { + Log.Error($"No alert alert for mob state {currentMobState} for entity {ToPrettyString(target)}"); + return; + } - dict.TryGetValue(MobState.Alive, out healthAlert); - dict.TryGetValue(MobState.Critical, out critAlert); - dict.TryGetValue(MobState.Dead, out deadAlert); + if (!_alerts.TryGet(currentAlert, out var alertPrototype)) + { + Log.Error($"Invalid alert type {currentAlert}"); + return; + } - switch (currentMobState) + if (alertPrototype.SupportsSeverity) { - case MobState.Alive: + var severity = _alerts.GetMinSeverity(currentAlert); + if (TryGetNextState(target, currentMobState, out var nextState, threshold) && + TryGetPercentageForState(target, nextState.Value, damageable.TotalDamage, out var percentage)) { - var severity = _alerts.GetMinSeverity(healthAlert); - if (TryGetIncapPercentage(target, damageable.TotalDamage, out var percentage)) - { - severity = (short) MathF.Floor(percentage.Value.Float() * - _alerts.GetSeverityRange(healthAlert)); - severity += _alerts.GetMinSeverity(healthAlert); - } - _alerts.ShowAlert(target, healthAlert, severity); - break; - } - case MobState.Critical: - { - _alerts.ShowAlert(target, critAlert); - break; - } - case MobState.Dead: - { - _alerts.ShowAlert(target, deadAlert); - break; + percentage = FixedPoint2.Clamp(percentage.Value, 0, 1); + + severity = (short) MathF.Round( + MathHelper.Lerp( + _alerts.GetMinSeverity(currentAlert), + _alerts.GetMaxSeverity(currentAlert), + percentage.Value.Float())); } - case MobState.Invalid: - default: - throw new ArgumentOutOfRangeException(nameof(currentMobState), currentMobState, null); + _alerts.ShowAlert(target, currentAlert, severity); + } + else + { + _alerts.ShowAlert(target, currentAlert); } } diff --git a/Content.Shared/Movement/Components/FootstepModifierComponent.cs b/Content.Shared/Movement/Components/FootstepModifierComponent.cs index 88563276336..bd7b5377bd4 100644 --- a/Content.Shared/Movement/Components/FootstepModifierComponent.cs +++ b/Content.Shared/Movement/Components/FootstepModifierComponent.cs @@ -1,15 +1,14 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; -namespace Content.Shared.Movement.Components +namespace Content.Shared.Movement.Components; + +/// +/// Changes footstep sound +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class FootstepModifierComponent : Component { - /// - /// Changes footstep sound - /// - [RegisterComponent, NetworkedComponent] - public sealed partial class FootstepModifierComponent : Component - { - [DataField("footstepSoundCollection", required: true)] - public SoundSpecifier Sound = default!; - } + [DataField(required: true), AutoNetworkedField] + public SoundSpecifier FootstepSoundCollection = default!; } diff --git a/Content.Shared/Movement/Components/InputMoverComponent.cs b/Content.Shared/Movement/Components/InputMoverComponent.cs index 1a987a9b29f..5562bfaee40 100644 --- a/Content.Shared/Movement/Components/InputMoverComponent.cs +++ b/Content.Shared/Movement/Components/InputMoverComponent.cs @@ -6,8 +6,7 @@ namespace Content.Shared.Movement.Components { - [RegisterComponent] - [NetworkedComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class InputMoverComponent : Component { // This class has to be able to handle server TPS being lower than client FPS. @@ -41,36 +40,40 @@ public sealed partial class InputMoverComponent : Component public Vector2 CurTickWalkMovement; public Vector2 CurTickSprintMovement; + [AutoNetworkedField] public MoveButtons HeldMoveButtons = MoveButtons.None; /// /// Entity our movement is relative to. /// + [AutoNetworkedField] public EntityUid? RelativeEntity; /// /// Although our movement might be relative to a particular entity we may have an additional relative rotation /// e.g. if we've snapped to a different cardinal direction /// - [ViewVariables] + [ViewVariables, AutoNetworkedField] public Angle TargetRelativeRotation = Angle.Zero; /// /// The current relative rotation. This will lerp towards the . /// - [ViewVariables] public Angle RelativeRotation; + [ViewVariables, AutoNetworkedField] + public Angle RelativeRotation; /// /// If we traverse on / off a grid then set a timer to update our relative inputs. /// - [ViewVariables(VVAccess.ReadWrite), DataField("lerpTarget", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public TimeSpan LerpTarget; public const float LerpTime = 1.0f; public bool Sprinting => (HeldMoveButtons & MoveButtons.Walk) == 0x0; - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public bool CanMove { get; set; } = true; } } diff --git a/Content.Shared/Movement/Components/JetpackUserComponent.cs b/Content.Shared/Movement/Components/JetpackUserComponent.cs index b59b677b62e..972f8c69c6a 100644 --- a/Content.Shared/Movement/Components/JetpackUserComponent.cs +++ b/Content.Shared/Movement/Components/JetpackUserComponent.cs @@ -5,8 +5,9 @@ namespace Content.Shared.Movement.Components; /// /// Added to someone using a jetpack for movement purposes /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class JetpackUserComponent : Component { + [AutoNetworkedField] public EntityUid Jetpack; } diff --git a/Content.Shared/Movement/Components/MobMoverComponent.cs b/Content.Shared/Movement/Components/MobMoverComponent.cs index e833f2d4b7d..a77f415b938 100644 --- a/Content.Shared/Movement/Components/MobMoverComponent.cs +++ b/Content.Shared/Movement/Components/MobMoverComponent.cs @@ -6,14 +6,13 @@ namespace Content.Shared.Movement.Components /// /// Has additional movement data such as footsteps and weightless grab range for an entity. /// - [RegisterComponent] - [NetworkedComponent()] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MobMoverComponent : Component { private float _stepSoundDistance; - [DataField("grabRange")] public float GrabRange = 1.0f; + [DataField] public float GrabRange = 1.0f; - [DataField("pushStrength")] public float PushStrength = 600f; + [DataField] public float PushStrength = 600f; [ViewVariables(VVAccess.ReadWrite)] public EntityCoordinates LastPosition { get; set; } @@ -32,7 +31,7 @@ public float StepSoundDistance } } - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float GrabRangeVV { get => GrabRange; @@ -44,7 +43,7 @@ public float GrabRangeVV } } - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public float PushStrengthVV { get => PushStrength; diff --git a/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs b/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs index 33270c2034b..7efc12a7316 100644 --- a/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs +++ b/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs @@ -7,8 +7,8 @@ namespace Content.Shared.Movement.Components /// Applies basic movement speed and movement modifiers for an entity. /// If this is not present on the entity then they will use defaults for movement. /// - [RegisterComponent] - [NetworkedComponent, Access(typeof(MovementSpeedModifierSystem))] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] + [Access(typeof(MovementSpeedModifierSystem))] public sealed partial class MovementSpeedModifierComponent : Component { // Weightless @@ -25,10 +25,10 @@ public sealed partial class MovementSpeedModifierComponent : Component public const float DefaultBaseWalkSpeed = 2.5f; public const float DefaultBaseSprintSpeed = 4.5f; - [ViewVariables] + [AutoNetworkedField, ViewVariables] public float WalkSpeedModifier = 1.0f; - [ViewVariables] + [AutoNetworkedField, ViewVariables] public float SprintSpeedModifier = 1.0f; [ViewVariables(VVAccess.ReadWrite)] @@ -56,55 +56,56 @@ private float _baseSprintSpeedVV /// /// Minimum speed a mob has to be moving before applying movement friction. /// - [ViewVariables(VVAccess.ReadWrite), DataField("minimumFrictionSpeed")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float MinimumFrictionSpeed = DefaultMinimumFrictionSpeed; /// /// The negative velocity applied for friction when weightless and providing inputs. /// - [ViewVariables(VVAccess.ReadWrite), DataField("weightlessFriction")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float WeightlessFriction = DefaultWeightlessFriction; /// /// The negative velocity applied for friction when weightless and not providing inputs. /// This is essentially how much their speed decreases per second. /// - [ViewVariables(VVAccess.ReadWrite), DataField("weightlessFrictionNoInput")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float WeightlessFrictionNoInput = DefaultWeightlessFrictionNoInput; /// /// The movement speed modifier applied to a mob's total input velocity when weightless. /// - [ViewVariables(VVAccess.ReadWrite), DataField("weightlessModifier")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float WeightlessModifier = DefaultWeightlessModifier; /// /// The acceleration applied to mobs when moving and weightless. /// - [ViewVariables(VVAccess.ReadWrite), DataField("weightlessAcceleration")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float WeightlessAcceleration = DefaultWeightlessAcceleration; /// /// The acceleration applied to mobs when moving. /// - [ViewVariables(VVAccess.ReadWrite), DataField("acceleration")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float Acceleration = DefaultAcceleration; /// /// The negative velocity applied for friction. /// - [ViewVariables(VVAccess.ReadWrite), DataField("friction")] + [ViewVariables(VVAccess.ReadWrite), DataField] public float Friction = DefaultFriction; /// /// The negative velocity applied for friction. /// - [ViewVariables(VVAccess.ReadWrite), DataField("frictionNoInput")] public float? FrictionNoInput = null; + [ViewVariables(VVAccess.ReadWrite), DataField] + public float? FrictionNoInput; - [ViewVariables(VVAccess.ReadWrite), DataField("baseWalkSpeed")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float BaseWalkSpeed { get; set; } = DefaultBaseWalkSpeed; - [ViewVariables(VVAccess.ReadWrite), DataField("baseSprintSpeed")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float BaseSprintSpeed { get; set; } = DefaultBaseSprintSpeed; [ViewVariables] diff --git a/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs b/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs index a83fcf78b2c..c95ab379c6b 100644 --- a/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs +++ b/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs @@ -1,9 +1,6 @@ using Content.Shared.Inventory; using Content.Shared.Movement.Components; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Timing; -using Robust.Shared.Utility; namespace Content.Shared.Movement.Systems { @@ -11,33 +8,6 @@ public sealed class MovementSpeedModifierSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnGetState(EntityUid uid, MovementSpeedModifierComponent component, ref ComponentGetState args) - { - args.State = new MovementSpeedModifierComponentState - { - BaseWalkSpeed = component.BaseWalkSpeed, - BaseSprintSpeed = component.BaseSprintSpeed, - WalkSpeedModifier = component.WalkSpeedModifier, - SprintSpeedModifier = component.SprintSpeedModifier, - }; - } - - private void OnHandleState(EntityUid uid, MovementSpeedModifierComponent component, ref ComponentHandleState args) - { - if (args.Current is not MovementSpeedModifierComponentState state) return; - component.BaseWalkSpeed = state.BaseWalkSpeed; - component.BaseSprintSpeed = state.BaseSprintSpeed; - component.WalkSpeedModifier = state.WalkSpeedModifier; - component.SprintSpeedModifier = state.SprintSpeedModifier; - } - public void RefreshMovementSpeedModifiers(EntityUid uid, MovementSpeedModifierComponent? move = null) { if (!Resolve(uid, ref move, false)) @@ -68,15 +38,6 @@ public void ChangeBaseSpeed(EntityUid uid, float baseWalkSpeed, float baseSprint move.Acceleration = acceleration; Dirty(move); } - - [Serializable, NetSerializable] - private sealed class MovementSpeedModifierComponentState : ComponentState - { - public float BaseWalkSpeed; - public float BaseSprintSpeed; - public float WalkSpeedModifier; - public float SprintSpeedModifier; - } } /// diff --git a/Content.Shared/Movement/Systems/SharedJetpackSystem.cs b/Content.Shared/Movement/Systems/SharedJetpackSystem.cs index 26373da2567..f624f6c4ce4 100644 --- a/Content.Shared/Movement/Systems/SharedJetpackSystem.cs +++ b/Content.Shared/Movement/Systems/SharedJetpackSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Movement.Events; using Content.Shared.Popups; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Serialization; @@ -31,8 +30,6 @@ public override void Initialize() SubscribeLocalEvent(OnJetpackUserCanWeightless); SubscribeLocalEvent(OnJetpackUserEntParentChanged); - SubscribeLocalEvent(OnJetpackUserGetState); - SubscribeLocalEvent(OnJetpackUserHandleState); SubscribeLocalEvent(OnJetpackUserGravityChanged); } @@ -60,22 +57,6 @@ private void OnJetpackUserGravityChanged(ref GravityChangedEvent ev) } } - private void OnJetpackUserHandleState(EntityUid uid, JetpackUserComponent component, ref ComponentHandleState args) - { - if (args.Current is not JetpackUserComponentState state) - return; - - component.Jetpack = EnsureEntity(state.Jetpack, uid); - } - - private void OnJetpackUserGetState(EntityUid uid, JetpackUserComponent component, ref ComponentGetState args) - { - args.State = new JetpackUserComponentState() - { - Jetpack = GetNetEntity(component.Jetpack), - }; - } - private void OnJetpackDropped(EntityUid uid, JetpackComponent component, DroppedEvent args) { SetEnabled(uid, component, false, args.User); @@ -204,12 +185,6 @@ protected virtual bool CanEnable(EntityUid uid, JetpackComponent component) { return true; } - - [Serializable, NetSerializable] - protected sealed class JetpackUserComponentState : ComponentState - { - public NetEntity Jetpack; - } } [Serializable, NetSerializable] diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Footsteps.cs b/Content.Shared/Movement/Systems/SharedMoverController.Footsteps.cs deleted file mode 100644 index bbaf2250ecb..00000000000 --- a/Content.Shared/Movement/Systems/SharedMoverController.Footsteps.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Content.Shared.Movement.Components; -using Robust.Shared.Audio; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Movement.Systems; - -public abstract partial class SharedMoverController -{ - private void InitializeFootsteps() - { - SubscribeLocalEvent(OnFootGetState); - SubscribeLocalEvent(OnFootHandleState); - } - - private void OnFootHandleState(EntityUid uid, FootstepModifierComponent component, ref ComponentHandleState args) - { - if (args.Current is not FootstepModifierComponentState state) return; - component.Sound = state.Sound; - } - - private void OnFootGetState(EntityUid uid, FootstepModifierComponent component, ref ComponentGetState args) - { - args.State = new FootstepModifierComponentState() - { - Sound = component.Sound, - }; - } - - [Serializable, NetSerializable] - private sealed class FootstepModifierComponentState : ComponentState - { - public SoundSpecifier Sound = default!; - } -} diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 9d150a0652b..425322408ef 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -4,7 +4,6 @@ using Content.Shared.Input; using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; -using Robust.Shared.GameStates; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Players; @@ -49,8 +48,7 @@ private void InitializeInput() .Register(); SubscribeLocalEvent(OnInputInit); - SubscribeLocalEvent(OnInputGetState); - SubscribeLocalEvent(OnInputHandleState); + SubscribeLocalEvent(OnInputHandleState); SubscribeLocalEvent(OnInputParentChange); SubscribeLocalEvent(OnAutoParentChange); @@ -75,31 +73,10 @@ protected void SetMoveInput(InputMoverComponent component, MoveButtons buttons) Dirty(component); } - private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref ComponentHandleState args) + private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not InputMoverComponentState state) - return; - - component.HeldMoveButtons = state.Buttons; component.LastInputTick = GameTick.Zero; component.LastInputSubTick = 0; - component.CanMove = state.CanMove; - - component.RelativeRotation = state.RelativeRotation; - component.TargetRelativeRotation = state.TargetRelativeRotation; - component.RelativeEntity = EnsureEntity(state.RelativeEntity, uid); - component.LerpTarget = state.LerpAccumulator; - } - - private void OnInputGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args) - { - args.State = new InputMoverComponentState( - component.HeldMoveButtons, - component.CanMove, - component.RelativeRotation, - component.TargetRelativeRotation, - GetNetEntity(component.RelativeEntity), - component.LerpTarget); } private void ShutdownInput() @@ -564,35 +541,6 @@ public override bool HandleCmdMessage(IEntityManager entManager, ICommonSession? } } - [Serializable, NetSerializable] - private sealed class InputMoverComponentState : ComponentState - { - public MoveButtons Buttons { get; } - public readonly bool CanMove; - - /// - /// Our current rotation for movement purposes. This is lerping towards - /// - public Angle RelativeRotation; - - /// - /// Target rotation relative to the . Typically 0 - /// - public Angle TargetRelativeRotation; - public NetEntity? RelativeEntity; - public TimeSpan LerpAccumulator; - - public InputMoverComponentState(MoveButtons buttons, bool canMove, Angle relativeRotation, Angle targetRelativeRotation, NetEntity? relativeEntity, TimeSpan lerpTarget) - { - Buttons = buttons; - CanMove = canMove; - RelativeRotation = relativeRotation; - TargetRelativeRotation = targetRelativeRotation; - RelativeEntity = relativeEntity; - LerpAccumulator = lerpTarget; - } - } - private sealed class ShuttleInputCmdHandler : InputCmdHandler { private readonly SharedMoverController _controller; @@ -615,6 +563,7 @@ public override bool HandleCmdMessage(IEntityManager entManager, ICommonSession? } [Flags] + [Serializable, NetSerializable] public enum MoveButtons : byte { None = 0, diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Mob.cs b/Content.Shared/Movement/Systems/SharedMoverController.Mob.cs deleted file mode 100644 index 9f6c2f4a486..00000000000 --- a/Content.Shared/Movement/Systems/SharedMoverController.Mob.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Shared.Movement.Components; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Movement.Systems; - -public abstract partial class SharedMoverController -{ - private void InitializeMob() - { - SubscribeLocalEvent(OnMobGetState); - SubscribeLocalEvent(OnMobHandleState); - } - - private void OnMobHandleState(EntityUid uid, MobMoverComponent component, ref ComponentHandleState args) - { - if (args.Current is not MobMoverComponentState state) return; - component.GrabRangeVV = state.GrabRange; - component.PushStrengthVV = state.PushStrength; - } - - private void OnMobGetState(EntityUid uid, MobMoverComponent component, ref ComponentGetState args) - { - args.State = new MobMoverComponentState(component.GrabRange, component.PushStrength); - } - - [Serializable, NetSerializable] - private sealed class MobMoverComponentState : ComponentState - { - public float GrabRange; - public float PushStrength; - - public MobMoverComponentState(float grabRange, float pushStrength) - { - GrabRange = grabRange; - PushStrength = pushStrength; - } - } -} diff --git a/Content.Shared/Movement/Systems/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs index a9297b94110..af065d0dec8 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -1,8 +1,12 @@ +using System.Diagnostics.CodeAnalysis; +using System.Numerics; +using Content.Shared.Bed.Sleep; using Content.Shared.CCVar; using Content.Shared.Friction; using Content.Shared.Gravity; using Content.Shared.Inventory; using Content.Shared.Maps; +using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; using Content.Shared.Pulling.Components; @@ -12,15 +16,11 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Physics; +using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Controllers; +using Robust.Shared.Physics.Systems; using Robust.Shared.Timing; using Robust.Shared.Utility; -using System.Diagnostics.CodeAnalysis; -using System.Numerics; -using Content.Shared.Mobs.Systems; -using Robust.Shared.Physics.Components; -using Robust.Shared.Physics.Systems; -using Content.Shared.Bed.Sleep; namespace Content.Shared.Movement.Systems { @@ -88,9 +88,7 @@ public override void Initialize() NoRotateQuery = GetEntityQuery(); CanMoveInAirQuery = GetEntityQuery(); - InitializeFootsteps(); InitializeInput(); - InitializeMob(); InitializeRelay(); _configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true); _configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); @@ -440,14 +438,14 @@ private bool TryGetSound( if (TryComp(uid, out var moverModifier)) { - sound = moverModifier.Sound; + sound = moverModifier.FootstepSoundCollection; return true; } if (_inventory.TryGetSlotEntity(uid, "shoes", out var shoes) && TryComp(shoes, out var modifier)) { - sound = modifier.Sound; + sound = modifier.FootstepSoundCollection; return true; } @@ -468,7 +466,7 @@ private bool TryGetFootstepSound( { if (TryComp(xform.MapUid, out var modifier)) { - sound = modifier.Sound; + sound = modifier.FootstepSoundCollection; return true; } @@ -494,7 +492,7 @@ private bool TryGetFootstepSound( if (TryComp(maybeFootstep, out var footstep)) { - sound = footstep.Sound; + sound = footstep.FootstepSoundCollection; return true; } } diff --git a/Content.Shared/Nutrition/Components/HungerComponent.cs b/Content.Shared/Nutrition/Components/HungerComponent.cs index 037c069cf4d..11197d8b42a 100644 --- a/Content.Shared/Nutrition/Components/HungerComponent.cs +++ b/Content.Shared/Nutrition/Components/HungerComponent.cs @@ -52,7 +52,7 @@ public sealed partial class HungerComponent : Component /// A dictionary relating HungerThreshold to the amount of needed for each one /// [DataField("thresholds", customTypeSerializer: typeof(DictionarySerializer))] - [AutoNetworkedField(cloneData: true)] + [AutoNetworkedField] public Dictionary Thresholds = new() { { HungerThreshold.Overfed, 200.0f }, @@ -66,7 +66,7 @@ public sealed partial class HungerComponent : Component /// A dictionary relating hunger thresholds to corresponding alerts. /// [DataField("hungerThresholdAlerts", customTypeSerializer: typeof(DictionarySerializer))] - [AutoNetworkedField(cloneData: true)] + [AutoNetworkedField] public Dictionary HungerThresholdAlerts = new() { { HungerThreshold.Peckish, AlertType.Peckish }, @@ -78,7 +78,7 @@ public sealed partial class HungerComponent : Component /// A dictionary relating HungerThreshold to how much they modify . /// [DataField("hungerThresholdDecayModifiers", customTypeSerializer: typeof(DictionarySerializer))] - [AutoNetworkedField(cloneData: true)] + [AutoNetworkedField] public Dictionary HungerThresholdDecayModifiers = new() { { HungerThreshold.Overfed, 1.2f }, diff --git a/Content.Shared/Nutrition/Components/ThirstComponent.cs b/Content.Shared/Nutrition/Components/ThirstComponent.cs index ec2ff10667b..1e3f1398079 100644 --- a/Content.Shared/Nutrition/Components/ThirstComponent.cs +++ b/Content.Shared/Nutrition/Components/ThirstComponent.cs @@ -35,7 +35,7 @@ public sealed partial class ThirstComponent : Component /// [DataField("nextUpdateTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] - public TimeSpan NextUpdateTime = TimeSpan.MaxValue; + public TimeSpan NextUpdateTime; /// /// The time between each update. @@ -45,7 +45,7 @@ public sealed partial class ThirstComponent : Component public TimeSpan UpdateRate = TimeSpan.FromSeconds(1); [DataField("thresholds")] - [AutoNetworkedField(cloneData: true)] + [AutoNetworkedField] public Dictionary ThirstThresholds = new() { {ThirstThreshold.OverHydrated, 600.0f}, diff --git a/Content.Shared/Nyanotrasen/ReverseEngineering/ReverseEngineeringComponent.cs b/Content.Shared/Nyanotrasen/ReverseEngineering/ReverseEngineeringComponent.cs new file mode 100644 index 00000000000..e928180e0ac --- /dev/null +++ b/Content.Shared/Nyanotrasen/ReverseEngineering/ReverseEngineeringComponent.cs @@ -0,0 +1,38 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.ReverseEngineering; + +/// +/// This item has some value in reverse engineering lathe recipes. +/// +[RegisterComponent] +public sealed partial class ReverseEngineeringComponent : Component +{ + /// + /// The recipes that can be reverse engineered from this. + /// Does not neccesarily line up with lathe recipes. + /// + [DataField("recipes")] + public List? Recipes; + + /// + /// Difficulty score 1-5 how hard this is to reverse engineer. + /// + [DataField("difficulty")] + public int Difficulty = 1; + + /// + /// Used to mark whether this entity intentionally lets its children use its recipe. + /// e.g. all jetpacks unlock the same jetpack recipe. Used for tests. + /// + [DataField("generic")] + public bool Generic = false; + + /// + /// A new item that should be given back by the reverse engineering machine instead of this one. + /// E.g., NT aligned versions of syndicate items. + /// + [DataField("newItem", customTypeSerializer:typeof(PrototypeIdSerializer))] + public string? NewItem; +} diff --git a/Content.Shared/Nyanotrasen/ReverseEngineering/SharedReverseEngineering.cs b/Content.Shared/Nyanotrasen/ReverseEngineering/SharedReverseEngineering.cs new file mode 100644 index 00000000000..9d73c57692d --- /dev/null +++ b/Content.Shared/Nyanotrasen/ReverseEngineering/SharedReverseEngineering.cs @@ -0,0 +1,106 @@ +using Robust.Shared.Serialization; +using Robust.Shared.Utility; + +namespace Content.Shared.ReverseEngineering; + +[Serializable, NetSerializable] +public enum ReverseEngineeringMachineUiKey : byte +{ + Key +} + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineScanButtonPressedMessage : BoundUserInterfaceMessage +{ +} + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineSafetyButtonToggledMessage : BoundUserInterfaceMessage +{ + public bool Safety; + + public ReverseEngineeringMachineSafetyButtonToggledMessage(bool safety) + { + Safety = safety; + } +} + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineAutoScanButtonToggledMessage : BoundUserInterfaceMessage +{ + public bool AutoScan; + + public ReverseEngineeringMachineAutoScanButtonToggledMessage(bool autoScan) + { + AutoScan = autoScan; + } +} + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineStopButtonPressedMessage : BoundUserInterfaceMessage +{ +} + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineEjectButtonPressedMessage : BoundUserInterfaceMessage +{ +} + + +[Serializable, NetSerializable] +public sealed class ReverseEngineeringMachineScanUpdateState : BoundUserInterfaceState +{ + public NetEntity? Target; + + public bool CanScan; + + public FormattedMessage? ScanReport; + + public bool Scanning; + + public bool Safety; + + public bool AutoProbe; + + public int TotalProgress; + + public TimeSpan TimeRemaining; + + public TimeSpan TotalTime; + + public ReverseEngineeringMachineScanUpdateState(NetEntity? target, bool canScan, + FormattedMessage? scanReport, bool scanning, bool safety, bool autoProbe, int totalProgress, TimeSpan timeRemaining, TimeSpan totalTime) + { + Target = target; + CanScan = canScan; + + ScanReport = scanReport; + + Scanning = scanning; + Safety = safety; + AutoProbe = autoProbe; + TotalProgress = totalProgress; + TimeRemaining = timeRemaining; + TotalTime = totalTime; + } +} + +/// +// 3d6 + scanner bonus + danger bonus - item difficulty +/// +[Serializable, NetSerializable] +public enum ReverseEngineeringTickResult : byte +{ + Destruction, // 9 (only destroys if danger bonus is active, effectively 8 since aversion bonus is always 1) + Stagnation, // 10 + SuccessMinor, // 11-12 + SuccessAverage, // 13-15 + SuccessMajor, // 16-17 + InstantSuccess // 18 +} + +[Serializable, NetSerializable] +public enum ReverseEngineeringVisuals : byte +{ + ChamberOpen, +} diff --git a/Content.Shared/Physics/Controllers/SharedConveyorController.cs b/Content.Shared/Physics/Controllers/SharedConveyorController.cs index 1ba66aa1a37..8ec6ddbefe5 100644 --- a/Content.Shared/Physics/Controllers/SharedConveyorController.cs +++ b/Content.Shared/Physics/Controllers/SharedConveyorController.cs @@ -2,7 +2,6 @@ using Content.Shared.Conveyor; using Content.Shared.Gravity; using Content.Shared.Movement.Systems; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; @@ -26,8 +25,6 @@ public abstract class SharedConveyorController : VirtualController public override void Initialize() { UpdatesAfter.Add(typeof(SharedMoverController)); - SubscribeLocalEvent(OnConveyorGetState); - SubscribeLocalEvent(OnConveyorHandleState); SubscribeLocalEvent(OnConveyorStartCollide); SubscribeLocalEvent(OnConveyorEndCollide); @@ -35,22 +32,6 @@ public override void Initialize() base.Initialize(); } - private void OnConveyorGetState(EntityUid uid, ConveyorComponent component, ref ComponentGetState args) - { - args.State = new ConveyorComponentState(component.Angle, component.Speed, component.State, component.Powered); - } - - private void OnConveyorHandleState(EntityUid uid, ConveyorComponent component, ref ComponentHandleState args) - { - if (args.Current is not ConveyorComponentState state) - return; - - component.Powered = state.Powered; - component.Angle = state.Angle; - component.Speed = state.Speed; - component.State = state.State; - } - private void OnConveyorStartCollide(EntityUid uid, ConveyorComponent component, ref StartCollideEvent args) { var otherUid = args.OtherEntity; diff --git a/Content.Shared/Physics/PreventCollideComponent.cs b/Content.Shared/Physics/PreventCollideComponent.cs index 429b7b56b3f..af59d367735 100644 --- a/Content.Shared/Physics/PreventCollideComponent.cs +++ b/Content.Shared/Physics/PreventCollideComponent.cs @@ -1,24 +1,14 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Physics; /// /// Use this to allow a specific UID to prevent collides /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class PreventCollideComponent : Component { + [AutoNetworkedField] public EntityUid Uid; } -[Serializable, NetSerializable] -public sealed class PreventCollideComponentState : ComponentState -{ - public NetEntity Uid; - - public PreventCollideComponentState(NetEntity netEntity) - { - Uid = netEntity; - } -} diff --git a/Content.Shared/Physics/SharedPreventCollideSystem.cs b/Content.Shared/Physics/SharedPreventCollideSystem.cs index 408125e1409..83d3a918e87 100644 --- a/Content.Shared/Physics/SharedPreventCollideSystem.cs +++ b/Content.Shared/Physics/SharedPreventCollideSystem.cs @@ -1,6 +1,4 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Physics.Dynamics; -using Robust.Shared.Physics.Events; +using Robust.Shared.Physics.Events; namespace Content.Shared.Physics; @@ -10,24 +8,9 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnPreventCollide); } - private void OnGetState(EntityUid uid, PreventCollideComponent component, ref ComponentGetState args) - { - args.State = new PreventCollideComponentState(GetNetEntity(component.Uid)); - } - - private void OnHandleState(EntityUid uid, PreventCollideComponent component, ref ComponentHandleState args) - { - if (args.Current is not PreventCollideComponentState state) - return; - - component.Uid = EnsureEntity(state.Uid, uid); - } - private void OnPreventCollide(EntityUid uid, PreventCollideComponent component, ref PreventCollideEvent args) { if (component.Uid == args.OtherEntity) diff --git a/Content.Shared/Placeable/ItemPlacerComponent.cs b/Content.Shared/Placeable/ItemPlacerComponent.cs index c4fb6079cfb..84df2e395a8 100644 --- a/Content.Shared/Placeable/ItemPlacerComponent.cs +++ b/Content.Shared/Placeable/ItemPlacerComponent.cs @@ -6,26 +6,27 @@ namespace Content.Shared.Placeable; /// /// Detects items placed on it that match a whitelist. /// -[RegisterComponent, NetworkedComponent, Access(typeof(ItemPlacerSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(ItemPlacerSystem))] public sealed partial class ItemPlacerComponent : Component { /// /// The entities that are currently on top of the placer. /// Guaranteed to have less than enitities if it is set. /// - [DataField("placedEntities")] + [DataField, AutoNetworkedField] public HashSet PlacedEntities = new(); /// /// Whitelist for entities that can be placed. /// - [DataField("whitelist"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public EntityWhitelist? Whitelist; /// /// The max amount of entities that can be placed at the same time. /// If 0, there is no limit. /// - [ViewVariables(VVAccess.ReadWrite), DataField("maxEntities")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public uint MaxEntities = 1; } diff --git a/Content.Shared/Placeable/ItemPlacerSystem.cs b/Content.Shared/Placeable/ItemPlacerSystem.cs index ccce286214e..92dc8eb74b7 100644 --- a/Content.Shared/Placeable/ItemPlacerSystem.cs +++ b/Content.Shared/Placeable/ItemPlacerSystem.cs @@ -1,8 +1,5 @@ using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; -using System.Linq; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Placeable; @@ -21,28 +18,6 @@ public override void Initialize() SubscribeLocalEvent(OnStartCollide); SubscribeLocalEvent(OnEndCollide); - SubscribeLocalEvent(OnPlacerGetState); - SubscribeLocalEvent(OnPlacerHandleState); - } - - private void OnPlacerHandleState(EntityUid uid, ItemPlacerComponent component, ref ComponentHandleState args) - { - if (args.Current is not ItemPlacerComponentState state) - return; - - component.MaxEntities = state.MaxEntities; - component.PlacedEntities.Clear(); - var ents = EnsureEntitySet(state.Entities, uid); - component.PlacedEntities.UnionWith(ents); - } - - private void OnPlacerGetState(EntityUid uid, ItemPlacerComponent component, ref ComponentGetState args) - { - args.State = new ItemPlacerComponentState() - { - MaxEntities = component.MaxEntities, - Entities = GetNetEntitySet(component.PlacedEntities), - }; } private void OnStartCollide(EntityUid uid, ItemPlacerComponent comp, ref StartCollideEvent args) @@ -81,13 +56,6 @@ private void OnEndCollide(EntityUid uid, ItemPlacerComponent comp, ref EndCollid _placeableSurface.SetPlaceable(uid, true); } - - [Serializable, NetSerializable] - private sealed class ItemPlacerComponentState : ComponentState - { - public uint MaxEntities; - public HashSet Entities = default!; - } } /// diff --git a/Content.Shared/Placeable/PlaceableSurfaceComponent.cs b/Content.Shared/Placeable/PlaceableSurfaceComponent.cs index b30bcedcdbd..40fa282ab5f 100644 --- a/Content.Shared/Placeable/PlaceableSurfaceComponent.cs +++ b/Content.Shared/Placeable/PlaceableSurfaceComponent.cs @@ -1,35 +1,18 @@ using System.Numerics; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -namespace Content.Shared.Placeable -{ - [RegisterComponent, NetworkedComponent] - [Access(typeof(PlaceableSurfaceSystem))] - public sealed partial class PlaceableSurfaceComponent : Component - { - [DataField("isPlaceable")] - public bool IsPlaceable { get; set; } = true; - - [DataField("placeCentered")] - public bool PlaceCentered { get; set; } +namespace Content.Shared.Placeable; - [DataField("positionOffset")] - public Vector2 PositionOffset { get; set; } - } +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(PlaceableSurfaceSystem))] +public sealed partial class PlaceableSurfaceComponent : Component +{ + [DataField, AutoNetworkedField] + public bool IsPlaceable { get; set; } = true; - [Serializable, NetSerializable] - public sealed class PlaceableSurfaceComponentState : ComponentState - { - public readonly bool IsPlaceable; - public readonly bool PlaceCentered; - public readonly Vector2 PositionOffset; + [DataField, AutoNetworkedField] + public bool PlaceCentered { get; set; } - public PlaceableSurfaceComponentState(bool placeable, bool centered, Vector2 offset) - { - IsPlaceable = placeable; - PlaceCentered = centered; - PositionOffset = offset; - } - } + [DataField, AutoNetworkedField] + public Vector2 PositionOffset { get; set; } } diff --git a/Content.Shared/Placeable/PlaceableSurfaceSystem.cs b/Content.Shared/Placeable/PlaceableSurfaceSystem.cs index 7464c8890c1..b0031cfa33f 100644 --- a/Content.Shared/Placeable/PlaceableSurfaceSystem.cs +++ b/Content.Shared/Placeable/PlaceableSurfaceSystem.cs @@ -1,8 +1,7 @@ using System.Numerics; -using Content.Shared.Storage.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; -using Robust.Shared.GameStates; +using Content.Shared.Storage.Components; namespace Content.Shared.Placeable { @@ -15,13 +14,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnAfterInteractUsing); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnGetState(EntityUid uid, PlaceableSurfaceComponent component, ref ComponentGetState args) - { - args.State = new PlaceableSurfaceComponentState(component.IsPlaceable, component.PlaceCentered, component.PositionOffset); } public void SetPlaceable(EntityUid uid, bool isPlaceable, PlaceableSurfaceComponent? surface = null) @@ -30,7 +22,7 @@ public void SetPlaceable(EntityUid uid, bool isPlaceable, PlaceableSurfaceCompon return; surface.IsPlaceable = isPlaceable; - Dirty(surface); + Dirty(uid, surface); } public void SetPlaceCentered(EntityUid uid, bool placeCentered, PlaceableSurfaceComponent? surface = null) @@ -39,7 +31,7 @@ public void SetPlaceCentered(EntityUid uid, bool placeCentered, PlaceableSurface return; surface.PlaceCentered = placeCentered; - Dirty(surface); + Dirty(uid, surface); } public void SetPositionOffset(EntityUid uid, Vector2 offset, PlaceableSurfaceComponent? surface = null) @@ -48,7 +40,7 @@ public void SetPositionOffset(EntityUid uid, Vector2 offset, PlaceableSurfaceCom return; surface.PositionOffset = offset; - Dirty(surface); + Dirty(uid, surface); } private void OnAfterInteractUsing(EntityUid uid, PlaceableSurfaceComponent surface, AfterInteractUsingEvent args) @@ -74,15 +66,5 @@ private void OnAfterInteractUsing(EntityUid uid, PlaceableSurfaceComponent surfa args.Handled = true; } - - private void OnHandleState(EntityUid uid, PlaceableSurfaceComponent component, ref ComponentHandleState args) - { - if (args.Current is not PlaceableSurfaceComponentState state) - return; - - component.IsPlaceable = state.IsPlaceable; - component.PlaceCentered = state.PlaceCentered; - component.PositionOffset = state.PositionOffset; - } } } diff --git a/Content.Shared/Points/PointManagerComponent.cs b/Content.Shared/Points/PointManagerComponent.cs index 4250d44dc12..6c5bf6b0fa3 100644 --- a/Content.Shared/Points/PointManagerComponent.cs +++ b/Content.Shared/Points/PointManagerComponent.cs @@ -1,7 +1,6 @@ using Content.Shared.FixedPoint; using Robust.Shared.GameStates; using Robust.Shared.Network; -using Robust.Shared.Serialization; using Robust.Shared.Utility; namespace Content.Shared.Points; @@ -9,32 +8,19 @@ namespace Content.Shared.Points; /// /// This is a component that generically stores points for all players. /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedPointSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +[Access(typeof(SharedPointSystem))] public sealed partial class PointManagerComponent : Component { /// /// A dictionary of a player's netuserID to the amount of points they have. /// - [DataField("points")] + [DataField, AutoNetworkedField] public Dictionary Points = new(); /// /// A text-only version of the scoreboard used by the client. /// - [DataField("scoreboard")] + [DataField, AutoNetworkedField] public FormattedMessage Scoreboard = new(); } - -[Serializable, NetSerializable] -public sealed class PointManagerComponentState : ComponentState -{ - public Dictionary Points; - - public FormattedMessage Scoreboard; - - public PointManagerComponentState(Dictionary points, FormattedMessage scoreboard) - { - Points = points; - Scoreboard = scoreboard; - } -} diff --git a/Content.Shared/Prying/Components/PryUnpoweredComponent.cs b/Content.Shared/Prying/Components/PryUnpoweredComponent.cs new file mode 100644 index 00000000000..f0e61dc9685 --- /dev/null +++ b/Content.Shared/Prying/Components/PryUnpoweredComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Prying.Components; + +/// +/// Applied to entities that can be pried open without tools while unpowered +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class PryUnpoweredComponent : Component +{ +} diff --git a/Content.Shared/Prying/Components/PryingComponent.cs b/Content.Shared/Prying/Components/PryingComponent.cs new file mode 100644 index 00000000000..4442481dce1 --- /dev/null +++ b/Content.Shared/Prying/Components/PryingComponent.cs @@ -0,0 +1,82 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Shared.Prying.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class PryingComponent : Component +{ + /// + /// Whether the entity can pry open powered doors + /// + [DataField("pryPowered")] + public bool PryPowered = false; + + /// + /// Whether the tool can bypass certain restrictions when prying. + /// For example door bolts. + /// + [DataField("force")] + public bool Force = false; + /// + /// Modifier on the prying time. + /// Lower values result in more time. + /// + [DataField("speedModifier")] + public float SpeedModifier = 1.0f; + + /// + /// What sound to play when prying is finished. + /// + [DataField("useSound")] + public SoundSpecifier UseSound = new SoundPathSpecifier("/Audio/Items/crowbar.ogg"); + + /// + /// Whether the entity can currently pry things. + /// + [DataField("enabled")] + public bool Enabled = true; +} + +/// +/// Raised directed on an entity before prying it. +/// Cancel to stop the entity from being pried open. +/// +[ByRefEvent] +public record struct BeforePryEvent(EntityUid User, bool PryPowered, bool Force) +{ + public readonly EntityUid User = User; + + public readonly bool PryPowered = PryPowered; + + public readonly bool Force = Force; + + public bool Cancelled; +} + +/// +/// Raised directed on an entity that has been pried. +/// +[ByRefEvent] +public readonly record struct PriedEvent(EntityUid User) +{ + public readonly EntityUid User = User; +} + +/// +/// Raised to determine how long the door's pry time should be modified by. +/// Multiply PryTimeModifier by the desired amount. +/// +[ByRefEvent] +public record struct GetPryTimeModifierEvent +{ + public readonly EntityUid User; + public float PryTimeModifier = 1.0f; + public float BaseTime = 5.0f; + + public GetPryTimeModifierEvent(EntityUid user) + { + User = user; + } +} + diff --git a/Content.Shared/Prying/Systems/PryingSystem.cs b/Content.Shared/Prying/Systems/PryingSystem.cs new file mode 100644 index 00000000000..3bb3a9bc9b0 --- /dev/null +++ b/Content.Shared/Prying/Systems/PryingSystem.cs @@ -0,0 +1,162 @@ +using Content.Shared.Prying.Components; +using Content.Shared.Verbs; +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; +using Content.Shared.Doors.Components; +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Interaction; +using PryUnpoweredComponent = Content.Shared.Prying.Components.PryUnpoweredComponent; + +namespace Content.Shared.Prying.Systems; + +/// +/// Handles prying of entities (e.g. doors) +/// +public sealed class PryingSystem : EntitySystem +{ + [Dependency] private readonly ISharedAdminLogManager _adminLog = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + // Mob prying doors + SubscribeLocalEvent>(OnDoorAltVerb); + SubscribeLocalEvent(OnDoAfter); + SubscribeLocalEvent(TryPryDoor); + } + + private void TryPryDoor(EntityUid uid, DoorComponent comp, InteractUsingEvent args) + { + if (args.Handled) + return; + + args.Handled = TryPry(uid, args.User, out _, args.Used); + } + + private void OnDoorAltVerb(EntityUid uid, DoorComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + if (!TryComp(args.User, out var tool)) + return; + + args.Verbs.Add(new AlternativeVerb() + { + Text = Loc.GetString("door-pry"), + Impact = LogImpact.Low, + Act = () => TryPry(uid, args.User, out _, args.User), + }); + } + + /// + /// Attempt to pry an entity. + /// + public bool TryPry(EntityUid target, EntityUid user, out DoAfterId? id, EntityUid tool) + { + id = null; + + PryingComponent? comp = null; + if (!Resolve(tool, ref comp, false)) + return false; + + if (!comp.Enabled) + return false; + + if (!CanPry(target, user, comp)) + { + // If we have reached this point we want the event that caused this + // to be marked as handled as a popup would be generated on failure. + return true; + } + + StartPry(target, user, tool, comp.SpeedModifier, out id); + + return true; + } + + /// + /// Try to pry an entity. + /// + public bool TryPry(EntityUid target, EntityUid user, out DoAfterId? id) + { + id = null; + + if (!CanPry(target, user)) + // If we have reached this point we want the event that caused this + // to be marked as handled as a popup would be generated on failure. + return true; + + return StartPry(target, user, null, 1.0f, out id); + } + + private bool CanPry(EntityUid target, EntityUid user, PryingComponent? comp = null) + { + BeforePryEvent canev; + + if (comp != null) + { + canev = new BeforePryEvent(user, comp.PryPowered, comp.Force); + } + else + { + if (!TryComp(target, out _)) + return false; + canev = new BeforePryEvent(user, false, false); + } + + RaiseLocalEvent(target, ref canev); + + if (canev.Cancelled) + return false; + return true; + } + + private bool StartPry(EntityUid target, EntityUid user, EntityUid? tool, float toolModifier, [NotNullWhen(true)] out DoAfterId? id) + { + var modEv = new GetPryTimeModifierEvent(user); + + RaiseLocalEvent(target, ref modEv); + var doAfterArgs = new DoAfterArgs(EntityManager, user, TimeSpan.FromSeconds(modEv.BaseTime * modEv.PryTimeModifier / toolModifier), new DoorPryDoAfterEvent(), target, target, tool) + { + BreakOnDamage = true, + BreakOnUserMove = true, + }; + + if (tool != null) + { + _adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user)} is using {ToPrettyString(tool.Value)} to pry {ToPrettyString(target)}"); + } + else + { + _adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user)} is prying {ToPrettyString(target)}"); + } + return _doAfterSystem.TryStartDoAfter(doAfterArgs, out id); + } + + private void OnDoAfter(EntityUid uid, DoorComponent door, DoorPryDoAfterEvent args) + { + if (args.Cancelled) + return; + if (args.Target is null) + return; + + PryingComponent? comp = null; + + if (args.Used != null && Resolve(args.Used.Value, ref comp)) + _audioSystem.PlayPredicted(comp.UseSound, args.Used.Value, args.User); + + var ev = new PriedEvent(args.User); + RaiseLocalEvent(uid, ref ev); + } +} + +[Serializable, NetSerializable] +public sealed partial class DoorPryDoAfterEvent : SimpleDoAfterEvent +{ +} diff --git a/Content.Shared/Radiation/Components/GeigerComponent.cs b/Content.Shared/Radiation/Components/GeigerComponent.cs index ebcd84b3a3c..585c1a51dcb 100644 --- a/Content.Shared/Radiation/Components/GeigerComponent.cs +++ b/Content.Shared/Radiation/Components/GeigerComponent.cs @@ -9,41 +9,41 @@ namespace Content.Shared.Radiation.Components; /// Geiger counter that shows current radiation level. /// Can be added as a component to clothes. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] [Access(typeof(SharedGeigerSystem))] public sealed partial class GeigerComponent : Component { /// /// If true it will be active only when player equipped it. /// - [DataField("attachedToSuit")] + [DataField] public bool AttachedToSuit; /// /// Is geiger counter currently active? /// If false attached entity will ignore any radiation rays. /// - [DataField("isEnabled")] + [DataField, AutoNetworkedField] public bool IsEnabled; /// /// Should it shows examine message with current radiation level? /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("showExamine")] + [DataField] public bool ShowExamine; /// /// Should it shows item control when equipped by player? /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("showControl")] + [DataField] public bool ShowControl; /// /// Map of sounds that should be play on loop for different radiation levels. /// - [DataField("sounds")] + [DataField] public Dictionary Sounds = new() { {GeigerDangerLevel.Low, new SoundPathSpecifier("/Audio/Items/Geiger/low.ogg")}, @@ -55,13 +55,13 @@ public sealed partial class GeigerComponent : Component /// /// Current radiation level in rad per second. /// - [ViewVariables(VVAccess.ReadOnly)] + [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] public float CurrentRadiation; /// /// Estimated radiation danger level. /// - [ViewVariables(VVAccess.ReadOnly)] + [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] public GeigerDangerLevel DangerLevel = GeigerDangerLevel.None; /// @@ -69,7 +69,7 @@ public sealed partial class GeigerComponent : Component /// Because sound is annoying, geiger counter clicks will play /// only for player that equipped it. /// - [ViewVariables(VVAccess.ReadOnly)] + [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] public EntityUid? User; /// @@ -85,15 +85,6 @@ public sealed partial class GeigerComponent : Component public IPlayingAudioStream? Stream; } -[Serializable, NetSerializable] -public sealed class GeigerComponentState : ComponentState -{ - public float CurrentRadiation; - public GeigerDangerLevel DangerLevel; - public bool IsEnabled; - public NetEntity? User; -} - [Serializable, NetSerializable] public enum GeigerDangerLevel : byte { diff --git a/Content.Shared/Radiation/Components/RadiationPulseComponent.cs b/Content.Shared/Radiation/Components/RadiationPulseComponent.cs index a1cfa566bcf..a11e8e3ee0e 100644 --- a/Content.Shared/Radiation/Components/RadiationPulseComponent.cs +++ b/Content.Shared/Radiation/Components/RadiationPulseComponent.cs @@ -1,5 +1,4 @@ using Content.Shared.Radiation.Systems; -using Content.Shared.Spawners.Components; namespace Content.Shared.Radiation.Components; @@ -18,7 +17,7 @@ public sealed partial class RadiationPulseComponent : Component /// /// How long will animation play in seconds. - /// Can be overridden by . + /// Can be overridden by . /// public float VisualDuration = 2f; diff --git a/Content.Shared/Radiation/Systems/RadiationPulseSystem.cs b/Content.Shared/Radiation/Systems/RadiationPulseSystem.cs index 7991f331eef..9f280330257 100644 --- a/Content.Shared/Radiation/Systems/RadiationPulseSystem.cs +++ b/Content.Shared/Radiation/Systems/RadiationPulseSystem.cs @@ -1,5 +1,5 @@ using Content.Shared.Radiation.Components; -using Content.Shared.Spawners.Components; +using Robust.Shared.Spawners; using Robust.Shared.Timing; namespace Content.Shared.Radiation.Systems; @@ -25,7 +25,7 @@ private void OnStartup(EntityUid uid, RadiationPulseComponent component, Compone } // try to get radiation range or keep default visual range if (TryComp(uid, out var radSource)) - { + { component.VisualRange = radSource.Intensity / radSource.Slope; } } diff --git a/Content.Shared/Research/Components/TechnologyDatabaseComponent.cs b/Content.Shared/Research/Components/TechnologyDatabaseComponent.cs index b9936956adc..fc317454c9a 100644 --- a/Content.Shared/Research/Components/TechnologyDatabaseComponent.cs +++ b/Content.Shared/Research/Components/TechnologyDatabaseComponent.cs @@ -17,21 +17,21 @@ public sealed partial class TechnologyDatabaseComponent : Component [DataField("mainDiscipline", customTypeSerializer: typeof(PrototypeIdSerializer))] public string? MainDiscipline; - [AutoNetworkedField(true)] + [AutoNetworkedField] [DataField("currentTechnologyCards")] public List CurrentTechnologyCards = new(); /// /// Which research disciplines are able to be unlocked /// - [AutoNetworkedField(true)] + [AutoNetworkedField] [DataField("supportedDisciplines", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List SupportedDisciplines = new(); /// /// The ids of all the technologies which have been unlocked. /// - [AutoNetworkedField(true)] + [AutoNetworkedField] [DataField("unlockedTechnologies", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List UnlockedTechnologies = new(); @@ -40,7 +40,7 @@ public sealed partial class TechnologyDatabaseComponent : Component /// This is maintained alongside the TechnologyIds /// /// todo: if you unlock all the recipes in a tech, it doesn't count as unlocking the tech. sadge - [AutoNetworkedField(true)] + [AutoNetworkedField] [DataField("unlockedRecipes", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List UnlockedRecipes = new(); } diff --git a/Content.Shared/Shuttles/Components/IFFComponent.cs b/Content.Shared/Shuttles/Components/IFFComponent.cs index dc834aebf2f..24f06e93d4f 100644 --- a/Content.Shared/Shuttles/Components/IFFComponent.cs +++ b/Content.Shared/Shuttles/Components/IFFComponent.cs @@ -6,7 +6,8 @@ namespace Content.Shared.Shuttles.Components; /// /// Handles what a grid should look like on radar. /// -[RegisterComponent, NetworkedComponent, Access(typeof(SharedShuttleSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedShuttleSystem))] public sealed partial class IFFComponent : Component { /// @@ -19,13 +20,13 @@ public sealed partial class IFFComponent : Component /// public static readonly Color IFFColor = Color.Aquamarine; - [ViewVariables(VVAccess.ReadWrite), DataField("flags")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public IFFFlags Flags = IFFFlags.None; /// /// Color for this to show up on IFF. /// - [ViewVariables(VVAccess.ReadWrite), DataField("color")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public Color Color = IFFColor; } diff --git a/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs b/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs index 952f4798225..96018480f1b 100644 --- a/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs +++ b/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs @@ -3,7 +3,8 @@ namespace Content.Shared.Shuttles.Components; -[RegisterComponent, NetworkedComponent, Access(typeof(SharedRadarConsoleSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedRadarConsoleSystem))] public sealed partial class RadarConsoleComponent : Component { [ViewVariables(VVAccess.ReadWrite)] @@ -16,6 +17,6 @@ public float RangeVV .SetRange(Owner, value, this); } - [DataField("maxRange")] + [DataField, AutoNetworkedField] public float MaxRange = 256f; } diff --git a/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs b/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs index 2e98e899231..a069a2d2e25 100644 --- a/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs +++ b/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs @@ -1,6 +1,4 @@ using Content.Shared.Shuttles.Components; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Shuttles.Systems; @@ -9,29 +7,6 @@ public abstract class SharedRadarConsoleSystem : EntitySystem public const float DefaultMinRange = 64f; public const float DefaultMaxRange = 256f; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnHandleState(EntityUid uid, RadarConsoleComponent component, ref ComponentHandleState args) - { - if (args.Current is not RadarConsoleComponentState state) - return; - - component.MaxRange = state.Range; - } - - private void OnGetState(EntityUid uid, RadarConsoleComponent component, ref ComponentGetState args) - { - args.State = new RadarConsoleComponentState() - { - Range = component.MaxRange - }; - } - protected virtual void UpdateState(EntityUid uid, RadarConsoleComponent component) { } @@ -45,10 +20,4 @@ public void SetRange(EntityUid uid, float value, RadarConsoleComponent component Dirty(uid, component); UpdateState(uid, component); } - - [Serializable, NetSerializable] - protected sealed class RadarConsoleComponentState : ComponentState - { - public float Range; - } } diff --git a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs index a128d763382..587b5fafe04 100644 --- a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs +++ b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.IFF.cs @@ -1,7 +1,5 @@ using Content.Shared.Shuttles.Components; using JetBrains.Annotations; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Shuttles.Systems; @@ -11,12 +9,6 @@ public abstract partial class SharedShuttleSystem * Handles the label visibility on radar controls. This can be hiding the label or applying other effects. */ - private void InitializeIFF() - { - SubscribeLocalEvent(OnIFFGetState); - SubscribeLocalEvent(OnIFFHandleState); - } - protected virtual void UpdateIFFInterfaces(EntityUid gridUid, IFFComponent component) {} /// @@ -61,29 +53,4 @@ public void RemoveIFFFlag(EntityUid gridUid, IFFFlags flags, IFFComponent? compo Dirty(component); UpdateIFFInterfaces(gridUid, component); } - - private void OnIFFHandleState(EntityUid uid, IFFComponent component, ref ComponentHandleState args) - { - if (args.Current is not IFFComponentState state) - return; - - component.Flags = state.Flags; - component.Color = state.Color; - } - - private void OnIFFGetState(EntityUid uid, IFFComponent component, ref ComponentGetState args) - { - args.State = new IFFComponentState() - { - Flags = component.Flags, - Color = component.Color, - }; - } - - [Serializable, NetSerializable] - private sealed class IFFComponentState : ComponentState - { - public IFFFlags Flags; - public Color Color; - } } diff --git a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs index e75976c585d..8471e83df51 100644 --- a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs +++ b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs @@ -2,11 +2,6 @@ namespace Content.Shared.Shuttles.Systems; public abstract partial class SharedShuttleSystem : EntitySystem { - public override void Initialize() - { - base.Initialize(); - InitializeIFF(); - } } [Flags] diff --git a/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantComponentComponent.cs b/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantComponentComponent.cs new file mode 100644 index 00000000000..b558f697d3d --- /dev/null +++ b/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantComponentComponent.cs @@ -0,0 +1,15 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.SimpleStation14.Clothing +{ + [RegisterComponent] + public sealed partial class ClothingGrantComponentComponent : Component + { + [DataField("component", required: true)] + [AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + [ViewVariables(VVAccess.ReadWrite)] + public bool IsActive = false; + } +} diff --git a/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantTagComponent.cs b/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantTagComponent.cs new file mode 100644 index 00000000000..312430cb737 --- /dev/null +++ b/Content.Shared/SimpleStation14/Clothing/Components/ClothingGrantTagComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.SimpleStation14.Clothing; + +[RegisterComponent] +public sealed partial class ClothingGrantTagComponent : Component +{ + [DataField("tag", required: true), ViewVariables(VVAccess.ReadWrite)] + public string Tag = ""; + + [ViewVariables(VVAccess.ReadWrite)] + public bool IsActive = false; +} diff --git a/Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs b/Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs new file mode 100644 index 00000000000..5fbc83a4b06 --- /dev/null +++ b/Content.Shared/SimpleStation14/Clothing/Systems/ClothingGrantingSystem.cs @@ -0,0 +1,92 @@ +using Content.Shared.Clothing.Components; +using Content.Shared.Inventory.Events; +using Robust.Shared.Serialization.Manager; +using Content.Shared.Tag; + +namespace Content.Shared.SimpleStation14.Clothing; + +public sealed class ClothingGrantingSystem : EntitySystem +{ + [Dependency] private readonly IComponentFactory _componentFactory = default!; + [Dependency] private readonly ISerializationManager _serializationManager = default!; + [Dependency] private readonly TagSystem _tagSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnCompEquip); + SubscribeLocalEvent(OnCompUnequip); + + SubscribeLocalEvent(OnTagEquip); + SubscribeLocalEvent(OnTagUnequip); + } + + private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent component, GotEquippedEvent args) + { + if (!TryComp(uid, out var clothing)) return; + + if (!clothing.Slots.HasFlag(args.SlotFlags)) return; + + if (component.Components.Count > 1) + { + Logger.Error("Although a component registry supports multiple components, we cannot bookkeep more than 1 component for ClothingGrantComponent at this time."); + return; + } + + foreach (var (name, data) in component.Components) + { + var newComp = (Component) _componentFactory.GetComponent(name); + + if (HasComp(args.Equipee, newComp.GetType())) + continue; + + newComp.Owner = args.Equipee; + + var temp = (object) newComp; + _serializationManager.CopyTo(data.Component, ref temp); + EntityManager.AddComponent(args.Equipee, (Component)temp!); + + component.IsActive = true; + } + } + + private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent component, GotUnequippedEvent args) + { + if (!component.IsActive) return; + + foreach (var (name, data) in component.Components) + { + var newComp = (Component) _componentFactory.GetComponent(name); + + RemComp(args.Equipee, newComp.GetType()); + } + + component.IsActive = false; + } + + + private void OnTagEquip(EntityUid uid, ClothingGrantTagComponent component, GotEquippedEvent args) + { + if (!TryComp(uid, out var clothing)) + return; + + if (!clothing.Slots.HasFlag(args.SlotFlags)) + return; + + EnsureComp(args.Equipee); + _tagSystem.AddTag(args.Equipee, component.Tag); + + component.IsActive = true; + } + + private void OnTagUnequip(EntityUid uid, ClothingGrantTagComponent component, GotUnequippedEvent args) + { + if (!component.IsActive) + return; + + _tagSystem.RemoveTag(args.Equipee, component.Tag); + + component.IsActive = false; + } +} diff --git a/Content.Shared/SimpleStation14/Traits/Components/NearsightedComponent.cs b/Content.Shared/SimpleStation14/Traits/Components/NearsightedComponent.cs new file mode 100644 index 00000000000..fafd8f87102 --- /dev/null +++ b/Content.Shared/SimpleStation14/Traits/Components/NearsightedComponent.cs @@ -0,0 +1,49 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.SimpleStation14.Traits.Components; + +/// +/// Owner entity cannot see well, without prescription glasses. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class NearsightedComponent : Component +{ + /// + /// Distance from the edge of the screen to the center + /// + /// + /// I don't know how the distance is measured, 1 is very close to the center, 0 is maybe visible around the edge + /// + [DataField("radius"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float Radius = 0.8f; + + /// + /// How dark the circle mask is from + /// + /// + /// I also don't know how this works, it only starts getting noticeably dark at 0.7, and is definitely noticeable at 0.9, 1 is black + /// + [DataField("alpha"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float Alpha = 0.995f; + + /// + [DataField("equippedRadius"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float EquippedRadius = 0.45f; + + /// + [DataField("equippedAlpha"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float EquippedAlpha = 0.93f; + + /// + /// How long the lerp animation should go on for in seconds. + /// + [DataField("lerpDuration"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public float LerpDuration = 0.25f; + + /// + /// If true, uses the variables prefixed "Equipped" + /// If false, uses the variables without a prefix + /// + [ViewVariables(VVAccess.ReadWrite)] // Make the system shared if you want this networked, I don't wanna do that + public bool Active = false; +} diff --git a/Content.Shared/Slippery/SlipperyComponent.cs b/Content.Shared/Slippery/SlipperyComponent.cs index ff395176ed0..b470e2cbbd5 100644 --- a/Content.Shared/Slippery/SlipperyComponent.cs +++ b/Content.Shared/Slippery/SlipperyComponent.cs @@ -1,7 +1,6 @@ using Content.Shared.StepTrigger.Components; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Slippery { @@ -11,14 +10,13 @@ namespace Content.Shared.Slippery /// /// Requires , see that component for some additional properties. /// - [RegisterComponent] - [NetworkedComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class SlipperyComponent : Component { /// /// Path to the sound to be played when a mob slips. /// - [DataField("slipSound")] + [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWriteExecute)] public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg"); @@ -26,7 +24,7 @@ public sealed partial class SlipperyComponent : Component /// How many seconds the mob will be paralyzed for. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("paralyzeTime")] + [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] public float ParalyzeTime = 3f; @@ -34,23 +32,8 @@ public sealed partial class SlipperyComponent : Component /// The entity's speed will be multiplied by this to slip it forwards. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("launchForwardsMultiplier")] + [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] public float LaunchForwardsMultiplier = 1f; } - - [Serializable, NetSerializable] - public sealed class SlipperyComponentState : ComponentState - { - public float ParalyzeTime { get; } - public float LaunchForwardsMultiplier { get; } - public string SlipSound { get; } - - public SlipperyComponentState(float paralyzeTime, float launchForwardsMultiplier, string slipSound) - { - ParalyzeTime = paralyzeTime; - LaunchForwardsMultiplier = launchForwardsMultiplier; - SlipSound = slipSound; - } - } } diff --git a/Content.Shared/Slippery/SlipperySystem.cs b/Content.Shared/Slippery/SlipperySystem.cs index 41bfe03c4c3..00f023f9a3a 100644 --- a/Content.Shared/Slippery/SlipperySystem.cs +++ b/Content.Shared/Slippery/SlipperySystem.cs @@ -5,9 +5,7 @@ using Content.Shared.StepTrigger.Systems; using Content.Shared.Stunnable; using JetBrains.Annotations; -using Robust.Shared.Audio; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; @@ -32,22 +30,6 @@ public override void Initialize() SubscribeLocalEvent(OnNoSlipAttempt); // as long as slip-resistant mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer). SubscribeLocalEvent>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args)); - SubscribeLocalEvent(OnSlipperyGetState); - SubscribeLocalEvent(OnSlipperyHandleState); - } - - private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args) - { - if (args.Current is not SlipperyComponentState state) return; - - component.ParalyzeTime = state.ParalyzeTime; - component.LaunchForwardsMultiplier = state.LaunchForwardsMultiplier; - component.SlipSound = new SoundPathSpecifier(state.SlipSound); - } - - private void OnSlipperyGetState(EntityUid uid, SlipperyComponent component, ref ComponentGetState args) - { - args.State = new SlipperyComponentState(component.ParalyzeTime, component.LaunchForwardsMultiplier, _audio.GetSound(component.SlipSound)); } private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent args) @@ -103,14 +85,6 @@ private void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other _adminLogger.Add(LogType.Slip, LogImpact.Low, $"{ToPrettyString(other):mob} slipped on collision with {ToPrettyString(uid):entity}"); } - - public void CopyConstruct(EntityUid destUid, SlipperyComponent srcSlip) - { - var destEvaporation = EntityManager.EnsureComponent(destUid); - destEvaporation.SlipSound = srcSlip.SlipSound; - destEvaporation.ParalyzeTime = srcSlip.ParalyzeTime; - destEvaporation.LaunchForwardsMultiplier = srcSlip.LaunchForwardsMultiplier; - } } /// diff --git a/Content.Shared/Spawners/Components/TimedDespawnComponent.cs b/Content.Shared/Spawners/Components/TimedDespawnComponent.cs deleted file mode 100644 index c66d4810ad4..00000000000 --- a/Content.Shared/Spawners/Components/TimedDespawnComponent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Robust.Shared.GameStates; - -namespace Content.Shared.Spawners.Components; - -/// -/// Put this component on something you would like to despawn after a certain amount of time -/// -[RegisterComponent] -public sealed partial class TimedDespawnComponent : Component -{ - /// - /// How long the entity will exist before despawning - /// - [DataField("lifetime")] - public float Lifetime = 5f; -} diff --git a/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs b/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs deleted file mode 100644 index b867737cb69..00000000000 --- a/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Content.Shared.Spawners.Components; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -using Robust.Shared.Timing; - -namespace Content.Shared.Spawners.EntitySystems; - -public abstract class SharedTimedDespawnSystem : EntitySystem -{ - [Dependency] private readonly IGameTiming _timing = default!; - - public override void Initialize() - { - base.Initialize(); - UpdatesOutsidePrediction = true; - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - // AAAAAAAAAAAAAAAAAAAAAAAAAAA - // Client both needs to predict this, but also can't properly handle prediction resetting. - if (!_timing.IsFirstTimePredicted) - return; - - var query = EntityQueryEnumerator(); - - while (query.MoveNext(out var uid, out var comp)) - { - comp.Lifetime -= frameTime; - - if (!CanDelete(uid)) - continue; - - if (comp.Lifetime <= 0) - { - var ev = new TimedDespawnEvent(); - RaiseLocalEvent(uid, ref ev); - QueueDel(uid); - } - } - } - - protected abstract bool CanDelete(EntityUid uid); -} diff --git a/Content.Shared/Spawners/TimedDespawnEvent.cs b/Content.Shared/Spawners/TimedDespawnEvent.cs deleted file mode 100644 index 26551d86bfd..00000000000 --- a/Content.Shared/Spawners/TimedDespawnEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Shared.Spawners; - -/// -/// Raised directed on an entity when its timed despawn is over. -/// -[ByRefEvent] -public readonly record struct TimedDespawnEvent; diff --git a/Content.Shared/Speech/SpeechComponent.cs b/Content.Shared/Speech/SpeechComponent.cs index f5ef0e0d678..96e05502ad6 100644 --- a/Content.Shared/Speech/SpeechComponent.cs +++ b/Content.Shared/Speech/SpeechComponent.cs @@ -1,8 +1,6 @@ -using System.Collections.Specialized; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; +using Robust.Shared.Prototypes; namespace Content.Shared.Speech { @@ -10,31 +8,30 @@ namespace Content.Shared.Speech /// Component required for entities to be able to speak. (TODO: Entities can speak fine without this, this only forbids them speak if they have it and enabled is false.) /// Contains the option to let entities make noise when speaking, change speech verbs, datafields for the sounds in question, and relevant AudioParams. /// - [RegisterComponent, NetworkedComponent] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class SpeechComponent : Component { - [DataField("enabled"), Access(typeof(SpeechSystem), - Friend = AccessPermissions.ReadWrite, - Other = AccessPermissions.Read)] + [DataField, AutoNetworkedField] + [Access(typeof(SpeechSystem), Friend = AccessPermissions.ReadWrite, Other = AccessPermissions.Read)] public bool Enabled = true; [ViewVariables(VVAccess.ReadWrite)] - [DataField("speechSounds", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string? SpeechSounds; + [DataField] + public ProtoId? SpeechSounds; /// /// What speech verb prototype should be used by default for displaying this entity's messages? /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("speechVerb", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string SpeechVerb = "Default"; + [DataField] + public ProtoId SpeechVerb = "Default"; /// /// A mapping from chat suffixes loc strings to speech verb prototypes that should be conditionally used. /// For things like '?' changing to 'asks' or '!!' making text bold and changing to 'yells'. Can be overridden if necessary. /// - [DataField("suffixSpeechVerbs", customTypeSerializer:typeof(PrototypeIdValueDictionarySerializer))] - public Dictionary SuffixSpeechVerbs = new() + [DataField] + public Dictionary> SuffixSpeechVerbs = new() { { "chat-speech-verb-suffix-exclamation-strong", "DefaultExclamationStrong" }, { "chat-speech-verb-suffix-exclamation", "DefaultExclamation" }, @@ -43,11 +40,11 @@ public sealed partial class SpeechComponent : Component { "chat-speech-verb-suffix-mumble", "DefaultMumble" }, }; - [DataField("audioParams")] + [DataField] public AudioParams AudioParams = AudioParams.Default.WithVolume(6f).WithRolloffFactor(4.5f); [ViewVariables(VVAccess.ReadWrite)] - [DataField("soundCooldownTime")] + [DataField] public float SoundCooldownTime { get; set; } = 0.5f; public TimeSpan LastTimeSoundPlayed = TimeSpan.Zero; diff --git a/Content.Shared/Speech/SpeechSystem.cs b/Content.Shared/Speech/SpeechSystem.cs index a21158aa9e3..4ce408b91a6 100644 --- a/Content.Shared/Speech/SpeechSystem.cs +++ b/Content.Shared/Speech/SpeechSystem.cs @@ -1,6 +1,3 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - namespace Content.Shared.Speech { public sealed class SpeechSystem : EntitySystem @@ -10,8 +7,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnSpeakAttempt); - SubscribeLocalEvent(OnSpeechGetState); - SubscribeLocalEvent(OnSpeechHandleState); } public void SetSpeech(EntityUid uid, bool value, SpeechComponent? component = null) @@ -27,34 +22,10 @@ public void SetSpeech(EntityUid uid, bool value, SpeechComponent? component = nu Dirty(component); } - private void OnSpeechHandleState(EntityUid uid, SpeechComponent component, ref ComponentHandleState args) - { - if (args.Current is not SpeechComponentState state) - return; - - component.Enabled = state.Enabled; - } - - private void OnSpeechGetState(EntityUid uid, SpeechComponent component, ref ComponentGetState args) - { - args.State = new SpeechComponentState(component.Enabled); - } - private void OnSpeakAttempt(SpeakAttemptEvent args) { if (!TryComp(args.Uid, out SpeechComponent? speech) || !speech.Enabled) args.Cancel(); } - - [Serializable, NetSerializable] - private sealed class SpeechComponentState : ComponentState - { - public readonly bool Enabled; - - public SpeechComponentState(bool enabled) - { - Enabled = enabled; - } - } } } diff --git a/Content.Shared/Standing/StandingStateComponent.cs b/Content.Shared/Standing/StandingStateComponent.cs index 583839fa105..5d7bb0a59fd 100644 --- a/Content.Shared/Standing/StandingStateComponent.cs +++ b/Content.Shared/Standing/StandingStateComponent.cs @@ -3,22 +3,22 @@ namespace Content.Shared.Standing { + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] [Access(typeof(StandingStateSystem))] - [RegisterComponent, NetworkedComponent] public sealed partial class StandingStateComponent : Component { [ViewVariables(VVAccess.ReadWrite)] - [DataField("downSound")] + [DataField] public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall"); - [DataField("standing")] + [DataField, AutoNetworkedField] public bool Standing { get; set; } = true; /// /// List of fixtures that had their collision mask changed when the entity was downed. /// Required for re-adding the collision mask. /// - [DataField("changedFixtures")] + [DataField, AutoNetworkedField] public List ChangedFixtures = new(); } } diff --git a/Content.Shared/Standing/StandingStateSystem.cs b/Content.Shared/Standing/StandingStateSystem.cs index 2716ed02df2..bb74a088b3e 100644 --- a/Content.Shared/Standing/StandingStateSystem.cs +++ b/Content.Shared/Standing/StandingStateSystem.cs @@ -2,10 +2,8 @@ using Content.Shared.Physics; using Content.Shared.Rotation; using Robust.Shared.Audio; -using Robust.Shared.GameStates; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; -using Robust.Shared.Serialization; namespace Content.Shared.Standing { @@ -18,26 +16,6 @@ public sealed class StandingStateSystem : EntitySystem // If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited. private const int StandingCollisionLayer = (int) CollisionGroup.MidImpassable; - public override void Initialize() - { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnHandleState(EntityUid uid, StandingStateComponent component, ref ComponentHandleState args) - { - if (args.Current is not StandingComponentState state) - return; - - component.Standing = state.Standing; - component.ChangedFixtures = new List(state.ChangedFixtures); - } - - private void OnGetState(EntityUid uid, StandingStateComponent component, ref ComponentGetState args) - { - args.State = new StandingComponentState(component.Standing, component.ChangedFixtures); - } - public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null) { if (!Resolve(uid, ref standingState, false)) @@ -151,20 +129,6 @@ public bool Stand(EntityUid uid, return true; } - - // I'm not calling it StandingStateComponentState - [Serializable, NetSerializable] - private sealed class StandingComponentState : ComponentState - { - public bool Standing { get; } - public List ChangedFixtures { get; } - - public StandingComponentState(bool standing, List changedFixtures) - { - Standing = standing; - ChangedFixtures = changedFixtures; - } - } } public sealed class DropHandItemsEvent : EventArgs diff --git a/Content.Shared/StatusEffect/StatusEffectsSystem.cs b/Content.Shared/StatusEffect/StatusEffectsSystem.cs index 70822a05f44..bedc5a824ce 100644 --- a/Content.Shared/StatusEffect/StatusEffectsSystem.cs +++ b/Content.Shared/StatusEffect/StatusEffectsSystem.cs @@ -61,7 +61,8 @@ private void OnHandleState(EntityUid uid, StatusEffectsComponent component, ref if (args.Current is not StatusEffectsComponentState state) return; - component.AllowedEffects = new(state.AllowedEffects); + component.AllowedEffects.Clear(); + component.AllowedEffects.AddRange(state.AllowedEffects); // Remove non-existent effects. foreach (var effect in component.ActiveEffects.Keys) diff --git a/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs b/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs index 21cf5397a1f..f4731bf46ab 100644 --- a/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs +++ b/Content.Shared/StepTrigger/Components/StepTriggerComponent.cs @@ -1,58 +1,56 @@ using Content.Shared.StepTrigger.Systems; using Content.Shared.Whitelist; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.StepTrigger.Components; -[RegisterComponent] -[NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] [Access(typeof(StepTriggerSystem))] public sealed partial class StepTriggerComponent : Component { /// /// List of entities that are currently colliding with the entity. /// - [ViewVariables] - public readonly HashSet Colliding = new(); + [ViewVariables, AutoNetworkedField] + public HashSet Colliding = new(); /// /// The list of entities that are standing on this entity, /// which shouldn't be able to trigger it again until stepping off. /// - [ViewVariables] - public readonly HashSet CurrentlySteppedOn = new(); + [ViewVariables, AutoNetworkedField] + public HashSet CurrentlySteppedOn = new(); /// /// Whether or not this component will currently try to trigger for entities. /// - [DataField("active")] + [DataField, AutoNetworkedField] public bool Active = true; /// /// Ratio of shape intersection for a trigger to occur. /// - [DataField("intersectRatio")] + [DataField, AutoNetworkedField] public float IntersectRatio = 0.3f; /// /// Entities will only be triggered if their speed exceeds this limit. /// - [DataField("requiredTriggeredSpeed")] - public float RequiredTriggerSpeed = 3.5f; + [DataField, AutoNetworkedField] + public float RequiredTriggeredSpeed = 3.5f; /// /// If any entities occupy the blacklist on the same tile then steptrigger won't work. /// - [DataField("blacklist")] + [DataField] public EntityWhitelist? Blacklist; /// /// If this is true, steptrigger will still occur on entities that are in air / weightless. They do not /// by default. /// - [DataField("ignoreWeightless")] - public bool IgnoreWeightless = false; + [DataField] + public bool IgnoreWeightless; } [RegisterComponent] @@ -61,23 +59,3 @@ public sealed partial class StepTriggerActiveComponent : Component { } - -[Serializable, NetSerializable] -public sealed class StepTriggerComponentState : ComponentState -{ - public float IntersectRatio { get; } - public float RequiredTriggerSpeed { get; } - public readonly HashSet CurrentlySteppedOn; - public readonly HashSet Colliding; - public readonly bool Active; - - public StepTriggerComponentState(float intersectRatio, HashSet currentlySteppedOn, HashSet colliding, float requiredTriggerSpeed, bool active) - { - IntersectRatio = intersectRatio; - CurrentlySteppedOn = currentlySteppedOn; - RequiredTriggerSpeed = requiredTriggerSpeed; - Active = active; - Colliding = colliding; - } -} - diff --git a/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs b/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs index 335d9bea9f4..ede39b2aa97 100644 --- a/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs +++ b/Content.Shared/StepTrigger/Systems/StepTriggerSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Gravity; using Content.Shared.StepTrigger.Components; -using Robust.Shared.GameStates; using Robust.Shared.Map.Components; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; @@ -16,8 +15,7 @@ public sealed class StepTriggerSystem : EntitySystem public override void Initialize() { UpdatesOutsidePrediction = true; - SubscribeLocalEvent(TriggerGetState); - SubscribeLocalEvent(TriggerHandleState); + SubscribeLocalEvent(TriggerHandleState); SubscribeLocalEvent(OnStartCollide); SubscribeLocalEvent(OnEndCollide); @@ -103,7 +101,7 @@ private void UpdateColliding(EntityUid uid, StepTriggerComponent component, Tran // this is hard to explain var intersect = Box2.Area(otherAabb.Intersect(ourAabb)); var ratio = Math.Max(intersect / Box2.Area(otherAabb), intersect / Box2.Area(ourAabb)); - if (otherPhysics.LinearVelocity.Length() < component.RequiredTriggerSpeed + if (otherPhysics.LinearVelocity.Length() < component.RequiredTriggeredSpeed || component.CurrentlySteppedOn.Contains(otherUid) || ratio < component.IntersectRatio || !CanTrigger(uid, otherUid, component)) @@ -171,24 +169,8 @@ private void OnEndCollide(EntityUid uid, StepTriggerComponent component, ref End } } - - private void TriggerHandleState(EntityUid uid, StepTriggerComponent component, ref ComponentHandleState args) + private void TriggerHandleState(EntityUid uid, StepTriggerComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not StepTriggerComponentState state) - return; - - component.RequiredTriggerSpeed = state.RequiredTriggerSpeed; - component.IntersectRatio = state.IntersectRatio; - component.Active = state.Active; - var stepped = EnsureEntitySet(state.CurrentlySteppedOn, uid); - var colliding = EnsureEntitySet(state.CurrentlySteppedOn, uid); - - component.CurrentlySteppedOn.Clear(); - component.CurrentlySteppedOn.UnionWith(stepped); - - component.Colliding.Clear(); - component.Colliding.UnionWith(colliding); - if (component.Colliding.Count > 0) { EnsureComp(uid); @@ -199,16 +181,6 @@ private void TriggerHandleState(EntityUid uid, StepTriggerComponent component, r } } - private void TriggerGetState(EntityUid uid, StepTriggerComponent component, ref ComponentGetState args) - { - args.State = new StepTriggerComponentState( - component.IntersectRatio, - GetNetEntitySet(component.CurrentlySteppedOn), - GetNetEntitySet(component.Colliding), - component.RequiredTriggerSpeed, - component.Active); - } - public void SetIntersectRatio(EntityUid uid, float ratio, StepTriggerComponent? component = null) { if (!Resolve(uid, ref component)) @@ -226,10 +198,10 @@ public void SetRequiredTriggerSpeed(EntityUid uid, float speed, StepTriggerCompo if (!Resolve(uid, ref component)) return; - if (MathHelper.CloseToPercent(component.RequiredTriggerSpeed, speed)) + if (MathHelper.CloseToPercent(component.RequiredTriggeredSpeed, speed)) return; - component.RequiredTriggerSpeed = speed; + component.RequiredTriggeredSpeed = speed; Dirty(uid, component); } diff --git a/Content.Shared/Storage/Components/BinComponent.cs b/Content.Shared/Storage/Components/BinComponent.cs index 4294ce1e790..99e2a9844a4 100644 --- a/Content.Shared/Storage/Components/BinComponent.cs +++ b/Content.Shared/Storage/Components/BinComponent.cs @@ -3,8 +3,6 @@ using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Storage.Components; @@ -12,7 +10,8 @@ namespace Content.Shared.Storage.Components; /// This is used for things like paper bins, in which /// you can only take off of the top of the bin. /// -[RegisterComponent, NetworkedComponent, Access(typeof(BinSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(BinSystem))] public sealed partial class BinComponent : Component { /// @@ -30,42 +29,25 @@ public sealed partial class BinComponent : Component /// i can handle entities being deleted and removed /// out of order by other systems /// - [DataField("items")] + [DataField, AutoNetworkedField] public List Items = new(); /// /// The items that start in the bin. Sorted in order. /// - [DataField("initialContents", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List InitialContents = new(); + [DataField] + public List InitialContents = new(); /// /// A whitelist governing what items can be inserted into the bin. /// - [DataField("whitelist")] + [DataField, AutoNetworkedField] public EntityWhitelist? Whitelist; /// /// The maximum amount of items /// that can be stored in the bin. /// - [DataField("maxItems")] + [DataField, AutoNetworkedField] public int MaxItems = 20; } - -[Serializable, NetSerializable] -public sealed class BinComponentState : ComponentState -{ - public List Items; - - public EntityWhitelist? Whitelist; - - public int MaxItems; - - public BinComponentState(List items, EntityWhitelist? whitelist, int maxItems) - { - Items = items; - Whitelist = whitelist; - MaxItems = maxItems; - } -} diff --git a/Content.Shared/Storage/Components/SharedEntityStorageComponent.cs b/Content.Shared/Storage/Components/SharedEntityStorageComponent.cs index db1d3bac9af..80f38188ea9 100644 --- a/Content.Shared/Storage/Components/SharedEntityStorageComponent.cs +++ b/Content.Shared/Storage/Components/SharedEntityStorageComponent.cs @@ -27,19 +27,19 @@ public abstract partial class SharedEntityStorageComponent : Component /// /// Collision masks that were removed from ANY layer when the storage was opened; /// - [DataField("removedMasks")] + [DataField] public int RemovedMasks; /// /// The total amount of items that can fit in one entitystorage /// - [DataField("capacity")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public int Capacity = 30; /// /// Whether or not the entity still has collision when open /// - [DataField("isCollidableWhenOpen")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool IsCollidableWhenOpen; /// @@ -47,71 +47,70 @@ public abstract partial class SharedEntityStorageComponent : Component /// If false, it prevents the storage from opening when the entity inside of it moves. /// This is for objects that you want the player to move while inside, like large cardboard boxes, without opening the storage. /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("openOnMove")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool OpenOnMove = true; //The offset for where items are emptied/vacuumed for the EntityStorage. - [DataField("enteringOffset")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public Vector2 EnteringOffset = new(0, 0); //The collision groups checked, so that items are depositied or grabbed from inside walls. - [DataField("enteringOffsetCollisionFlags")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public CollisionGroup EnteringOffsetCollisionFlags = CollisionGroup.Impassable | CollisionGroup.MidImpassable; /// /// How close you have to be to the "entering" spot to be able to enter /// - [DataField("enteringRange")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public float EnteringRange = 0.18f; /// /// Whether or not to show the contents when the storage is closed /// - [DataField("showContents")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool ShowContents; /// /// Whether or not light is occluded by the storage /// - [DataField("occludesLight")] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool OccludesLight = true; /// /// Whether or not all the contents stored should be deleted with the entitystorage /// - [DataField("deleteContentsOnDestruction"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool DeleteContentsOnDestruction; /// /// Whether or not the container is sealed and traps air inside of it /// - [DataField("airtight"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool Airtight = true; /// /// Whether or not the entitystorage is open or closed /// - [DataField("open")] + [DataField] public bool Open; /// /// The sound made when closed /// - [DataField("closeSound")] + [DataField] public SoundSpecifier CloseSound = new SoundPathSpecifier("/Audio/Effects/closetclose.ogg"); /// /// The sound made when open /// - [DataField("openSound")] + [DataField] public SoundSpecifier OpenSound = new SoundPathSpecifier("/Audio/Effects/closetopen.ogg"); /// /// Whitelist for what entities are allowed to be inserted into this container. If this is not null, the /// standard requirement that the entity must be an item or mob is waived. /// - [DataField("whitelist")] + [DataField] public EntityWhitelist? Whitelist; /// diff --git a/Content.Shared/Storage/EntitySystems/BinSystem.cs b/Content.Shared/Storage/EntitySystems/BinSystem.cs index e82861f4e15..86726587f01 100644 --- a/Content.Shared/Storage/EntitySystems/BinSystem.cs +++ b/Content.Shared/Storage/EntitySystems/BinSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Interaction; using Content.Shared.Storage.Components; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Timing; @@ -27,8 +26,6 @@ public sealed class BinSystem : EntitySystem /// public override void Initialize() { - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnEntRemoved); @@ -36,21 +33,6 @@ public override void Initialize() SubscribeLocalEvent(OnAfterInteractUsing); } - private void OnGetState(EntityUid uid, BinComponent component, ref ComponentGetState args) - { - args.State = new BinComponentState(GetNetEntityList(component.Items), component.Whitelist, component.MaxItems); - } - - private void OnHandleState(EntityUid uid, BinComponent component, ref ComponentHandleState args) - { - if (args.Current is not BinComponentState state) - return; - - component.Items = EnsureEntityList(state.Items, uid); - component.Whitelist = state.Whitelist; - component.MaxItems = state.MaxItems; - } - private void OnStartup(EntityUid uid, BinComponent component, ComponentStartup args) { component.ItemContainer = _container.EnsureContainer(uid, BinContainerId); diff --git a/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs index b4c0a639799..7553fb6c9cc 100644 --- a/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedEntityStorageSystem.cs @@ -15,7 +15,6 @@ using Content.Shared.Tools.Systems; using Content.Shared.Verbs; using Content.Shared.Wall; -using Content.Shared.Whitelist; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Map; @@ -41,7 +40,7 @@ public abstract class SharedEntityStorageSystem : EntitySystem [Dependency] private readonly SharedJointSystem _joints = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] protected readonly SharedTransformSystem TransformSystem = default!; [Dependency] private readonly WeldableSystem _weldable = default!; public const string ContainerName = "entity_storage"; @@ -103,7 +102,7 @@ protected void OnLockToggleAttempt(EntityUid uid, SharedEntityStorageComponent t protected void OnDestruction(EntityUid uid, SharedEntityStorageComponent component, DestructionEventArgs args) { component.Open = true; - Dirty(component); + Dirty(uid, component); if (!component.DeleteContentsOnDestruction) { EmptyContents(uid, component); @@ -199,7 +198,7 @@ public void OpenStorage(EntityUid uid, SharedEntityStorageComponent? component = var beforeev = new StorageBeforeOpenEvent(); RaiseLocalEvent(uid, ref beforeev); component.Open = true; - Dirty(component); + Dirty(uid, component); EmptyContents(uid, component); ModifyComponents(uid, component); if (_net.IsClient && _timing.IsFirstTimePredicted) @@ -215,7 +214,7 @@ public void CloseStorage(EntityUid uid, SharedEntityStorageComponent? component return; component.Open = false; - Dirty(component); + Dirty(uid, component); var targetCoordinates = new EntityCoordinates(uid, component.EnteringOffset); @@ -228,7 +227,7 @@ public void CloseStorage(EntityUid uid, SharedEntityStorageComponent? component { if (!ev.BypassChecks.Contains(entity)) { - if (!CanFit(entity, uid, component.Whitelist)) + if (!CanInsert(entity, uid, component)) continue; } @@ -256,7 +255,7 @@ public bool Insert(EntityUid toInsert, EntityUid container, SharedEntityStorageC if (component.Open) { - _transform.SetWorldPosition(toInsert, _transform.GetWorldPosition(container)); + TransformSystem.SetWorldPosition(toInsert, TransformSystem.GetWorldPosition(container)); return true; } @@ -276,12 +275,12 @@ public bool Remove(EntityUid toRemove, EntityUid container, SharedEntityStorageC RemComp(toRemove); component.Contents.Remove(toRemove, EntityManager); - var pos = _transform.GetWorldPosition(xform) + _transform.GetWorldRotation(xform).RotateVec(component.EnteringOffset); - _transform.SetWorldPosition(toRemove, pos); + var pos = TransformSystem.GetWorldPosition(xform) + TransformSystem.GetWorldRotation(xform).RotateVec(component.EnteringOffset); + TransformSystem.SetWorldPosition(toRemove, pos); return true; } - public bool CanInsert(EntityUid container, SharedEntityStorageComponent? component = null) + public bool CanInsert(EntityUid toInsert, EntityUid container, SharedEntityStorageComponent? component = null) { if (!ResolveStorage(container, ref component)) return false; @@ -292,7 +291,7 @@ public bool CanInsert(EntityUid container, SharedEntityStorageComponent? compone if (component.Contents.ContainedEntities.Count >= component.Capacity) return false; - return true; + return CanFit(toInsert, container, component); } public bool TryOpenStorage(EntityUid user, EntityUid target, bool silent = false) @@ -376,8 +375,11 @@ public bool AddToContents(EntityUid toAdd, EntityUid container, SharedEntityStor return Insert(toAdd, container, component); } - public bool CanFit(EntityUid toInsert, EntityUid container, EntityWhitelist? whitelist) + private bool CanFit(EntityUid toInsert, EntityUid container, SharedEntityStorageComponent? component = null) { + if (!Resolve(container, ref component)) + return false; + // conditions are complicated because of pizzabox-related issues, so follow this guide // 0. Accomplish your goals at all costs. // 1. AddToContents can block anything @@ -395,7 +397,7 @@ public bool CanFit(EntityUid toInsert, EntityUid container, EntityWhitelist? whi var targetIsMob = HasComp(toInsert); var storageIsItem = HasComp(container); - var allowedToEat = whitelist?.IsValid(toInsert) ?? HasComp(toInsert); + var allowedToEat = component.Whitelist?.IsValid(toInsert) ?? HasComp(toInsert); // BEFORE REPLACING THIS WITH, I.E. A PROPERTY: // Make absolutely 100% sure you have worked out how to stop people ending up in backpacks. diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index 4f1534f5443..4875f2f68f8 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -155,6 +155,10 @@ public bool TryStun(EntityUid uid, TimeSpan time, bool refresh, if (!_statusEffect.TryAddStatusEffect(uid, "Stun", time, refresh)) return false; + + var ev = new StunnedEvent(); + RaiseLocalEvent(uid, ref ev); + _adminLogger.Add(LogType.Stamina, LogImpact.Medium, $"{ToPrettyString(uid):user} stunned for {time.Seconds} seconds"); return true; } @@ -171,7 +175,13 @@ public bool TryKnockdown(EntityUid uid, TimeSpan time, bool refresh, if (!Resolve(uid, ref status, false)) return false; - return _statusEffect.TryAddStatusEffect(uid, "KnockedDown", time, refresh); + if (!_statusEffect.TryAddStatusEffect(uid, "KnockedDown", time, refresh)) + return false; + + var ev = new KnockedDownEvent(); + RaiseLocalEvent(uid, ref ev); + + return true; } /// @@ -271,5 +281,16 @@ private void OnUnequipAttempt(EntityUid uid, StunnedComponent stunned, IsUnequip } #endregion - } + +/// +/// Raised directed on an entity when it is stunned. +/// +[ByRefEvent] +public record struct StunnedEvent; + +/// +/// Raised directed on an entity when it is knocked down. +/// +[ByRefEvent] +public record struct KnockedDownEvent; diff --git a/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs b/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs index e1aa281d17d..eb8ab36243c 100644 --- a/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs +++ b/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs @@ -6,11 +6,10 @@ namespace Content.Shared.Tabletop.Components; /// /// Allows an entity to be dragged around by the mouse. The position is updated for all player while dragging. /// -[NetworkedComponent] -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class TabletopDraggableComponent : Component { // The player dragging the piece - [ViewVariables] + [ViewVariables, AutoNetworkedField] public NetUserId? DraggingPlayer; } diff --git a/Content.Shared/Tabletop/SharedTabletopSystem.cs b/Content.Shared/Tabletop/SharedTabletopSystem.cs index 1ff90303411..7bfd9d34572 100644 --- a/Content.Shared/Tabletop/SharedTabletopSystem.cs +++ b/Content.Shared/Tabletop/SharedTabletopSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Interaction; using Content.Shared.Tabletop.Components; using Content.Shared.Tabletop.Events; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Serialization; @@ -22,7 +21,6 @@ public abstract class SharedTabletopSystem : EntitySystem public override void Initialize() { - SubscribeLocalEvent(GetDraggableState); SubscribeAllEvent(OnDraggingPlayerChanged); SubscribeAllEvent(OnTabletopMove); } @@ -47,11 +45,6 @@ protected virtual void OnTabletopMove(TabletopMoveEvent msg, EntitySessionEventA _transforms.SetLocalPositionNoLerp(transform, msg.Coordinates.Position); } - private void GetDraggableState(EntityUid uid, TabletopDraggableComponent component, ref ComponentGetState args) - { - args.State = new TabletopDraggableComponentState(component.DraggingPlayer); - } - private void OnDraggingPlayerChanged(TabletopDraggingPlayerChangedEvent msg, EntitySessionEventArgs args) { var dragged = GetEntity(msg.DraggedEntityUid); diff --git a/Content.Shared/Teleportation/Components/LinkedEntityComponent.cs b/Content.Shared/Teleportation/Components/LinkedEntityComponent.cs index ae9a1a03d0d..f9ad509d1fe 100644 --- a/Content.Shared/Teleportation/Components/LinkedEntityComponent.cs +++ b/Content.Shared/Teleportation/Components/LinkedEntityComponent.cs @@ -8,31 +8,21 @@ namespace Content.Shared.Teleportation.Components; /// Represents an entity which is linked to other entities (perhaps portals), and which can be walked through/ /// thrown into to teleport an entity. /// -[RegisterComponent, Access(typeof(LinkedEntitySystem)), NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(LinkedEntitySystem))] public sealed partial class LinkedEntityComponent : Component { /// /// The entities that this entity is linked to. /// - [DataField("linkedEntities")] + [DataField, AutoNetworkedField] public HashSet LinkedEntities = new(); /// /// Should this entity be deleted if all of its links are removed? /// - [DataField("deleteOnEmptyLinks")] - public bool DeleteOnEmptyLinks = false; -} - -[Serializable, NetSerializable] -public sealed class LinkedEntityComponentState : ComponentState -{ - public HashSet LinkedEntities; - - public LinkedEntityComponentState(HashSet linkedEntities) - { - LinkedEntities = linkedEntities; - } + [DataField] + public bool DeleteOnEmptyLinks; } [Serializable, NetSerializable] diff --git a/Content.Shared/Teleportation/Components/PortalTimeoutComponent.cs b/Content.Shared/Teleportation/Components/PortalTimeoutComponent.cs index 37441508e11..341c68d7c86 100644 --- a/Content.Shared/Teleportation/Components/PortalTimeoutComponent.cs +++ b/Content.Shared/Teleportation/Components/PortalTimeoutComponent.cs @@ -1,5 +1,4 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization; namespace Content.Shared.Teleportation.Components; @@ -7,23 +6,12 @@ namespace Content.Shared.Teleportation.Components; /// Attached to an entity after portal transit to mark that they should not immediately be portaled back /// at the end destination. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class PortalTimeoutComponent : Component { /// /// The portal that was entered. Null if coming from a hand teleporter, etc. /// - [ViewVariables, DataField("enteredPortal")] - public EntityUid? EnteredPortal = null; -} - -[Serializable, NetSerializable] -public sealed class PortalTimeoutComponentState : ComponentState -{ - public NetEntity? EnteredPortal; - - public PortalTimeoutComponentState(NetEntity? enteredPortal) - { - EnteredPortal = enteredPortal; - } + [ViewVariables, DataField, AutoNetworkedField] + public EntityUid? EnteredPortal; } diff --git a/Content.Shared/Teleportation/Systems/LinkedEntitySystem.cs b/Content.Shared/Teleportation/Systems/LinkedEntitySystem.cs index 73e686e8bdc..ed979754527 100644 --- a/Content.Shared/Teleportation/Systems/LinkedEntitySystem.cs +++ b/Content.Shared/Teleportation/Systems/LinkedEntitySystem.cs @@ -1,7 +1,6 @@ -using Content.Shared.Teleportation.Components; -using Robust.Shared.GameStates; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Shared.Teleportation.Components; namespace Content.Shared.Teleportation.Systems; @@ -20,22 +19,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnLinkShutdown); - - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); - } - - private void OnGetState(EntityUid uid, LinkedEntityComponent component, ref ComponentGetState args) - { - args.State = new LinkedEntityComponentState(GetNetEntitySet(component.LinkedEntities)); - } - - private void OnHandleState(EntityUid uid, LinkedEntityComponent component, ref ComponentHandleState args) - { - if (args.Current is LinkedEntityComponentState state) - { - component.LinkedEntities = EnsureEntitySet(state.LinkedEntities, uid); - } } private void OnLinkShutdown(EntityUid uid, LinkedEntityComponent component, ComponentShutdown args) diff --git a/Content.Shared/Teleportation/Systems/SharedPortalSystem.cs b/Content.Shared/Teleportation/Systems/SharedPortalSystem.cs index 1ecaca57c3c..e614a2c040f 100644 --- a/Content.Shared/Teleportation/Systems/SharedPortalSystem.cs +++ b/Content.Shared/Teleportation/Systems/SharedPortalSystem.cs @@ -1,13 +1,11 @@ using System.Linq; using Content.Shared.Ghost; -using Content.Shared.Pinpointer; using Content.Shared.Popups; using Content.Shared.Projectiles; using Content.Shared.Pulling; using Content.Shared.Pulling.Components; using Content.Shared.Teleportation.Components; using Content.Shared.Verbs; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Physics.Dynamics; @@ -42,9 +40,6 @@ public override void Initialize() SubscribeLocalEvent(OnCollide); SubscribeLocalEvent(OnEndCollide); SubscribeLocalEvent>(OnGetVerbs); - - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); } private void OnGetVerbs(EntityUid uid, PortalComponent component, GetVerbsEvent args) @@ -77,17 +72,6 @@ private void OnGetVerbs(EntityUid uid, PortalComponent component, GetVerbsEvent< }); } - private void OnGetState(EntityUid uid, PortalTimeoutComponent component, ref ComponentGetState args) - { - args.State = new PortalTimeoutComponentState(GetNetEntity(component.EnteredPortal)); - } - - private void OnHandleState(EntityUid uid, PortalTimeoutComponent component, ref ComponentHandleState args) - { - if (args.Current is PortalTimeoutComponentState state) - component.EnteredPortal = EnsureEntity(state.EnteredPortal, uid); - } - private bool ShouldCollide(string ourId, string otherId, Fixture our, Fixture other) { // most non-hard fixtures shouldn't pass through portals, but projectiles are non-hard as well diff --git a/Content.Shared/Timing/UseDelayComponent.cs b/Content.Shared/Timing/UseDelayComponent.cs index aa12f04847a..4135bf26fe1 100644 --- a/Content.Shared/Timing/UseDelayComponent.cs +++ b/Content.Shared/Timing/UseDelayComponent.cs @@ -1,45 +1,28 @@ -using System.Threading; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -namespace Content.Shared.Timing -{ - /// - /// Timer that creates a cooldown each time an object is activated/used - /// - [RegisterComponent] - [NetworkedComponent] - public sealed partial class UseDelayComponent : Component - { - public TimeSpan LastUseTime; - - public TimeSpan? DelayEndTime; +namespace Content.Shared.Timing; - [DataField("delay")] - [ViewVariables(VVAccess.ReadWrite)] - public TimeSpan Delay = TimeSpan.FromSeconds(1); +/// +/// Timer that creates a cooldown each time an object is activated/used +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class UseDelayComponent : Component +{ + [AutoNetworkedField] + public TimeSpan LastUseTime; - /// - /// Stores remaining delay pausing (and eventually, serialization). - /// - [DataField("remainingDelay")] - public TimeSpan? RemainingDelay; + [AutoNetworkedField] + public TimeSpan? DelayEndTime; - public bool ActiveDelay => DelayEndTime != null; - } + [DataField, AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan Delay = TimeSpan.FromSeconds(1); - [Serializable, NetSerializable] - public sealed class UseDelayComponentState : ComponentState - { - public readonly TimeSpan LastUseTime; - public readonly TimeSpan Delay; - public readonly TimeSpan? DelayEndTime; + /// + /// Stores remaining delay pausing (and eventually, serialization). + /// + [DataField] + public TimeSpan? RemainingDelay; - public UseDelayComponentState(TimeSpan lastUseTime, TimeSpan delay, TimeSpan? delayEndTime) - { - LastUseTime = lastUseTime; - Delay = delay; - DelayEndTime = delayEndTime; - } - } + public bool ActiveDelay => DelayEndTime != null; } diff --git a/Content.Shared/Timing/UseDelaySystem.cs b/Content.Shared/Timing/UseDelaySystem.cs index f6dcdafe41d..1d1d636b89f 100644 --- a/Content.Shared/Timing/UseDelaySystem.cs +++ b/Content.Shared/Timing/UseDelaySystem.cs @@ -1,6 +1,4 @@ -using System.Threading; using Content.Shared.Cooldown; -using Robust.Shared.GameStates; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -16,8 +14,7 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); + SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnPaused); SubscribeLocalEvent(OnUnpaused); @@ -45,26 +42,14 @@ private void OnUnpaused(EntityUid uid, UseDelayComponent component, ref EntityUn _activeDelays.Add(component); } - private void OnHandleState(EntityUid uid, UseDelayComponent component, ref ComponentHandleState args) + private void OnHandleState(EntityUid uid, UseDelayComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not UseDelayComponentState state) - return; - - component.LastUseTime = state.LastUseTime; - component.Delay = state.Delay; - component.DelayEndTime = state.DelayEndTime; - if (component.DelayEndTime == null) _activeDelays.Remove(component); else _activeDelays.Add(component); } - private void OnGetState(EntityUid uid, UseDelayComponent component, ref ComponentGetState args) - { - args.State = new UseDelayComponentState(component.LastUseTime, component.Delay, component.DelayEndTime); - } - public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Shared/Tools/Components/MultipleToolComponent.cs b/Content.Shared/Tools/Components/MultipleToolComponent.cs index 87fa4ad1750..4e30abb5ad8 100644 --- a/Content.Shared/Tools/Components/MultipleToolComponent.cs +++ b/Content.Shared/Tools/Components/MultipleToolComponent.cs @@ -1,53 +1,41 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; using Robust.Shared.Utility; -namespace Content.Shared.Tools.Components +namespace Content.Shared.Tools.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class MultipleToolComponent : Component { - [RegisterComponent, NetworkedComponent] - public sealed partial class MultipleToolComponent : Component + [DataDefinition] + public sealed partial class ToolEntry { - [DataDefinition] - public sealed partial class ToolEntry - { - [DataField("behavior", required: true)] - public PrototypeFlags Behavior = new(); - - [DataField("useSound")] - public SoundSpecifier? Sound; + [DataField(required: true)] + public PrototypeFlags Behavior = new(); - [DataField("changeSound")] - public SoundSpecifier? ChangeSound; + [DataField] + public SoundSpecifier? UseSound; - [DataField("sprite")] - public SpriteSpecifier? Sprite; - } + [DataField] + public SoundSpecifier? ChangeSound; - [DataField("entries", required: true)] - public ToolEntry[] Entries { get; private set; } = Array.Empty(); + [DataField] + public SpriteSpecifier? Sprite; + } - [ViewVariables] - public uint CurrentEntry = 0; + [DataField(required: true)] + public ToolEntry[] Entries { get; private set; } = Array.Empty(); - [ViewVariables] - public string CurrentQualityName = string.Empty; + [ViewVariables] + [AutoNetworkedField] + public uint CurrentEntry = 0; - [ViewVariables(VVAccess.ReadWrite)] - public bool UiUpdateNeeded; + [ViewVariables] + public string CurrentQualityName = string.Empty; - [DataField("statusShowBehavior")] - public bool StatusShowBehavior = true; - } + [ViewVariables(VVAccess.ReadWrite)] + public bool UiUpdateNeeded; - [NetSerializable, Serializable] - public sealed class MultipleToolComponentState : ComponentState - { - public readonly uint Selected; - - public MultipleToolComponentState(uint selected) - { - Selected = selected; - } - } + [DataField] + public bool StatusShowBehavior = true; } diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs index b198f6d779c..39a1dc50f32 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs @@ -1,7 +1,7 @@ using System.Linq; using Content.Shared.Interaction; using Content.Shared.Tools.Components; -using Robust.Shared.GameStates; +using Content.Shared.Prying.Components; namespace Content.Shared.Tools; @@ -11,23 +11,18 @@ public void InitializeMultipleTool() { SubscribeLocalEvent(OnMultipleToolStartup); SubscribeLocalEvent(OnMultipleToolActivated); - SubscribeLocalEvent(OnMultipleToolGetState); - SubscribeLocalEvent(OnMultipleToolHandleState); + SubscribeLocalEvent(OnMultipleToolHandleState); } - private void OnMultipleToolHandleState(EntityUid uid, MultipleToolComponent component, ref ComponentHandleState args) + private void OnMultipleToolHandleState(EntityUid uid, MultipleToolComponent component, ref AfterAutoHandleStateEvent args) { - if (args.Current is not MultipleToolComponentState state) - return; - - component.CurrentEntry = state.Selected; SetMultipleTool(uid, component); } private void OnMultipleToolStartup(EntityUid uid, MultipleToolComponent multiple, ComponentStartup args) { // Only set the multiple tool if we have a tool component. - if(EntityManager.TryGetComponent(uid, out ToolComponent? tool)) + if (EntityManager.TryGetComponent(uid, out ToolComponent? tool)) SetMultipleTool(uid, multiple, tool); } @@ -39,11 +34,6 @@ private void OnMultipleToolActivated(EntityUid uid, MultipleToolComponent multip args.Handled = CycleMultipleTool(uid, multiple, args.User); } - private void OnMultipleToolGetState(EntityUid uid, MultipleToolComponent multiple, ref ComponentGetState args) - { - args.State = new MultipleToolComponentState(multiple.CurrentEntry); - } - public bool CycleMultipleTool(EntityUid uid, MultipleToolComponent? multiple = null, EntityUid? user = null) { if (!Resolve(uid, ref multiple)) @@ -52,7 +42,7 @@ public bool CycleMultipleTool(EntityUid uid, MultipleToolComponent? multiple = n if (multiple.Entries.Length == 0) return false; - multiple.CurrentEntry = (uint) ((multiple.CurrentEntry + 1) % multiple.Entries.Length); + multiple.CurrentEntry = (uint)((multiple.CurrentEntry + 1) % multiple.Entries.Length); SetMultipleTool(uid, multiple, playSound: true, user: user); return true; @@ -76,9 +66,22 @@ public virtual void SetMultipleTool(EntityUid uid, } var current = multiple.Entries[multiple.CurrentEntry]; - tool.UseSound = current.Sound; + tool.UseSound = current.UseSound; tool.Qualities = current.Behavior; + // TODO: Replace this with a better solution later + if (TryComp(uid, out var pcomp)) + { + if (current.Behavior.Contains("Prying")) + { + pcomp.Enabled = true; + } + else + { + pcomp.Enabled = false; + } + } + if (playSound && current.ChangeSound != null) _audioSystem.PlayPredicted(current.ChangeSound, uid, user); diff --git a/Content.Shared/Vehicle/SharedVehicleSystem.cs b/Content.Shared/Vehicle/SharedVehicleSystem.cs index 9ba22d644a4..334c115ba8d 100644 --- a/Content.Shared/Vehicle/SharedVehicleSystem.cs +++ b/Content.Shared/Vehicle/SharedVehicleSystem.cs @@ -91,8 +91,8 @@ private void OnVehicleStartup(EntityUid uid, VehicleComponent component, Compone // This code should be purged anyway but with that being said this doesn't handle components being changed. if (TryComp(uid, out var strap)) { - component.BaseBuckleOffset = strap.BuckleOffset; - strap.BuckleOffsetUnclamped = Vector2.Zero; + component.BaseBuckleOffset = strap.BuckleOffsetClamped; + strap.BuckleOffset = Vector2.Zero; } _modifier.RefreshMovementSpeedModifiers(uid); @@ -301,9 +301,9 @@ private void UpdateBuckleOffset(EntityUid uid, TransformComponent xform, Vehicle return; // TODO: Strap should handle this but buckle E/C moment. - var oldOffset = strap.BuckleOffsetUnclamped; + var oldOffset = strap.BuckleOffset; - strap.BuckleOffsetUnclamped = xform.LocalRotation.Degrees switch + strap.BuckleOffset = xform.LocalRotation.Degrees switch { < 45f => new(0, component.SouthOverride), <= 135f => component.BaseBuckleOffset, @@ -312,13 +312,13 @@ private void UpdateBuckleOffset(EntityUid uid, TransformComponent xform, Vehicle _ => new(0, component.SouthOverride) }; - if (!oldOffset.Equals(strap.BuckleOffsetUnclamped)) + if (!oldOffset.Equals(strap.BuckleOffset)) Dirty(strap); foreach (var buckledEntity in strap.BuckledEntities) { var buckleXform = Transform(buckledEntity); - _transform.SetLocalPositionNoLerp(buckleXform, strap.BuckleOffset); + _transform.SetLocalPositionNoLerp(buckleXform, strap.BuckleOffsetClamped); } } diff --git a/Content.Shared/Verbs/Verb.cs b/Content.Shared/Verbs/Verb.cs index 33576b6b9c7..76ed2073075 100644 --- a/Content.Shared/Verbs/Verb.cs +++ b/Content.Shared/Verbs/Verb.cs @@ -1,7 +1,7 @@ -using Robust.Shared.Serialization; -using Robust.Shared.Utility; using Content.Shared.Database; using Content.Shared.Interaction.Events; +using Robust.Shared.Serialization; +using Robust.Shared.Utility; namespace Content.Shared.Verbs { @@ -215,6 +215,7 @@ public int CompareTo(object? obj) public static List VerbTypes = new() { typeof(Verb), + typeof(VvVerb), typeof(InteractionVerb), typeof(UtilityVerb), typeof(InnateVerb), @@ -225,6 +226,16 @@ public int CompareTo(object? obj) }; } + /// + /// View variables verbs. + /// + /// Currently only used for the verb that opens the view variables panel. + [Serializable, NetSerializable] + public sealed class VvVerb : Verb + { + public override int TypePriority => int.MaxValue; + } + /// /// Primary interaction verbs. This includes both use-in-hand and interacting with external entities. /// diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs index 9e7ad7e3a79..ddc060e558b 100644 --- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs +++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs @@ -3,16 +3,14 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Weapons.Melee; /// /// When given to a mob lets them do unarmed attacks, or when given to an item lets someone wield it to do attacks. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MeleeWeaponComponent : Component { // TODO: This is becoming bloated as shit. @@ -20,26 +18,27 @@ public sealed partial class MeleeWeaponComponent : Component /// /// Does this entity do a disarm on alt attack. /// - [DataField("altDisarm"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool AltDisarm = true; /// /// Should the melee weapon's damage stats be examinable. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("hidden")] - public bool HideFromExamine; + [DataField] + public bool Hidden; /// /// Next time this component is allowed to light attack. Heavy attacks are wound up and never have a cooldown. /// - [ViewVariables(VVAccess.ReadWrite), DataField("nextAttack", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] public TimeSpan NextAttack; /// /// Starts attack cooldown when equipped if true. /// - [ViewVariables(VVAccess.ReadWrite), DataField("resetOnHandSelected")] + [ViewVariables(VVAccess.ReadWrite), DataField] public bool ResetOnHandSelected = true; /* @@ -51,50 +50,51 @@ public sealed partial class MeleeWeaponComponent : Component /// /// How many times we can attack per second. /// - [ViewVariables(VVAccess.ReadWrite), DataField("attackRate")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float AttackRate = 1f; /// /// Are we currently holding down the mouse for an attack. /// Used so we can't just hold the mouse button and attack constantly. /// - [ViewVariables(VVAccess.ReadWrite)] + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] public bool Attacking = false; /// /// Base damage for this weapon. Can be modified via heavy damage or other means. /// - [DataField("damage", required:true)] + [DataField(required:true)] [ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier Damage = default!; - [DataField("bluntStaminaDamageFactor")] [ViewVariables(VVAccess.ReadWrite)] + [DataField] + [ViewVariables(VVAccess.ReadWrite)] public FixedPoint2 BluntStaminaDamageFactor = FixedPoint2.New(0.5f); /// /// Multiplies damage by this amount for single-target attacks. /// - [ViewVariables(VVAccess.ReadWrite), DataField("clickDamageModifier")] + [ViewVariables(VVAccess.ReadWrite), DataField] public FixedPoint2 ClickDamageModifier = FixedPoint2.New(1); // TODO: Temporarily 1.5 until interactionoutline is adjusted to use melee, then probably drop to 1.2 /// /// Nearest edge range to hit an entity. /// - [ViewVariables(VVAccess.ReadWrite), DataField("range")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public float Range = 1.5f; /// /// Total width of the angle for wide attacks. /// - [ViewVariables(VVAccess.ReadWrite), DataField("angle")] + [ViewVariables(VVAccess.ReadWrite), DataField] public Angle Angle = Angle.FromDegrees(60); - [ViewVariables(VVAccess.ReadWrite), DataField("animation", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string ClickAnimation = "WeaponArcPunch"; + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public EntProtoId Animation = "WeaponArcPunch"; - [ViewVariables(VVAccess.ReadWrite), DataField("wideAnimation", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string WideAnimation = "WeaponArcSlash"; + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public EntProtoId WideAnimation = "WeaponArcSlash"; // Sounds @@ -132,27 +132,3 @@ public sealed class GetMeleeWeaponEvent : HandledEntityEventArgs { public EntityUid? Weapon; } - -[Serializable, NetSerializable] -public sealed class MeleeWeaponComponentState : ComponentState -{ - // None of the other data matters for client as they're not predicted. - - public float AttackRate; - public bool Attacking; - public TimeSpan NextAttack; - - public string ClickAnimation; - public string WideAnimation; - public float Range; - - public MeleeWeaponComponentState(float attackRate, bool attacking, TimeSpan nextAttack, string clickAnimation, string wideAnimation, float range) - { - AttackRate = attackRate; - Attacking = attacking; - NextAttack = nextAttack; - ClickAnimation = clickAnimation; - WideAnimation = wideAnimation; - Range = range; - } -} diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 08ecea43263..9b61fd03b7d 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -20,7 +20,6 @@ using Content.Shared.Weapons.Ranged.Events; using Content.Shared.Weapons.Ranged.Systems; using Robust.Shared.Audio; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; @@ -65,8 +64,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnMeleeUnpaused); - SubscribeLocalEvent(OnGetState); - SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnMeleeSelected); SubscribeLocalEvent(OnMeleeShotAttempted); SubscribeLocalEvent(OnMeleeShot); @@ -223,25 +220,6 @@ private void OnDisarmAttack(DisarmAttackEvent msg, EntitySessionEventArgs args) AttemptAttack(args.SenderSession.AttachedEntity.Value, weaponUid, weapon, msg, args.SenderSession); } - private void OnGetState(EntityUid uid, MeleeWeaponComponent component, ref ComponentGetState args) - { - args.State = new MeleeWeaponComponentState(component.AttackRate, component.Attacking, component.NextAttack, component.ClickAnimation, component.WideAnimation, component.Range); - } - - private void OnHandleState(EntityUid uid, MeleeWeaponComponent component, ref ComponentHandleState args) - { - if (args.Current is not MeleeWeaponComponentState state) - return; - - component.Attacking = state.Attacking; - component.AttackRate = state.AttackRate; - component.NextAttack = state.NextAttack; - - component.ClickAnimation = state.ClickAnimation; - component.WideAnimation = state.WideAnimation; - component.Range = state.Range; - } - /// /// Gets the total damage a weapon does, including modifiers like wielding and enablind/disabling /// @@ -427,13 +405,13 @@ private bool AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponCompo { case LightAttackEvent light: DoLightAttack(user, light, weaponUid, weapon, session); - animation = weapon.ClickAnimation; + animation = weapon.Animation; break; case DisarmAttackEvent disarm: if (!DoDisarm(user, disarm, weaponUid, weapon, session)) return false; - animation = weapon.ClickAnimation; + animation = weapon.Animation; break; case HeavyAttackEvent heavy: if (!DoHeavyAttack(user, heavy, weaponUid, weapon, session)) diff --git a/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs b/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs index 8d0f6a52838..eb04d3227db 100644 --- a/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs @@ -3,37 +3,36 @@ using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Weapons.Ranged.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class BallisticAmmoProviderComponent : Component { - [ViewVariables(VVAccess.ReadWrite), DataField("soundRack")] + [ViewVariables(VVAccess.ReadWrite), DataField] public SoundSpecifier? SoundRack = new SoundPathSpecifier("/Audio/Weapons/Guns/Cock/smg_cock.ogg"); - [ViewVariables(VVAccess.ReadWrite), DataField("soundInsert")] + [ViewVariables(VVAccess.ReadWrite), DataField] public SoundSpecifier? SoundInsert = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/bullet_insert.ogg"); - [ViewVariables(VVAccess.ReadWrite), DataField("proto", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? FillProto; + [ViewVariables(VVAccess.ReadWrite), DataField] + public EntProtoId? Proto; - [ViewVariables(VVAccess.ReadWrite), DataField("capacity")] + [ViewVariables(VVAccess.ReadWrite), DataField] public int Capacity = 30; public int Count => UnspawnedCount + Container.ContainedEntities.Count; - [ViewVariables(VVAccess.ReadWrite), DataField("unspawnedCount")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public int UnspawnedCount; - [ViewVariables(VVAccess.ReadWrite), DataField("whitelist")] + [ViewVariables(VVAccess.ReadWrite), DataField] public EntityWhitelist? Whitelist; public Container Container = default!; // TODO: Make this use stacks when the typeserializer is done. - [DataField("entities")] + [DataField, AutoNetworkedField] public List Entities = new(); /// @@ -42,18 +41,18 @@ public sealed partial class BallisticAmmoProviderComponent : Component /// /// Set to false for entities like turrets to avoid users being able to cycle them. /// - [ViewVariables(VVAccess.ReadWrite), DataField("cycleable")] + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] public bool Cycleable = true; /// /// Is it okay for this entity to directly transfer its valid ammunition into another provider? /// - [ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")] - public bool MayTransfer = false; + [ViewVariables(VVAccess.ReadWrite), DataField] + public bool MayTransfer; /// /// DoAfter delay for filling a bullet into another ballistic ammo provider. /// - [DataField("fillDelay")] + [DataField] public TimeSpan FillDelay = TimeSpan.FromSeconds(0.5); } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs index f8b2394315c..8ad96fda531 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs @@ -6,7 +6,6 @@ using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; using Robust.Shared.Containers; -using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Serialization; @@ -29,29 +28,6 @@ protected virtual void InitializeBallistic() SubscribeLocalEvent(OnBallisticAfterInteract); SubscribeLocalEvent(OnBallisticAmmoFillDoAfter); SubscribeLocalEvent(OnBallisticUse); - - SubscribeLocalEvent(OnBallisticGetState); - SubscribeLocalEvent(OnBallisticHandleState); - } - - private void OnBallisticGetState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentGetState args) - { - args.State = new BallisticAmmoProviderComponentState() - { - UnspawnedCount = component.UnspawnedCount, - Cycleable = component.Cycleable, - Entities = GetNetEntityList(component.Entities), - }; - } - - private void OnBallisticHandleState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentHandleState args) - { - if (args.Current is not BallisticAmmoProviderComponentState state) - return; - - component.UnspawnedCount = state.UnspawnedCount; - component.Cycleable = state.Cycleable; - component.Entities = EnsureEntityList(state.Entities, uid); } private void OnBallisticUse(EntityUid uid, BallisticAmmoProviderComponent component, UseInHandEvent args) @@ -239,7 +215,7 @@ private void OnBallisticMapInit(EntityUid uid, BallisticAmmoProviderComponent co { // TODO this should be part of the prototype, not set on map init. // Alternatively, just track spawned count, instead of unspawned count. - if (component.FillProto != null) + if (component.Proto != null) { component.UnspawnedCount = Math.Max(0, component.Capacity - component.Container.ContainedEntities.Count); UpdateBallisticAppearance(uid, component); @@ -269,7 +245,7 @@ private void OnBallisticTakeAmmo(EntityUid uid, BallisticAmmoProviderComponent c else if (component.UnspawnedCount > 0) { component.UnspawnedCount--; - entity = Spawn(component.FillProto, args.Coordinates); + entity = Spawn(component.Proto, args.Coordinates); args.Ammo.Add((entity, EnsureShootable(entity))); } } @@ -292,14 +268,6 @@ private void UpdateBallisticAppearance(EntityUid uid, BallisticAmmoProviderCompo Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance); Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance); } - - [Serializable, NetSerializable] - private sealed class BallisticAmmoProviderComponentState : ComponentState - { - public int UnspawnedCount; - public List Entities = new(); - public bool Cycleable = true; - } } /// diff --git a/Content.Shared/Zombies/ZombieComponent.cs b/Content.Shared/Zombies/ZombieComponent.cs index f03a0baf79f..bb1f6bec5f1 100644 --- a/Content.Shared/Zombies/ZombieComponent.cs +++ b/Content.Shared/Zombies/ZombieComponent.cs @@ -1,15 +1,14 @@ using Content.Shared.Chat.Prototypes; using Content.Shared.Chemistry.Reagent; using Content.Shared.Damage; -using Content.Shared.Roles; using Content.Shared.Humanoid; +using Content.Shared.Roles; using Content.Shared.StatusIcon; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using static Content.Shared.Humanoid.HumanoidAppearanceState; namespace Content.Shared.Zombies; diff --git a/Content.Tests/Shared/Alert/ServerAlertsComponentTests.cs b/Content.Tests/Shared/Alert/ServerAlertsComponentTests.cs index 83fbb009ead..5d8d49d168c 100644 --- a/Content.Tests/Shared/Alert/ServerAlertsComponentTests.cs +++ b/Content.Tests/Shared/Alert/ServerAlertsComponentTests.cs @@ -57,7 +57,7 @@ public void ShowAlerts() var getty = new ComponentGetState(); entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - var alertState = (AlertsComponentState) getty.State!; + var alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; Assert.NotNull(alertState); Assert.That(alertState.Alerts.Count, Is.EqualTo(1)); Assert.That(alertState.Alerts.ContainsKey(lowpressure.AlertKey)); @@ -66,14 +66,14 @@ public void ShowAlerts() // Lazy entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - alertState = (AlertsComponentState) getty.State!; + alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; Assert.That(alertState.Alerts.Count, Is.EqualTo(1)); Assert.That(alertState.Alerts.ContainsKey(highpressure.AlertKey)); EntitySystem.Get().ClearAlertCategory(alertsComponent.Owner, AlertCategory.Pressure); entManager.EventBus.RaiseComponentEvent(alertsComponent, getty); - alertState = (AlertsComponentState) getty.State!; + alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!; Assert.That(alertState.Alerts.Count, Is.EqualTo(0)); } } diff --git a/Resources/Audio/Ambience/Objects/attributions.yml b/Resources/Audio/Ambience/Objects/attributions.yml index e5cd81a3725..58b4e5cd5bf 100644 --- a/Resources/Audio/Ambience/Objects/attributions.yml +++ b/Resources/Audio/Ambience/Objects/attributions.yml @@ -1,3 +1,8 @@ +- files: ["revMachine_ambience.wav"] + license: "CC0-1.0" + copyright: "Welding_3_continious.wav by ivolipa. Shrill_Scraping.wav by mickyman5000. Wheelchair Hydraulic 1.wav by maxlaclaria" + source: "https://freesound.org/people/ivolipa/sounds/385995/" #https://freesound.org/people/maxlacaria/sounds/557323/ https://freesound.org/people/mickyman5000/sounds/340719/" + - files: ["anomaly_generator.ogg"] license: "CC0-1.0" copyright: "Created by steaq, converted Mono and .ogg by EmoGarbage" diff --git a/Resources/Audio/Ambience/Objects/revMachine_ambience.ogg b/Resources/Audio/Ambience/Objects/revMachine_ambience.ogg new file mode 100644 index 00000000000..b1f5c4f6ec2 Binary files /dev/null and b/Resources/Audio/Ambience/Objects/revMachine_ambience.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/attributions.yml b/Resources/Audio/DeltaV/Voice/Vulpakin/attributions.yml new file mode 100644 index 00000000000..e45ab8b34bf --- /dev/null +++ b/Resources/Audio/DeltaV/Voice/Vulpakin/attributions.yml @@ -0,0 +1,29 @@ +- files: ["dog_bark1.ogg", "dog_bark2.ogg", "dog_bark3.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/abhisheky948/sounds/625497/" + source: "https://freesound.org/people/abhisheky948/sounds/625497/" + + files: ["dog_bark2.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/michael_grinnell/sounds/464400/" + source: "https://freesound.org/people/michael_grinnell/sounds/464400/" + + files: ["dog_bark3.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/Geoff-Bremner-Audio/sounds/688201/" + source: "https://freesound.org/people/Geoff-Bremner-Audio/sounds/688201/" + +- files: ["dog_growl1.ogg", "dog_growl2.ogg", "dog_growl3.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/Glitchedtones/sounds/372533/ - cut out three clips of dog growling, cleaned up, converted to ogg" + source: "https://freesound.org/people/Glitchedtones/sounds/372533/" + +- files: ["dog_snarl1.ogg", "dog_snarl2.ogg", "dog_snarl3.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/strongbot/sounds/341090/ - cut out three clips of dog snarling, cleaned up, converted to ogg" + source: "https://freesound.org/people/strongbot/sounds/341090/" + + files: ["dog_whine.ogg"] + license: "CC0-1.0" + copyright: "Original sound by https://freesound.org/people/Sruddi1/sounds/34878/ - cleaned up, converted to ogg" + source: "https://freesound.org/people/Sruddi1/sounds/34878/" diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg new file mode 100644 index 00000000000..55a947fbd8c Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg new file mode 100644 index 00000000000..6cc61c77d94 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg new file mode 100644 index 00000000000..3eee456323c Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg new file mode 100644 index 00000000000..82b54cbc546 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg new file mode 100644 index 00000000000..fa48c9f3d8a Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg new file mode 100644 index 00000000000..1eb5ed9eded Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg new file mode 100644 index 00000000000..171dcb01798 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg new file mode 100644 index 00000000000..9b1fe916df6 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg new file mode 100644 index 00000000000..9f9a19817c1 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg new file mode 100644 index 00000000000..37309ede597 Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg differ diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/license.txt b/Resources/Audio/DeltaV/Voice/Vulpakin/license.txt new file mode 100644 index 00000000000..7604e4dfc25 --- /dev/null +++ b/Resources/Audio/DeltaV/Voice/Vulpakin/license.txt @@ -0,0 +1,10 @@ +dog_bark1.ogg licensed under CC0 1.0 taken from abhisheky948 at https://freesound.org/people/abhisheky948/sounds/625497/ +dog_bark2.ogg licensed under CC0 1.0 taken from michael_grinnell at https://freesound.org/people/michael_grinnell/sounds/464400/ +dog_bark3.ogg licensed under CC0 1.0 taken from Geoff-Bremner-Audio at https://freesound.org/people/Geoff-Bremner-Audio/sounds/688201/ +dog_growl1.ogg licensed under CC0 1.0 taken from GlitchedTones at https://freesound.org/people/Glitchedtones/sounds/372533/ +dog_growl2.ogg licensed under CC0 1.0 taken from GlitchedTones at https://freesound.org/people/Glitchedtones/sounds/372533/ +dog_growl3.ogg licensed under CC0 1.0 taken from GlitchedTones at https://freesound.org/people/Glitchedtones/sounds/372533/ +dog_snarl1.ogg licensed under CC0 1.0 taken from strongbot at https://freesound.org/people/strongbot/sounds/341090/ +dog_snarl2.ogg licensed under CC0 1.0 taken from strongbot at https://freesound.org/people/strongbot/sounds/341090/ +dog_snarl3.ogg licensed under CC0 1.0 taken from strongbot at https://freesound.org/people/strongbot/sounds/341090/ +dog_whine.ogg licensed under CC SAMPLING+ 1.0 DEED taken from Sruddil at https://freesound.org/people/Sruddi1/sounds/34878/ \ No newline at end of file diff --git a/Resources/Audio/Items/Janitor/floor_sign_beep.ogg b/Resources/Audio/Items/Janitor/floor_sign_beep.ogg new file mode 100644 index 00000000000..25f68be1c38 Binary files /dev/null and b/Resources/Audio/Items/Janitor/floor_sign_beep.ogg differ diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e9c08f3ad62..4f4d33685ed 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,206 +1,4 @@ Entries: -- author: keronshb - changes: - - {message: Captains will now start with their gloves and carapace again, type: Tweak} - id: 4405 - time: '2023-08-01T21:10:36.0000000+00:00' -- author: EmoGarbage404 - changes: - - {message: 'Fixed messages related to the round not being sent (round starting, - round restarting, etc.)', type: Fix} - id: 4406 - time: '2023-08-01T21:11:50.0000000+00:00' -- author: PrPleGoo - changes: - - {message: added an overlay for the security hud that displays job icons, type: Add} - - {message: Added some buttons to the Agent ID interface to set the icon on the - ID card., type: Add} - - {message: Changed the id card computer to also set the icon on the ID when picking - a job prototype from the presets., type: Tweak} - id: 4407 - time: '2023-08-01T21:17:03.0000000+00:00' -- author: metalgearsloth - changes: - - {message: Added xeno spitters to salvage., type: Add} - - {message: Fix dragon carps not looking like their dragon., type: Fix} - - {message: Fix dragon carp NPCs not following the dragon and not idling on spawn., - type: Fix} - - {message: Fix NPCs not shutting down properly upon player takeover., type: Fix} - id: 4408 - time: '2023-08-02T00:48:57.0000000+00:00' -- author: Slava0135 - changes: - - {message: Hitting entities with thrown items that deal damage now provide more - feedback (sound and visual effect)., type: Add} - - {message: Thrown items that damage other entities now land after first hit., type: Tweak} - id: 4409 - time: '2023-08-02T09:30:04.0000000+00:00' -- author: Slava0135 - changes: - - {message: added visual effect on collision for damage on high speed entities, - type: Add} - id: 4410 - time: '2023-08-02T09:32:44.0000000+00:00' -- author: deltanedas - changes: - - {message: 'Added the gateway, currently for admins to teleport you to funny places.', - type: Add} - id: 4411 - time: '2023-08-02T09:47:18.0000000+00:00' -- author: Nimfar11 - changes: - - {message: Adds a magazine for the C20R to the uplink for 3 TC., type: Add} - id: 4412 - time: '2023-08-02T10:03:39.0000000+00:00' -- author: Nimfar - changes: - - {message: 'Adds a new theft target for the Syndicate, Emergency Security Orders - from the HoS.', type: Add} - id: 4413 - time: '2023-08-02T10:05:12.0000000+00:00' -- author: Bhijn and Myr - changes: - - {message: 'Interaction outlines now directly react to lighting. You can no longer - merely wave your mouse around in the dark to see objects in the distance in - maint. Interaction outlines that''re in-range are far brighter even in dim conditions, - though out-of-range interaction outlines are hard to see in poor light conditions.', - type: Add} - id: 4414 - time: '2023-08-02T10:07:12.0000000+00:00' -- author: eclips_e - changes: - - {message: The P-Block crate will now have oxygen and nitrogen jugs., type: Fix} - id: 4415 - time: '2023-08-02T14:32:08.0000000+00:00' -- author: chromiumboy - changes: - - {message: Containers used in recipes now drop their contents when crafted., type: Fix} - id: 4416 - time: '2023-08-02T18:32:51.0000000+00:00' -- author: PuceTint - changes: - - {message: Nitrous oxide now causes laughing, type: Add} - id: 4417 - time: '2023-08-02T21:33:00.0000000+00:00' -- author: metalgearsloth - changes: - - {message: Fix xenos not spittin'., type: Fix} - id: 4418 - time: '2023-08-02T21:34:54.0000000+00:00' -- author: Bhijn and Myr - changes: - - {message: The game now boots in GLES2 again. oops., type: Fix} - id: 4419 - time: '2023-08-02T23:13:07.0000000+00:00' -- author: router - changes: - - {message: Ringtones now have 2 more notes you can play around with., type: Tweak} - - {message: 'The Syndicate has taken advantage of this hardware expansion, making - brute-force attacks on their uplinks unfeasible.', type: Fix} - id: 4420 - time: '2023-08-03T11:13:17.0000000+00:00' -- author: fedKotikeD & crazybrain - changes: - - {message: Added Syndicate pAI., type: Add} - - {message: Syndicate pAI's can be found on the Nukie planet., type: Tweak} - id: 4421 - time: '2023-08-03T20:48:40.0000000+00:00' -- author: EmoGarbage404 - changes: - - {message: NT has issued a unique anti-balloon weapon to security personnel. Use - it to destroy syndicate balloons and crush their morale!, type: Add} - id: 4422 - time: '2023-08-04T01:53:06.0000000+00:00' -- author: Interrobang01 - changes: - - {message: 'A few changes to some chemical recipes, namely Dexalin, Lexorin, Ultravasculine, - Ammonia, Acetone, Sodium Carbonate, and Sigynate, have been reverted. They are - now like what they used to be.', type: Tweak} - - {message: Sigynate heals 3 Caustic per unit again., type: Tweak} - id: 4423 - time: '2023-08-04T02:30:37.0000000+00:00' -- author: liltenhead - changes: - - {message: Fixed the incorrect ammo count in the China Lake bundle's description., - type: Fix} - id: 4424 - time: '2023-08-04T02:57:02.0000000+00:00' -- author: Lank - changes: - - {message: 'Added Moth People as a playable race. These friends can move around - in zero gravity easily and love the cold, but are significantly weaker against - high temperatures and won''t be caught eating anything not made of cloth.', - type: Add} - id: 4425 - time: '2023-08-04T05:21:28.0000000+00:00' -- author: FillerVK - changes: - - {message: Added insulated gloves to emaged youtool, type: Add} - id: 4426 - time: '2023-08-04T08:39:34.0000000+00:00' -- author: Flareguy - changes: - - {message: Updated dirty steel & plastic floor tiles to match the new style., type: Tweak} - id: 4427 - time: '2023-08-04T08:55:08.0000000+00:00' -- author: metalgearsloth - changes: - - {message: Spears can now embed into things and require removing., type: Add} - id: 4428 - time: '2023-08-04T08:56:39.0000000+00:00' -- author: Flareguy - changes: - - {message: The smartfridge now uses its old sprites., type: Tweak} - id: 4429 - time: '2023-08-04T18:29:43.0000000+00:00' -- author: MilenVolf - changes: - - {message: Moths now have proper creampied texture! Honk!, type: Tweak} - id: 4430 - time: '2023-08-04T18:31:39.0000000+00:00' -- author: metalgearsloth - changes: - - {message: Fix spear wielding., type: Fix} - id: 4431 - time: '2023-08-04T18:37:17.0000000+00:00' -- author: Aleksh - changes: - - {message: Added laser raptors., type: Add} - id: 4432 - time: '2023-08-04T18:38:11.0000000+00:00' -- author: Unbelievable-Salmon - changes: - - {message: The Syndicate gas mask now protects your eyes from welders., type: Tweak} - id: 4433 - time: '2023-08-04T18:43:25.0000000+00:00' -- author: metalgearsloth - changes: - - {message: Allow pulling while buckled, type: Add} - id: 4434 - time: '2023-08-04T18:47:52.0000000+00:00' -- author: astriloqua - changes: - - {message: People wont hear buckling and unbuckling sounds twice anymore., type: Fix} - id: 4435 - time: '2023-08-04T22:24:21.0000000+00:00' -- author: Errant - changes: - - {message: Gas tanks and jetpacks have reduced capacity and now need to be refilled - more regularly., type: Tweak} - - {message: Jetpacks now start fully filled., type: Tweak} - id: 4436 - time: '2023-08-04T22:40:42.0000000+00:00' -- author: Potato1234_x - changes: - - {message: Added the Dr. Gibb Vendor, type: Add} - id: 4437 - time: '2023-08-05T02:07:41.0000000+00:00' -- author: liltenhead - changes: - - {message: Changed the swat crate to only contain non-lethal shells; now it comes - with shields., type: Tweak} - id: 4438 - time: '2023-08-05T03:47:32.0000000+00:00' - author: crazybrain changes: - {message: Uplinks can now purchase a Syndicate pAI., type: Add} @@ -2976,3 +2774,189 @@ Entries: - {message: What moths consider as food is now more consistent., type: Tweak} id: 4904 time: '2023-09-27T16:50:59.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Fixed getting moved briefly when closing a crematorium that you are + standing over., type: Fix} + id: 4905 + time: '2023-09-27T23:41:07.0000000+00:00' +- author: Psychpsyo + changes: + - {message: 'You can now pet Runtime instead of petting >the< Runtime. Also, Smile + is now a girl.', type: Fix} + id: 4906 + time: '2023-09-28T04:05:50.0000000+00:00' +- author: Psychpsyo + changes: + - {message: Bingus is no longer fuzzy., type: Fix} + id: 4907 + time: '2023-09-28T04:06:13.0000000+00:00' +- author: Psychpsyo + changes: + - {message: The wet floor sign can now be worn as an outer clothing. This now gives + syndicate janitors access to a suicide vest in form the wet floor sign mine., + type: Add} + id: 4908 + time: '2023-09-28T04:09:45.0000000+00:00' +- author: LEVELcat + changes: + - {message: Eyeglass are now available from the ClothesMate., type: Add} + id: 4909 + time: '2023-09-28T10:52:05.0000000+00:00' +- author: Repo + changes: + - {message: Pun Pun now showing on crew monitoring., type: Fix} + id: 4910 + time: '2023-09-28T10:53:54.0000000+00:00' +- author: nikthechampiongr + changes: + - {message: Mappers can now place airlocks that can be pried open while unpowered + without tools., type: Add} + id: 4911 + time: '2023-09-28T11:34:22.0000000+00:00' +- author: Doru991 + changes: + - {message: Arcade machine maintenance panels can be opened again., type: Fix} + id: 4912 + time: '2023-09-28T14:00:19.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: The health alerts now have text to help discern how gravely injured + you are., type: Tweak} + id: 4913 + time: '2023-09-28T14:05:42.0000000+00:00' +- author: NULL882 + changes: + - {message: Added Necropolis Wall., type: Add} + - {message: Added Mine Wall., type: Add} + - {message: Added Sings for Mine Wall., type: Add} + id: 4914 + time: '2023-09-28T17:07:13.0000000+00:00' +- author: lunarcomets + changes: + - {message: 'Tweaked archaic issues to fix capitalization issues, and removed the + replacement for ''request'' for consistency.', type: Tweak} + id: 4915 + time: '2023-09-28T19:19:58.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Changed the player actions panel to ask for confirmation when kicking + and respawning players., type: Tweak} + id: 4916 + time: '2023-09-28T22:46:07.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Fixed not being able to choose a role that you were unbanned from in + the same round without reconnecting., type: Fix} + id: 4917 + time: '2023-09-28T23:46:39.0000000+00:00' +- author: Micr0byte + changes: + - {message: Pressing F11 now toggles between full-screen and windowed modes., type: Add} + id: 4918 + time: '2023-09-28T23:55:10.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Fixed everyone being bald., type: Fix} + id: 4919 + time: '2023-09-29T00:44:47.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Fixed the HoP's id card computer not opening., type: Fix} + id: 4920 + time: '2023-09-29T00:59:14.0000000+00:00' +- author: mirrorcult + changes: + - {message: 'Being damaged, being stunned, or going into crit will now force you + to send whatever message you were typing, if it was in local/whisper/radio. + You''ll sometimes find yours-AUGH', type: Add} + id: 4921 + time: '2023-09-29T01:05:37.0000000+00:00' +- author: DrSmugleaf + changes: + - {message: Fixed AHelp progressively gaining more panels., type: Fix} + id: 4922 + time: '2023-09-29T01:46:16.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Fixed skeletons spawning in folded containers., type: Fix} + id: 4923 + time: '2023-09-29T03:55:29.0000000+00:00' +- author: casperr04 + changes: + - {message: Fixed the true name of disguised players being shown when electrocuted., + type: Fix} + id: 4924 + time: '2023-09-29T15:01:19.0000000+00:00' +- author: TsjipTsjip + changes: + - {message: Kettle's medical ward was reworked., type: Tweak} + id: 4925 + time: '2023-09-29T19:14:53.0000000+00:00' +- author: daerSeebaer + changes: + - {message: Volumetric pumps now indicate if they can't pump., type: Add} + id: 4926 + time: '2023-09-30T03:35:23.0000000+00:00' +- author: deltanedas + changes: + - {message: Fixed cognizine not creating ghost roles., type: Fix} + id: 4927 + time: '2023-09-30T17:53:22.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Holofans can now be destroyed by explosions., type: Fix} + id: 4928 + time: '2023-09-30T19:08:09.0000000+00:00' +- author: deltanedas + changes: + - {message: 'Space dragons get a proper greentext in the round end summary, along + with objectives in the character menu.', type: Tweak} + id: 4929 + time: '2023-09-30T20:18:02.0000000+00:00' +- author: Ubaser + changes: + - {message: Winter Boots are now available in the Winterdrobe., type: Add} + id: 4930 + time: '2023-10-01T14:28:14.0000000+00:00' +- author: Ubaser + changes: + - {message: 'QM now has a mantle, available at HoP''s uniform printer.', type: Add} + id: 4931 + time: '2023-10-01T14:28:47.0000000+00:00' +- author: Nimfar11 + changes: + - {message: Added new sprites for slime organs, type: Add} + - {message: Slimes now breathe nitrogen too., type: Tweak} + id: 4932 + time: '2023-10-01T14:34:29.0000000+00:00' +- author: casperr04 + changes: + - {message: Space ninjas now have random appearance., type: Tweak} + id: 4933 + time: '2023-10-01T14:51:35.0000000+00:00' +- author: TomCruize + changes: + - {message: Made Space Cats lungs ROBUST (They now don't suffocate in space), type: Fix} + id: 4934 + time: '2023-10-01T14:55:59.0000000+00:00' +- author: TheShuEd + changes: + - {message: Added wide-spectrum anomaly locator., type: Add} + id: 4935 + time: '2023-10-01T16:41:32.0000000+00:00' +- author: michaelcu + changes: + - {message: Telescopic Shield no longer glows in the dark when deployed., type: Fix} + id: 4936 + time: '2023-10-01T17:16:54.0000000+00:00' +- author: EmoGarbage404 + changes: + - {message: Nuclear Operative medics now come with a custom hardsuit., type: Add} + id: 4937 + time: '2023-10-01T17:36:20.0000000+00:00' +- author: DrTeaSpoon + changes: + - {message: Plant species mutation no longer resets other mutations., type: Fix} + id: 4938 + time: '2023-10-01T17:52:45.0000000+00:00' diff --git a/Resources/Changelog/DeltaVChangelog.yml b/Resources/Changelog/DeltaVChangelog.yml index 7bef6c2ea8f..a21dd9235a5 100644 --- a/Resources/Changelog/DeltaVChangelog.yml +++ b/Resources/Changelog/DeltaVChangelog.yml @@ -199,3 +199,75 @@ Entries: message: Added the vector safe. id: 32 time: '2023-10-01T20:10:24.0000000+00:00' +- author: VMSolidus + changes: + - type: Tweak + message: >- + Rebalanced Vulpakin, they are no longer HUMAN+, and are now currently a + sidegrade to humans. + id: 33 + time: '2023-10-03T16:49:35.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Remove + message: Removed the vape. + id: 34 + time: '2023-10-03T16:51:54.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: Added the Psionic Mantis. + id: 35 + time: '2023-10-03T17:47:54.0000000+00:00' +- author: Colin-Tel + changes: + - type: Add + message: >- + Added PDA boxes to department heads' lockers. Bug your manager for a + promotion now! + id: 36 + time: '2023-10-03T18:06:07.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: Added the Psionic Countermeasures research. + id: 37 + time: '2023-10-03T19:36:47.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: Added more guns. If that don't work, we'll add more guns. + id: 38 + time: '2023-10-03T20:01:48.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: Added tips about glimmer, rat kings and wisps. + id: 39 + time: '2023-10-03T20:23:18.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: Added an old epistemics book. + id: 40 + time: '2023-10-03T21:41:37.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Add + message: >- + Added the ability for Oni Syndicate agents to buy the Kanabou and + Tousei-Gusoku set. + id: 41 + time: '2023-10-03T21:45:06.0000000+00:00' +- author: DebugOk + changes: + - type: Add + message: Nanotrasen R&D has cooked up some new hardlight technology + id: 42 + time: '2023-10-03T22:23:09.0000000+00:00' +- author: FluffiestFloof + changes: + - type: Tweak + message: Martial artist finally gets a new coat of paint for their PDA. + id: 43 + time: '2023-10-04T00:20:48.0000000+00:00' diff --git a/Resources/Locale/en-US/accent/archaic.ftl b/Resources/Locale/en-US/accent/archaic.ftl index a9ff88746f8..11c6a7857e3 100644 --- a/Resources/Locale/en-US/accent/archaic.ftl +++ b/Resources/Locale/en-US/accent/archaic.ftl @@ -135,7 +135,7 @@ accent-archaic-replaced-43 = onto accent-archaic-replacement-43 = unto accent-archaic-replaced-44 = can i -accent-archaic-replacement-44 = am i allowed to +accent-archaic-replacement-44 = am I allowed to accent-archaic-replaced-45 = upon accent-archaic-replacement-45 = unto @@ -185,9 +185,6 @@ accent-archaic-replacement-59 = bemadding accent-archaic-replaced-60 = suggest accent-archaic-replacement-60 = bespeak -accent-archaic-replaced-53 = request -accent-archaic-replacement-53 = bespeak - accent-archaic-replaced-61 = indicate accent-archaic-replacement-61 = bespeak @@ -510,7 +507,7 @@ accent-archaic-replaced-175 = will accent-archaic-replacement-175 = shall accent-archaic-replaced-176 = i am thirsty -accent-archaic-replacement-176 = i require a drink +accent-archaic-replacement-176 = I require a drink accent-archaic-replaced-177 = hate accent-archaic-replacement-177 = loathe @@ -591,7 +588,7 @@ accent-archaic-replaced-204 = airlock accent-archaic-replacement-204 = door accent-archaic-replaced-205 = sorry -accent-archaic-replacement-205 = i apologise +accent-archaic-replacement-205 = I apologise accent-archaic-replaced-206 = hey accent-archaic-replacement-206 = pardon me @@ -615,7 +612,7 @@ accent-archaic-replaced-212 = why accent-archaic-replacement-212 = for what reason accent-archaic-replaced-213 = im -accent-archaic-replacement-213 = i am +accent-archaic-replacement-213 = I am accent-archaic-replaced-214 = sink accent-archaic-replacement-214 = taps @@ -645,13 +642,13 @@ accent-archaic-replaced-222 = myself accent-archaic-replacement-222 = mineself accent-archaic-replaced-223 = i am hungry -accent-archaic-replacement-223 = i require grub +accent-archaic-replacement-223 = I require grub accent-archaic-replaced-224 = you suck accent-archaic-replacement-224 = thou are foul accent-archaic-replaced-225 = please -accent-archaic-replacement-225 = i request of thee +accent-archaic-replacement-225 = I request of thee accent-archaic-replaced-226 = secway accent-archaic-replacement-226 = patrol cart diff --git a/Resources/Locale/en-US/actions/actions/dragon.ftl b/Resources/Locale/en-US/actions/actions/dragon.ftl index a9b887142d6..b2b9b6d3af9 100644 --- a/Resources/Locale/en-US/actions/actions/dragon.ftl +++ b/Resources/Locale/en-US/actions/actions/dragon.ftl @@ -3,19 +3,3 @@ devour-action-popup-message-fail-target-not-valid = That doesn't look particular devour-action-popup-message-fail-target-alive = You can't consume creatures that are alive! dragon-spawn-action-popup-message-fail-no-eggs = You don't have the stamina to do that! - -# Rifts -carp-rift-warning = A rift is causing an unnaturally large energy flux at {$location}. Stop it at all costs! -carp-rift-duplicate = Cannot have 2 charging rifts at the same time! -carp-rift-examine = It is [color=yellow]{$percentage}%[/color] charged! -carp-rift-max = You have reached your maximum amount of rifts -carp-rift-anchor = Rifts require a stable surface to spawn. -carp-rift-proximity = Too close to a nearby rift! Need to be at least {$proximity}m away. -carp-rift-space-proximity = Too close to space! Need to be at least {$proximity}m away. -carp-rift-weakened = You are unable to summon more rifts in your weakened state. -carp-rift-destroyed = A rift has been destroyed! You are now weakened temporarily. - -# Round end -dragon-round-end-summary = The dragons were: -dragon-round-end-dragon = {$name} with {$count} rifts -dragon-round-end-dragon-player = {$name} ({$player}) with {$count} rifts diff --git a/Resources/Locale/en-US/damage/damage-force-say.ftl b/Resources/Locale/en-US/damage/damage-force-say.ftl new file mode 100644 index 00000000000..a4360351145 --- /dev/null +++ b/Resources/Locale/en-US/damage/damage-force-say.ftl @@ -0,0 +1,12 @@ +damage-force-say-message-wrap = {$message}-{$suffix} +damage-force-say-message-wrap-no-suffix = {$message}- + +damage-force-say-1 = GACK! +damage-force-say-2 = GLORF! +damage-force-say-3 = OOF! +damage-force-say-4 = AUGH! +damage-force-say-5 = OW! +damage-force-say-6 = URGH! +damage-force-say-7 = HRNK! + +damage-force-say-sleep = zzz... diff --git a/Resources/Locale/en-US/deltav/hologram/hologram.ftl b/Resources/Locale/en-US/deltav/hologram/hologram.ftl new file mode 100644 index 00000000000..f67bfeb4a70 --- /dev/null +++ b/Resources/Locale/en-US/deltav/hologram/hologram.ftl @@ -0,0 +1,3 @@ +hologram-on-examine = [color=lightblue]It is but a transient specter...[/color] +hologram-disarm-blocked = Your hand phases through {THE($target)}. +hologram-disarm-blocked-other = {THE($performerName)}'s hand phases through {THE($target)}. diff --git a/Resources/Locale/en-US/deltav/research/technologies.ftl b/Resources/Locale/en-US/deltav/research/technologies.ftl new file mode 100644 index 00000000000..ab4286cafe5 --- /dev/null +++ b/Resources/Locale/en-US/deltav/research/technologies.ftl @@ -0,0 +1 @@ +research-technology-exotic-ammunition = Exotic Ammunition diff --git a/Resources/Locale/en-US/dragon/dragon.ftl b/Resources/Locale/en-US/dragon/dragon.ftl new file mode 100644 index 00000000000..11e8a586203 --- /dev/null +++ b/Resources/Locale/en-US/dragon/dragon.ftl @@ -0,0 +1,5 @@ +dragon-round-end-agent-name = dragon + +objective-issuer-dragon = [color=#7567b6]Space Dragon[/color] + +dragon-role-briefing = Summon 3 carp rifts and take over this quadrant! diff --git a/Resources/Locale/en-US/dragon/rifts.ftl b/Resources/Locale/en-US/dragon/rifts.ftl new file mode 100644 index 00000000000..5ad061abf96 --- /dev/null +++ b/Resources/Locale/en-US/dragon/rifts.ftl @@ -0,0 +1,9 @@ +carp-rift-warning = A rift is causing an unnaturally large energy flux at {$location}. Stop it at all costs! +carp-rift-duplicate = Cannot have 2 charging rifts at the same time! +carp-rift-examine = It is [color=yellow]{$percentage}%[/color] charged! +carp-rift-max = You have reached your maximum amount of rifts +carp-rift-anchor = Rifts require a stable surface to spawn. +carp-rift-proximity = Too close to a nearby rift! Need to be at least {$proximity}m away. +carp-rift-space-proximity = Too close to space! Need to be at least {$proximity}m away. +carp-rift-weakened = You are unable to summon more rifts in your weakened state. +carp-rift-destroyed = A rift has been destroyed! You are now weakened temporarily. diff --git a/Resources/Locale/en-US/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/flavors/flavor-profiles.ftl index 145e2aa51f0..8ecf4cb13e7 100644 --- a/Resources/Locale/en-US/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/flavors/flavor-profiles.ftl @@ -148,6 +148,7 @@ flavor-complex-parents = like someone's parents flavor-complex-plastic = like plastic flavor-complex-glue = like glue flavor-complex-spaceshroom-cooked = like space umami +flavor-complex-lost-friendship = like lost friendship # Drink-specific flavors. diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index 67d727dc532..02cbd973647 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -5,6 +5,7 @@ petting-success-generic = You pet {THE($target)} on {POSS-ADJ($target)} head. petting-success-soft-floofy = You pet {THE($target)} on {POSS-ADJ($target)} soft floofy head. +petting-success-bingus = You pet {THE($target)} on {POSS-ADJ($target)} wrinkly little head. petting-success-bird = You pet {THE($target)} on {POSS-ADJ($target)} cute feathery head. petting-success-cat = You pet {THE($target)} on {POSS-ADJ($target)} fuzzy little head. petting-success-corrupted-corgi = In an act of hubris, you pet {THE($target)} on {POSS-ADJ($target)} cursed little head. diff --git a/Resources/Locale/en-US/nyanotrasen/job/job-description.ftl b/Resources/Locale/en-US/nyanotrasen/job/job-description.ftl index 69c16e2aaa0..22d25b65c7a 100644 --- a/Resources/Locale/en-US/nyanotrasen/job/job-description.ftl +++ b/Resources/Locale/en-US/nyanotrasen/job/job-description.ftl @@ -3,3 +3,4 @@ job-description-guard = Keep track of prisoners and make sure they have their ba job-description-mail-carrier = Deliver mail and other packages from and to logistics. Avoid dogs. job-description-martialartist = Be honorable and disciplined, spar in the dojo, challenge security to CQC. job-description-prisoner = Sit in prison. Gamble with your cellmates. Talk to the warden. Write your memoirs. +job-description-mantis = Solve mysteries from the nature of the universe to the meaning of life. Be the main person to deal with Psionic beings. diff --git a/Resources/Locale/en-US/nyanotrasen/job/job-names.ftl b/Resources/Locale/en-US/nyanotrasen/job/job-names.ftl index f8d780f9179..bc99a777f1a 100644 --- a/Resources/Locale/en-US/nyanotrasen/job/job-names.ftl +++ b/Resources/Locale/en-US/nyanotrasen/job/job-names.ftl @@ -3,6 +3,8 @@ job-name-guard = Prison Guard job-name-mail-carrier = Courier job-name-martialartist = Martial Artist job-name-prisoner = Prisoner +job-name-mantis = Psionic Mantis # Role timers JobMailCarrier = Courier +JobForensicMantis = Psionic Mantis diff --git a/Resources/Locale/en-US/nyanotrasen/paper/book-epistemics.ftl b/Resources/Locale/en-US/nyanotrasen/paper/book-epistemics.ftl new file mode 100644 index 00000000000..64f68c87a89 --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/paper/book-epistemics.ftl @@ -0,0 +1,9 @@ +book-text-epistemics1 = THE EFFECTS OF HIGH GLIMMER LEVELS + + On a shift I served on one of our backwater stations, we had an eccentric mystagogue as our only command member. + Their magnum opus experiment was to... raise the glimmer as far as they could, up until our grammateus couldn't tell how much there was. + Thankfully, nobody was harmed. But as the glimmer gloomed, I'd started feeling its metallic smell, started feeling the pain of being in outer space. + And then, I saw the universe as a whole. I'd seen every movement, every thought, star, galaxy, in a dim blue marble in front of me. + When our mystagogue finally stopped, and failed to break the veil... the station felt off. Cramped, fragile with the eight of us. + Maybe they weren't crazy. I know now the universe is MASSIVELY smaller than it seems. + -Z7 diff --git a/Resources/Locale/en-US/nyanotrasen/paper/stamp-component.ftl b/Resources/Locale/en-US/nyanotrasen/paper/stamp-component.ftl new file mode 100644 index 00000000000..0434e6d26ac --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/paper/stamp-component.ftl @@ -0,0 +1 @@ +stamp-component-stamped-name-mantis = Psionic Mantis diff --git a/Resources/Locale/en-US/nyanotrasen/prototypes/fills/crates/syndicate-crates.ftl b/Resources/Locale/en-US/nyanotrasen/prototypes/fills/crates/syndicate-crates.ftl new file mode 100644 index 00000000000..1a8d1e48bba --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/prototypes/fills/crates/syndicate-crates.ftl @@ -0,0 +1,2 @@ +ent-CrateSyndicateSamurai = Syndicate samurai crate + .desc = Contains a modern replica of a full Tousei-Gusoku set. diff --git a/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl b/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl new file mode 100644 index 00000000000..6b0debd6fd8 --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/research/technologies.ftl @@ -0,0 +1,2 @@ +research-technology-psionic-countermeasures = Psionic Countermeasures +research-technology-teleportation = Teleportation diff --git a/Resources/Locale/en-US/nyanotrasen/reverse-engineering/reverseengineering.ftl b/Resources/Locale/en-US/nyanotrasen/reverse-engineering/reverseengineering.ftl new file mode 100644 index 00000000000..29584b3d806 --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/reverse-engineering/reverseengineering.ftl @@ -0,0 +1,35 @@ +reverse-engineering-machine-menu-title = reverse engineering machine +reverse-engineering-machine-server-list-button = Server List +reverse-engineering-machine-scan-button = Analyze +reverse-engineering-machine-scan-tooltip-info = Analyze the inserted item to attempt to reverse engineer it. +reverse-engineering-machine-safety-button = Safety +reverse-engineering-machine-safety-tooltip-info = Toggle safety protocols. Safety off will use stronger but possibly destructive methods of analysis. +reverse-engineering-machine-autoscan-button = AutoProbe +reverse-engineering-machine-autoscan-tooltip-info = Toggle whether to automatically start a new probe when the previous one finishes. +reverse-engineering-machine-stop-button = Stop +reverse-engineering-machine-stop-tooltip-info = Stop the current probe. +reverse-engineering-machine-eject-button = Eject +reverse-engineering-machine-eject-tooltip-info = Eject the current item. + +reverse-engineering-status-ready = Insert item to reverse engineer. +reverse-engineering-current-item = Current item: {$item} +reverse-engineering-analysis-score = Analysis power: {$score} +reverse-engineering-item-difficulty = Difficulty: {$difficulty} +reverse-engineering-progress = Progress: {$progress}% +reverse-engineering-last-attempt-result = Last probe result: {$result} + +reverse-engineering-total-progress-label = Total + +reverse-engineering-failure = CRITICAL FAILURE +reverse-engineering-stagnation = Minimal Progress +reverse-engineering-minor = Minor progress +reverse-engineering-average = Acceptable progress +reverse-engineering-major = Major progress +reverse-engineering-success = Breakthrough + +reverse-engineering-machine-bonus-upgrade = Analysis power +reverse-engineering-machine-aversion-upgrade = Destruction aversion bonus + +reverse-engineering-popup-failure = {CAPITALIZE(THE($machine))} blows smoke and debris everywhere! + +reverse-engineering-examine = [color=yellow]This item can be reverse engineered. Difficulty: {$diff}[/color] diff --git a/Resources/Locale/en-US/nyanotrasen/store/uplink-catalog.ftl b/Resources/Locale/en-US/nyanotrasen/store/uplink-catalog.ftl index 76be61245cd..1396ed20cae 100644 --- a/Resources/Locale/en-US/nyanotrasen/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/nyanotrasen/store/uplink-catalog.ftl @@ -1,2 +1,8 @@ +uplink-kanabou-name = Kanabou +uplink-kanabou-desc = A weapon for those who wish to forgo subtlety. Particularly suited to oni. + uplink-rickenbacker4001-name = Rickenbacker 4001 uplink-rickenbacker4001-desc = When it comes down to it, there are very few people who will swing the bat. + +uplink-samurai-crate-name = Syndicate samurai crate +uplink-samurai-crate-desc = A crate containing a modern replica of a full Tousei-Gusoku set. diff --git a/Resources/Locale/en-US/objectives/conditions/carp-rifts.ftl b/Resources/Locale/en-US/objectives/conditions/carp-rifts.ftl new file mode 100644 index 00000000000..6010473c552 --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/carp-rifts.ftl @@ -0,0 +1,2 @@ +objective-carp-rifts-title = Open {$count} carp rifts +objective-carp-rifts-description = Use the rift action to open {$count} rifts and ensure they do not get destroyed. If you don't open a rift after 5 minutes, you get killed. diff --git a/Resources/Locale/en-US/simplestation14/Traits/disabilities.ftl b/Resources/Locale/en-US/simplestation14/Traits/disabilities.ftl new file mode 100644 index 00000000000..3d8af061392 --- /dev/null +++ b/Resources/Locale/en-US/simplestation14/Traits/disabilities.ftl @@ -0,0 +1,3 @@ +trait-nearsighted-name = Nearsighted +trait-nearsighted-desc = You require glasses to see properly. +trait-nearsighted-examined = [color=lightblue]{CAPITALIZE(POSS-ADJ($target))} eyes are pretty unfocused. It doesn't seem like {SUBJECT($target)} can see things that well.[/color] diff --git a/Resources/Locale/en-US/weapons/grenades/timer-trigger.ftl b/Resources/Locale/en-US/weapons/grenades/timer-trigger.ftl index 76861c8b4fe..77e2dd938d6 100644 --- a/Resources/Locale/en-US/weapons/grenades/timer-trigger.ftl +++ b/Resources/Locale/en-US/weapons/grenades/timer-trigger.ftl @@ -7,6 +7,8 @@ examine-trigger-timer = The timer is set to {$time} seconds. popup-trigger-timer-set = Timer set to {$time} seconds. +verb-start-detonation = Start detonation + verb-toggle-start-on-stick = Toggle auto-activation popup-start-on-stick-off = The device will no longer activate automatically when planted popup-start-on-stick-on = The device will now activate automatically when planted diff --git a/Resources/Maps/kettle.yml b/Resources/Maps/kettle.yml index 3dadebf30ba..9bea1311dfc 100644 --- a/Resources/Maps/kettle.yml +++ b/Resources/Maps/kettle.yml @@ -54,7 +54,6 @@ tilemap: 100: FloorWhiteDiagonal 101: FloorWhiteDiagonalMini 103: FloorWhiteMini - 105: FloorWhiteOffset 108: FloorWhitePlastic 109: FloorWood 111: Lattice @@ -207,11 +206,11 @@ entities: version: 6 -3,-3: ind: -3,-3 - tiles: XwAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAaQAAAAAAYwAAAAADaQAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAAAYwAAAAADYwAAAAAAYwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAADcAAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAABaQAAAAAAaQAAAAAAYwAAAAACcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAaQAAAAAAYwAAAAACaQAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAADaQAAAAAAaQAAAAAAYwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAADYwAAAAADYwAAAAABYwAAAAADcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAaQAAAAAAYwAAAAAAYwAAAAADYwAAAAABYwAAAAAAcAAAAAAAcAAAAAAAYwAAAAADcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAaQAAAAAAaQAAAAAAcAAAAAAAYwAAAAABYwAAAAAAYwAAAAACYwAAAAACcAAAAAAAYwAAAAABYwAAAAACYwAAAAADcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAACYwAAAAADYwAAAAACYwAAAAABYwAAAAAAYwAAAAABYwAAAAACcAAAAAAAYwAAAAADYwAAAAAAYwAAAAAAcAAAAAAAGgAAAAADcAAAAAAAXwAAAAAAcAAAAAAAbQAAAAADbQAAAAAAbQAAAAADYwAAAAACYwAAAAABYwAAAAACYwAAAAADcAAAAAAAcAAAAAAAYwAAAAABcAAAAAAAcAAAAAAAGgAAAAACcAAAAAAAcAAAAAAAcAAAAAAAbQAAAAABbQAAAAAAbQAAAAACcAAAAAAAYwAAAAACYwAAAAAAYwAAAAAAYwAAAAACYwAAAAABYwAAAAAAYwAAAAABYwAAAAADGgAAAAADcAAAAAAAGgAAAAADGgAAAAAAGgAAAAABGgAAAAACGgAAAAAAcAAAAAAAYwAAAAABYwAAAAAAYwAAAAAAYwAAAAADYwAAAAADYwAAAAACYwAAAAACYwAAAAADGgAAAAADcAAAAAAAGgAAAAADGgAAAAADGgAAAAAAGgAAAAACGgAAAAAAcAAAAAAAYwAAAAACYwAAAAABYwAAAAABYwAAAAABYwAAAAAAYwAAAAADYwAAAAACYwAAAAACcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAADYwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAAAYwAAAAABYwAAAAACYwAAAAAAYwAAAAACYwAAAAACYwAAAAABYwAAAAAAYwAAAAAAYwAAAAABYwAAAAABYwAAAAABYwAAAAAAYwAAAAABYwAAAAABYwAAAAACYwAAAAAC + tiles: XwAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAYwAAAAADbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAYwAAAAADbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAYwAAAAACbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAACYwAAAAADYwAAAAACYwAAAAABbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAIwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAbQAAAAADbQAAAAAAbQAAAAADYwAAAAACbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAIwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbQAAAAABbQAAAAAAbQAAAAACcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAIwAAAAAAcAAAAAAAGgAAAAADGgAAAAAAGgAAAAABGgAAAAACGgAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAIwAAAAAAcAAAAAAAGgAAAAADGgAAAAADGgAAAAAAGgAAAAACGgAAAAAAcAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAADYwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAAAYwAAAAABYwAAAAACYwAAAAAAYwAAAAACYwAAAAACYwAAAAABYwAAAAAAYwAAAAAAYwAAAAABYwAAAAABYwAAAAABYwAAAAAAYwAAAAABYwAAAAABYwAAAAACYwAAAAAC version: 6 -2,-3: ind: -2,-3 - tiles: cAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAABGgAAAAADcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAGgAAAAAAGgAAAAACXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAIQAAAAADIQAAAAAAIQAAAAAAIQAAAAADGgAAAAAAGgAAAAAAGgAAAAACcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAAAIQAAAAAAIQAAAAABIQAAAAACGgAAAAADGgAAAAACGgAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAAARgAAAAAAIQAAAAADIQAAAAACcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAABcAAAAAAAGgAAAAABGgAAAAAAGgAAAAADGgAAAAAAcAAAAAAAIQAAAAADIQAAAAAAPAAAAAAAPAAAAAADYwAAAAACYwAAAAACYwAAAAAAcAAAAAAAGgAAAAACGgAAAAADGgAAAAADGgAAAAAAGgAAAAADGgAAAAAAGgAAAAACGgAAAAABIQAAAAACRgAAAAAAPAAAAAAEPAAAAAAEYwAAAAAAYwAAAAAAYwAAAAAAGgAAAAAAGgAAAAACGgAAAAAAGgAAAAABGgAAAAACGgAAAAAAGgAAAAADGgAAAAABGgAAAAAAIQAAAAABIQAAAAADPAAAAAAEPAAAAAAEYwAAAAABYwAAAAAAYwAAAAABcAAAAAAAGgAAAAADGgAAAAACGgAAAAACGgAAAAABGgAAAAABGgAAAAAAGgAAAAAAcAAAAAAAIQAAAAACIQAAAAAALwAAAAABLwAAAAAAYwAAAAACYwAAAAACYwAAAAADcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAADRgAAAAAALwAAAAABLwAAAAADYwAAAAACYwAAAAADYwAAAAABcAAAAAAAYwAAAAADYwAAAAABYwAAAAABYwAAAAAAYwAAAAADYwAAAAAAYwAAAAACcAAAAAAAIQAAAAACIQAAAAADLwAAAAACLwAAAAACYwAAAAADYwAAAAACYwAAAAACcAAAAAAAYwAAAAADYwAAAAADYwAAAAABYwAAAAADYwAAAAABYwAAAAAAYwAAAAADYwAAAAAAIQAAAAABRgAAAAAAIQAAAAABIQAAAAACYwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAAAYwAAAAAAYwAAAAABYwAAAAADYwAAAAACYwAAAAABYwAAAAABYwAAAAABIQAAAAADIQAAAAAAIQAAAAACIQAAAAACYwAAAAACYwAAAAACYwAAAAAAYwAAAAADYwAAAAAAYwAAAAACYwAAAAABYwAAAAADYwAAAAADYwAAAAACYwAAAAAAcAAAAAAAIQAAAAADRgAAAAAAIQAAAAADIQAAAAAB + tiles: cAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAABGgAAAAADcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAGgAAAAAAGgAAAAACXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAIQAAAAADIQAAAAAAIQAAAAAAIQAAAAADGgAAAAAAGgAAAAAAGgAAAAACcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAAAIQAAAAAAIQAAAAABIQAAAAACGgAAAAADGgAAAAACGgAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAAARgAAAAAAIQAAAAADIQAAAAACcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAABcAAAAAAAGgAAAAABGgAAAAAAGgAAAAADGgAAAAAAcAAAAAAAIQAAAAADIQAAAAAAPAAAAAAAPAAAAAADbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAGgAAAAACGgAAAAADGgAAAAADGgAAAAAAGgAAAAADGgAAAAAAGgAAAAACGgAAAAABIQAAAAACRgAAAAAAPAAAAAAEPAAAAAAEbAAAAAAAbAAAAAAAbAAAAAAAGgAAAAAAGgAAAAACGgAAAAAAGgAAAAABGgAAAAACGgAAAAAAGgAAAAADGgAAAAABGgAAAAAAIQAAAAABIQAAAAADPAAAAAAEPAAAAAAEbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAGgAAAAADGgAAAAACGgAAAAACGgAAAAABGgAAAAABGgAAAAAAGgAAAAAAcAAAAAAAIQAAAAACIQAAAAAALwAAAAABLwAAAAAAbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIQAAAAADRgAAAAAALwAAAAABLwAAAAADbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAYwAAAAADYwAAAAABYwAAAAABYwAAAAAAYwAAAAADYwAAAAAAYwAAAAACcAAAAAAAIQAAAAACIQAAAAADLwAAAAACLwAAAAACbAAAAAAAbAAAAAAAbAAAAAAAcAAAAAAAYwAAAAADYwAAAAADYwAAAAABYwAAAAADYwAAAAABYwAAAAAAYwAAAAADYwAAAAAAIQAAAAABRgAAAAAAIQAAAAABIQAAAAACYwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAYwAAAAAAYwAAAAAAYwAAAAABYwAAAAADYwAAAAACYwAAAAABYwAAAAABYwAAAAABIQAAAAADIQAAAAAAIQAAAAACIQAAAAACYwAAAAACYwAAAAACYwAAAAAAYwAAAAADYwAAAAAAYwAAAAACYwAAAAABYwAAAAADYwAAAAADYwAAAAACYwAAAAAAcAAAAAAAIQAAAAADRgAAAAAAIQAAAAADIQAAAAAB version: 6 -1,-3: ind: -1,-3 @@ -239,7 +238,7 @@ entities: version: 6 -4,-3: ind: -4,-3 - tiles: BwAAAAACBwAAAAACBwAAAAABBwAAAAACBwAAAAACBwAAAAACBwAAAAACBwAAAAACcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAABwAAAAACBwAAAAABBwAAAAAABwAAAAACBwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAABwAAAAAABwAAAAAABwAAAAACBwAAAAAABwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAABcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAABGgAAAAADGgAAAAACGgAAAAAAWAAAAAAAWAAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAAAHwAAAAABGgAAAAACHwAAAAACWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAABGgAAAAADGgAAAAADGgAAAAABWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADcAAAAAAAGgAAAAABWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAUwAAAAABUwAAAAADUwAAAAABcAAAAAAAYwAAAAABYwAAAAAAYwAAAAACYwAAAAAAYwAAAAAB + tiles: BwAAAAACBwAAAAACBwAAAAABBwAAAAACBwAAAAACBwAAAAACBwAAAAACBwAAAAACcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAABwAAAAACBwAAAAABBwAAAAAABwAAAAACBwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAABwAAAAAABwAAAAAABwAAAAACBwAAAAAABwAAAAABcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAWAAAAAAAWAAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAXwAAAAAAXwAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAIwAAAAAAWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADcAAAAAAAGgAAAAABWAAAAAAAWAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAXwAAAAAAcAAAAAAAUwAAAAABUwAAAAADUwAAAAABcAAAAAAAYwAAAAABYwAAAAAAYwAAAAACYwAAAAAAYwAAAAAB version: 6 -4,-2: ind: -4,-2 @@ -536,3830 +535,3785 @@ entities: version: 2 nodes: - node: - angle: 3.141592653589793 rad - color: '#B02E26FF' + angle: 1.5707963267948966 rad + color: '#EFB34196' id: Arrows decals: - 4740: -49.237755,-36.012096 - 4741: -48.818893,-36.01919 + 1233: -56,47 + 1234: -56,38 - node: angle: 1.5707963267948966 rad - color: '#EFB34196' - id: Arrows + color: '#52B4E996' + id: ArrowsGreyscale decals: - 1245: -56,47 - 1246: -56,38 + 4928: -41,-43 - node: - color: '#3AB3DAFF' + angle: 4.71238898038469 rad + color: '#52B4E996' id: ArrowsGreyscale decals: - 4742: -51.210106,-36.005 - 4743: -50.777042,-36.005 + 4927: -42,-41 - node: color: '#52B4E996' id: Bot decals: - 4010: 26,61 + 3903: 26,61 - node: color: '#EFB34196' id: Bot decals: - 477: 35,0 - 478: 36,0 - 479: 37,0 - 480: 35,-1 - 481: 36,-1 - 482: 37,-1 - 1092: 35,11 - 1093: 35,10 - 1094: 36,11 - 1095: 36,10 - 1096: 37,11 - 1097: 37,10 - 1098: 38,11 - 1099: 38,10 - 1100: 39,11 - 1101: 39,10 - 4009: 28,61 + 465: 35,0 + 466: 36,0 + 467: 37,0 + 468: 35,-1 + 469: 36,-1 + 470: 37,-1 + 1080: 35,11 + 1081: 35,10 + 1082: 36,11 + 1083: 36,10 + 1084: 37,11 + 1085: 37,10 + 1086: 38,11 + 1087: 38,10 + 1088: 39,11 + 1089: 39,10 + 3902: 28,61 - node: color: '#FFA500FF' id: Bot decals: - 5061: 52,-19 - 5062: 52,-20 - 5063: 52,-21 - 5064: 48,-21 - 5065: 48,-20 - 5066: 48,-19 + 4842: 52,-19 + 4843: 52,-20 + 4844: 52,-21 + 4845: 48,-21 + 4846: 48,-20 + 4847: 48,-19 - node: color: '#FFFFFFFF' id: Bot decals: - 4873: 20,76 - 4874: 21,76 - 4875: 21,75 - 4876: 20,75 - 4877: 20,73 - 4878: 21,73 - 4879: 21,72 - 4880: 20,72 + 4654: 20,76 + 4655: 21,76 + 4656: 21,75 + 4657: 20,75 + 4658: 20,73 + 4659: 21,73 + 4660: 21,72 + 4661: 20,72 - node: color: '#52B4E996' id: BotGreyscale decals: - 1681: -15,39 - 1687: 29,10 - 1694: 42,-6 - 4965: -27,18 - 4966: -27,17 - 4967: -25,18 - 4968: -25,17 + 1669: -15,39 + 1675: 29,10 + 1682: 42,-6 + 4746: -27,18 + 4747: -27,17 + 4748: -25,18 + 4749: -25,17 - node: color: '#EFB34196' id: BotGreyscale decals: - 1646: -55,-33 - 1647: -49,-29 - 1648: -44,-25 - 1649: -24,-33 - 1650: -3,-23 - 1651: 6,-27 - 1652: 17,-23 - 1653: 19,-58 - 1654: 32,-32 - 1655: 17,-6 - 1656: 40,5 - 1657: 43,-12 - 1658: 62,-3 - 1659: 22,7 - 1660: 35,30 - 1661: 43,12 - 1662: 25,25 - 1663: 30,40 - 1664: 14,48 - 1665: 26,68 - 1666: 3,38 - 1667: -20,24 - 1668: -20,21 - 1669: -27,-17 - 1670: -31,1 - 1671: 5,-2 - 1672: -3,-6 - 1673: -26,-2 - 1674: -43,-3 - 1675: -32,-23 - 1679: -23,52 - 1680: -15,41 - 1682: -61,43 - 1683: -39,31 - 1684: -18,-44 - 1685: -4,-63 - 1686: 26,-10 + 1634: -55,-33 + 1635: -49,-29 + 1636: -44,-25 + 1637: -24,-33 + 1638: -3,-23 + 1639: 6,-27 + 1640: 17,-23 + 1641: 19,-58 + 1642: 32,-32 + 1643: 17,-6 + 1644: 40,5 + 1645: 43,-12 + 1646: 62,-3 + 1647: 22,7 + 1648: 35,30 + 1649: 43,12 + 1650: 25,25 + 1651: 30,40 + 1652: 14,48 + 1653: 26,68 + 1654: 3,38 + 1655: -20,24 + 1656: -20,21 + 1657: -27,-17 + 1658: -31,1 + 1659: 5,-2 + 1660: -3,-6 + 1661: -26,-2 + 1662: -43,-3 + 1663: -32,-23 + 1667: -23,52 + 1668: -15,41 + 1670: -61,43 + 1671: -39,31 + 1672: -18,-44 + 1673: -4,-63 + 1674: 26,-10 - node: color: '#EFB34196' id: BotLeft decals: - 1056: 37,27 - 1057: 37,28 + 1044: 37,27 + 1045: 37,28 - node: angle: 3.141592653589793 rad color: '#334E6DC8' id: BotLeftGreyscale decals: - 512: -9,-1 - 513: -8,-1 - 514: -7,-1 + 500: -9,-1 + 501: -8,-1 + 502: -7,-1 + - node: + zIndex: 1 + color: '#FFFFFFFF' + id: BotLeftGreyscale + decals: + 4904: -44,-44 + 4905: -40,-44 + 4906: -42,-40 - node: color: '#EFB34196' id: BotRight decals: - 713: 24,17 - 714: 24,16 - 715: 24,15 - 716: 25,17 - 717: 25,16 - 718: 25,15 - 719: 26,17 - 720: 26,16 - 721: 26,15 - 722: 27,17 - 723: 27,16 - 724: 27,15 - 725: 28,17 - 726: 28,16 - 727: 28,15 - 728: 29,17 - 729: 29,16 - 730: 29,15 - 1102: 35,15 - 1103: 35,16 - 1104: 36,15 - 1105: 37,15 - 1106: 37,16 - 1107: 38,15 - 1108: 38,16 - 1109: 39,15 - 1110: 39,16 - 1562: 36,16 + 701: 24,17 + 702: 24,16 + 703: 24,15 + 704: 25,17 + 705: 25,16 + 706: 25,15 + 707: 26,17 + 708: 26,16 + 709: 26,15 + 710: 27,17 + 711: 27,16 + 712: 27,15 + 713: 28,17 + 714: 28,16 + 715: 28,15 + 716: 29,17 + 717: 29,16 + 718: 29,15 + 1090: 35,15 + 1091: 35,16 + 1092: 36,15 + 1093: 37,15 + 1094: 37,16 + 1095: 38,15 + 1096: 38,16 + 1097: 39,15 + 1098: 39,16 + 1550: 36,16 - node: color: '#EFB34196' id: Box decals: - 1054: 37,26 + 1042: 37,26 - node: angle: 3.141592653589793 rad color: '#EFB34196' id: Box decals: - 505: 23,1 - 506: 23,0 - 507: 22,1 - 508: 22,0 + 493: 23,1 + 494: 23,0 + 495: 22,1 + 496: 22,0 - node: color: '#EFB34196' id: BoxGreyscale decals: - 1126: 42,23 - 1127: 43,23 - 1128: 42,21 - 1129: 43,21 - 1132: 42,19 - 1133: 43,19 + 1114: 42,23 + 1115: 43,23 + 1116: 42,21 + 1117: 43,21 + 1120: 42,19 + 1121: 43,19 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNe decals: - 3644: 14,-10 - 3786: 29,-15 - 3930: 2,61 - 4023: 46,36 - 4053: 38,21 - 4067: 37,20 - 4418: -59,54 - 4458: -5,-61 - 4565: 29,56 - 4833: 16,75 - 4834: 19,74 - 4915: -31,18 + 3537: 14,-10 + 3679: 29,-15 + 3823: 2,61 + 3916: 46,36 + 3946: 38,21 + 3960: 37,20 + 4239: -59,54 + 4279: -5,-61 + 4386: 29,56 + 4614: 16,75 + 4615: 19,74 + 4696: -31,18 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerNw decals: - 3630: 0,-10 - 3787: 28,-15 - 3928: -2,61 - 4025: 43,36 - 4050: 35,21 - 4070: 36,20 - 4420: -61,54 - 4460: -7,-61 - 4498: 23,79 - 4562: 26,56 - 4831: 11,74 - 4832: 14,75 - 4912: -33,18 + 3523: 0,-10 + 3680: 28,-15 + 3821: -2,61 + 3918: 43,36 + 3943: 35,21 + 3963: 36,20 + 4241: -61,54 + 4281: -7,-61 + 4319: 23,79 + 4383: 26,56 + 4612: 11,74 + 4613: 14,75 + 4693: -33,18 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSe decals: - 3646: 14,-12 - 3664: 9,-14 - 3777: 29,-24 - 3896: -17,25 - 3929: 2,57 - 4024: 46,33 - 4056: 38,18 - 4068: 37,19 - 4459: -5,-62 - 4508: 31,73 - 4722: -30,-29 - 4835: 19,72 - 4913: -31,17 + 3539: 14,-12 + 3557: 9,-14 + 3670: 29,-24 + 3789: -17,25 + 3822: 2,57 + 3917: 46,33 + 3949: 38,18 + 3961: 37,19 + 4280: -5,-62 + 4329: 31,73 + 4529: -30,-29 + 4616: 19,72 + 4694: -31,17 - node: color: '#FFFFFFFF' id: BrickTileDarkCornerSw decals: - 3628: 0,-12 - 3660: 5,-14 - 3680: 22,-30 - 3776: 28,-24 - 3927: -2,57 - 4026: 43,33 - 4047: 35,18 - 4069: 36,19 - 4461: -7,-62 - 4492: 23,73 - 4836: 11,72 - 4914: -33,17 + 3521: 0,-12 + 3553: 5,-14 + 3573: 22,-30 + 3669: 28,-24 + 3820: -2,57 + 3919: 43,33 + 3940: 35,18 + 3962: 36,19 + 4282: -7,-62 + 4313: 23,73 + 4617: 11,72 + 4695: -33,17 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNe decals: - 3804: 28,-24 - 4850: 16,74 + 3697: 28,-24 + 4631: 16,74 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerNw decals: - 3803: 29,-24 - 4851: 14,74 - 4972: -24,16 + 3696: 29,-24 + 4632: 14,74 + 4753: -24,16 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerSe decals: - 3657: 9,-12 - 3822: 28,-15 - 3902: -17,26 + 3550: 9,-12 + 3715: 28,-15 + 3795: -17,26 - node: color: '#FFFFFFFF' id: BrickTileDarkInnerSw decals: - 3656: 5,-12 - 3821: 29,-15 - 4971: -24,19 + 3549: 5,-12 + 3714: 29,-15 + 4752: -24,19 - node: color: '#FFFFFFFF' id: BrickTileDarkLineE decals: - 3645: 14,-11 - 3658: 9,-13 - 3778: 29,-23 - 3779: 29,-22 - 3780: 29,-21 - 3781: 29,-20 - 3782: 29,-19 - 3783: 29,-18 - 3784: 29,-17 - 3785: 29,-16 - 3805: 28,-23 - 3806: 28,-22 - 3807: 28,-21 - 3808: 28,-20 - 3809: 28,-19 - 3810: 28,-18 - 3811: 28,-17 - 3812: 28,-16 - 3934: 2,58 - 3935: 2,59 - 3936: 2,60 - 4017: 46,34 - 4018: 46,35 - 4054: 38,20 - 4055: 38,19 - 4063: 35,19 - 4064: 35,20 - 4374: 41,0 - 4375: 41,-1 - 4417: -59,53 - 4509: 31,74 - 4510: 31,75 - 4566: 29,55 - 4567: 29,54 - 4568: 29,53 - 4569: 29,52 - 4700: -48,-35 - 4701: -48,-36 - 4702: -48,-37 - 4703: -48,-38 - 4723: -30,-28 - 4724: -30,-27 - 4725: -30,-26 - 4726: -30,-25 - 4837: 19,73 - 4922: -32,15 - 4923: -32,16 - 4924: -32,19 - 4925: -32,20 - 4935: -34,17 - 4936: -34,18 - 4937: -34,19 - 4938: -34,16 - 4947: -28,18 - 4948: -28,17 - 4955: -29,17 - 4956: -29,18 + 3538: 14,-11 + 3551: 9,-13 + 3671: 29,-23 + 3672: 29,-22 + 3673: 29,-21 + 3674: 29,-20 + 3675: 29,-19 + 3676: 29,-18 + 3677: 29,-17 + 3678: 29,-16 + 3698: 28,-23 + 3699: 28,-22 + 3700: 28,-21 + 3701: 28,-20 + 3702: 28,-19 + 3703: 28,-18 + 3704: 28,-17 + 3705: 28,-16 + 3827: 2,58 + 3828: 2,59 + 3829: 2,60 + 3910: 46,34 + 3911: 46,35 + 3947: 38,20 + 3948: 38,19 + 3956: 35,19 + 3957: 35,20 + 4195: 41,0 + 4196: 41,-1 + 4238: -59,53 + 4330: 31,74 + 4331: 31,75 + 4387: 29,55 + 4388: 29,54 + 4389: 29,53 + 4390: 29,52 + 4530: -30,-28 + 4531: -30,-27 + 4532: -30,-26 + 4533: -30,-25 + 4618: 19,73 + 4703: -32,15 + 4704: -32,16 + 4705: -32,19 + 4706: -32,20 + 4716: -34,17 + 4717: -34,18 + 4718: -34,19 + 4719: -34,16 + 4728: -28,18 + 4729: -28,17 + 4736: -29,17 + 4737: -29,18 - node: color: '#FFFFFFFF' id: BrickTileDarkLineN decals: - 3631: 1,-10 - 3632: 2,-10 - 3633: 3,-10 - 3634: 4,-10 - 3635: 5,-10 - 3636: 6,-10 - 3637: 7,-10 - 3638: 8,-10 - 3639: 9,-10 - 3640: 10,-10 - 3641: 11,-10 - 3642: 12,-10 - 3643: 13,-10 - 3937: 1,61 - 3938: 0,61 - 3939: -1,61 - 4021: 44,36 - 4022: 45,36 - 4051: 36,21 - 4052: 37,21 - 4065: 36,18 - 4066: 37,18 - 4419: -60,54 - 4457: -6,-61 - 4499: 24,79 - 4539: 26,79 - 4540: 27,79 - 4563: 27,56 - 4564: 28,56 - 4846: 12,74 - 4847: 13,74 - 4848: 15,75 - 4849: 17,74 - 4881: 18,74 - 4917: -32,18 + 3524: 1,-10 + 3525: 2,-10 + 3526: 3,-10 + 3527: 4,-10 + 3528: 5,-10 + 3529: 6,-10 + 3530: 7,-10 + 3531: 8,-10 + 3532: 9,-10 + 3533: 10,-10 + 3534: 11,-10 + 3535: 12,-10 + 3536: 13,-10 + 3830: 1,61 + 3831: 0,61 + 3832: -1,61 + 3914: 44,36 + 3915: 45,36 + 3944: 36,21 + 3945: 37,21 + 3958: 36,18 + 3959: 37,18 + 4240: -60,54 + 4278: -6,-61 + 4320: 24,79 + 4360: 26,79 + 4361: 27,79 + 4384: 27,56 + 4385: 28,56 + 4627: 12,74 + 4628: 13,74 + 4629: 15,75 + 4630: 17,74 + 4662: 18,74 + 4698: -32,18 - node: color: '#FFFFFFFF' id: BrickTileDarkLineS decals: - 3648: 13,-12 - 3649: 12,-12 - 3650: 11,-12 - 3651: 10,-12 - 3652: 1,-12 - 3653: 2,-12 - 3654: 3,-12 - 3655: 4,-12 - 3661: 6,-14 - 3662: 7,-14 - 3663: 8,-14 - 3683: 23,-30 - 3897: -18,25 - 3898: -19,25 - 3899: -20,25 - 3900: -21,25 - 3903: -16,26 - 3904: -15,26 - 3905: -14,26 - 3906: -13,26 - 3931: -1,57 - 3932: 0,57 - 3933: 1,57 - 4019: 44,33 - 4020: 45,33 - 4057: 37,18 - 4058: 36,18 - 4059: 36,21 - 4060: 37,21 - 4456: -6,-62 - 4500: 24,73 - 4501: 25,73 - 4502: 26,73 - 4503: 27,73 - 4504: 28,73 - 4505: 29,73 - 4506: 30,73 - 4507: 31,73 - 4537: 26,78 - 4538: 27,78 - 4714: -38,-29 - 4715: -37,-29 - 4716: -36,-29 - 4717: -35,-29 - 4718: -34,-29 - 4719: -33,-29 - 4720: -32,-29 - 4721: -31,-29 - 4839: 12,72 - 4840: 13,72 - 4841: 14,72 - 4842: 15,72 - 4843: 16,72 - 4844: 17,72 - 4845: 18,72 - 4916: -32,17 + 3541: 13,-12 + 3542: 12,-12 + 3543: 11,-12 + 3544: 10,-12 + 3545: 1,-12 + 3546: 2,-12 + 3547: 3,-12 + 3548: 4,-12 + 3554: 6,-14 + 3555: 7,-14 + 3556: 8,-14 + 3576: 23,-30 + 3790: -18,25 + 3791: -19,25 + 3792: -20,25 + 3793: -21,25 + 3796: -16,26 + 3797: -15,26 + 3798: -14,26 + 3799: -13,26 + 3824: -1,57 + 3825: 0,57 + 3826: 1,57 + 3912: 44,33 + 3913: 45,33 + 3950: 37,18 + 3951: 36,18 + 3952: 36,21 + 3953: 37,21 + 4277: -6,-62 + 4321: 24,73 + 4322: 25,73 + 4323: 26,73 + 4324: 27,73 + 4325: 28,73 + 4326: 29,73 + 4327: 30,73 + 4328: 31,73 + 4358: 26,78 + 4359: 27,78 + 4521: -38,-29 + 4522: -37,-29 + 4523: -36,-29 + 4524: -35,-29 + 4525: -34,-29 + 4526: -33,-29 + 4527: -32,-29 + 4528: -31,-29 + 4620: 12,72 + 4621: 13,72 + 4622: 14,72 + 4623: 15,72 + 4624: 16,72 + 4625: 17,72 + 4626: 18,72 + 4697: -32,17 - node: color: '#FFFFFFFF' id: BrickTileDarkLineW decals: - 3629: 0,-11 - 3659: 5,-13 - 3681: 22,-29 - 3682: 22,-28 - 3768: 28,-23 - 3769: 28,-22 - 3770: 28,-21 - 3771: 28,-20 - 3772: 28,-19 - 3773: 28,-18 - 3774: 28,-17 - 3775: 28,-16 - 3813: 29,-16 - 3814: 29,-17 - 3815: 29,-18 - 3816: 29,-19 - 3817: 29,-20 - 3818: 29,-21 - 3819: 29,-22 - 3820: 29,-23 - 3940: -2,60 - 3941: -2,59 - 3942: -2,58 - 4015: 43,34 - 4016: 43,35 - 4048: 35,19 - 4049: 35,20 - 4061: 38,20 - 4062: 38,19 - 4376: 39,0 - 4377: 39,-1 - 4421: -61,53 - 4493: 23,74 - 4494: 23,75 - 4495: 23,76 - 4496: 23,77 - 4497: 23,78 - 4560: 26,52 - 4561: 26,53 - 4590: 26,54 - 4591: 26,55 - 4704: -52,-38 - 4705: -52,-37 - 4706: -52,-35 - 4744: -52,-36 - 4838: 11,73 - 4918: -32,20 - 4919: -32,19 - 4920: -32,16 - 4921: -32,15 - 4951: -28,18 - 4952: -28,17 - 4969: -24,17 - 4970: -24,18 + 3522: 0,-11 + 3552: 5,-13 + 3574: 22,-29 + 3575: 22,-28 + 3661: 28,-23 + 3662: 28,-22 + 3663: 28,-21 + 3664: 28,-20 + 3665: 28,-19 + 3666: 28,-18 + 3667: 28,-17 + 3668: 28,-16 + 3706: 29,-16 + 3707: 29,-17 + 3708: 29,-18 + 3709: 29,-19 + 3710: 29,-20 + 3711: 29,-21 + 3712: 29,-22 + 3713: 29,-23 + 3833: -2,60 + 3834: -2,59 + 3835: -2,58 + 3908: 43,34 + 3909: 43,35 + 3941: 35,19 + 3942: 35,20 + 3954: 38,20 + 3955: 38,19 + 4197: 39,0 + 4198: 39,-1 + 4242: -61,53 + 4314: 23,74 + 4315: 23,75 + 4316: 23,76 + 4317: 23,77 + 4318: 23,78 + 4381: 26,52 + 4382: 26,53 + 4411: 26,54 + 4412: 26,55 + 4619: 11,73 + 4699: -32,20 + 4700: -32,19 + 4701: -32,16 + 4702: -32,15 + 4732: -28,18 + 4733: -28,17 + 4750: -24,17 + 4751: -24,18 - node: color: '#FFFFFFFF' id: BrickTileSteelBox decals: - 4169: -56,-32 + 3990: -56,-32 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerNe decals: - 3690: 31,-31 - 3876: 28,-8 - 3910: -24,38 - 4011: 28,70 - 4035: 40,30 - 4273: 62,-5 - 4289: 58,-14 - 4387: -58,44 - 4463: -27,4 - 4482: 81,9 + 3583: 31,-31 + 3769: 28,-8 + 3803: -24,38 + 3904: 28,70 + 3928: 40,30 + 4094: 62,-5 + 4110: 58,-14 + 4208: -58,44 + 4284: -27,4 + 4303: 81,9 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerNw decals: - 3684: 25,-31 - 3877: 23,-8 - 3908: -27,38 - 4014: 27,70 - 4036: 39,30 - 4258: 49,-5 - 4386: -62,44 - 4462: -30,4 - 4487: 77,9 + 3577: 25,-31 + 3770: 23,-8 + 3801: -27,38 + 3907: 27,70 + 3929: 39,30 + 4079: 49,-5 + 4207: -62,44 + 4283: -30,4 + 4308: 77,9 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerSe decals: - 3695: 31,-36 - 3879: 28,-9 - 3909: -24,37 - 4012: 28,69 - 4034: 40,26 - 4274: 62,-6 - 4295: 58,-20 - 4388: -58,37 - 4464: -27,1 - 4481: 81,7 + 3588: 31,-36 + 3772: 28,-9 + 3802: -24,37 + 3905: 28,69 + 3927: 40,26 + 4095: 62,-6 + 4116: 58,-20 + 4209: -58,37 + 4285: -27,1 + 4302: 81,7 - node: color: '#FFFFFFFF' id: BrickTileSteelCornerSw decals: - 3701: 25,-36 - 3878: 23,-9 - 3907: -27,37 - 4013: 27,69 - 4033: 39,26 - 4259: 49,-6 - 4299: 54,-20 - 4385: -62,37 - 4465: -30,1 - 4488: 77,7 + 3594: 25,-36 + 3771: 23,-9 + 3800: -27,37 + 3906: 27,69 + 3926: 39,26 + 4080: 49,-6 + 4120: 54,-20 + 4206: -62,37 + 4286: -30,1 + 4309: 77,7 - node: color: '#FFFFFFFF' id: BrickTileSteelEndN decals: - 4170: -56,-26 + 3991: -56,-26 - node: color: '#FFFFFFFF' id: BrickTileSteelEndS decals: - 4171: -56,-28 + 3992: -56,-28 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerNe decals: - 3724: 25,-36 - 4287: 56,-14 - 4407: -59,51 - 4413: -63,46 + 3617: 25,-36 + 4108: 56,-14 + 4228: -59,51 + 4234: -63,46 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerNw decals: - 3725: 31,-36 - 4406: -57,51 - 4412: -61,46 + 3618: 31,-36 + 4227: -57,51 + 4233: -61,46 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerSe decals: - 3727: 25,-31 - 4280: 56,-6 - 4577: 26,56 + 3620: 25,-31 + 4101: 56,-6 + 4398: 26,56 - node: color: '#FFFFFFFF' id: BrickTileSteelInnerSw decals: - 3726: 31,-31 - 4310: 54,-6 - 4311: 54,-6 - 4574: 29,56 + 3619: 31,-31 + 4131: 54,-6 + 4132: 54,-6 + 4395: 29,56 - node: color: '#FFFFFFFF' id: BrickTileSteelLineE decals: - 3691: 31,-32 - 3692: 31,-33 - 3693: 31,-34 - 3694: 31,-35 - 3706: 25,-34 - 3707: 25,-33 - 3708: 25,-32 - 3709: 25,-35 - 4030: 40,29 - 4031: 40,28 - 4032: 40,27 - 4172: -56,-27 - 4279: 56,-7 - 4281: 56,-9 - 4282: 56,-8 - 4283: 56,-10 - 4284: 56,-11 - 4285: 56,-12 - 4286: 56,-13 - 4290: 58,-15 - 4291: 58,-16 - 4292: 58,-17 - 4293: 58,-18 - 4294: 58,-19 - 4389: -58,38 - 4390: -58,39 - 4391: -58,40 - 4392: -58,41 - 4393: -58,39 - 4394: -58,42 - 4395: -58,43 - 4468: -27,2 - 4469: -27,3 - 4483: 81,8 - 4578: 26,53 - 4579: 26,52 - 4592: 26,55 - 4593: 26,54 + 3584: 31,-32 + 3585: 31,-33 + 3586: 31,-34 + 3587: 31,-35 + 3599: 25,-34 + 3600: 25,-33 + 3601: 25,-32 + 3602: 25,-35 + 3923: 40,29 + 3924: 40,28 + 3925: 40,27 + 3993: -56,-27 + 4100: 56,-7 + 4102: 56,-9 + 4103: 56,-8 + 4104: 56,-10 + 4105: 56,-11 + 4106: 56,-12 + 4107: 56,-13 + 4111: 58,-15 + 4112: 58,-16 + 4113: 58,-17 + 4114: 58,-18 + 4115: 58,-19 + 4210: -58,38 + 4211: -58,39 + 4212: -58,40 + 4213: -58,41 + 4214: -58,39 + 4215: -58,42 + 4216: -58,43 + 4289: -27,2 + 4290: -27,3 + 4304: 81,8 + 4399: 26,53 + 4400: 26,52 + 4413: 26,55 + 4414: 26,54 - node: color: '#FFFFFFFF' id: BrickTileSteelLineN decals: - 3685: 26,-31 - 3686: 27,-31 - 3687: 28,-31 - 3688: 29,-31 - 3689: 30,-31 - 3719: 30,-36 - 3720: 29,-36 - 3721: 28,-36 - 3722: 27,-36 - 3723: 26,-36 - 3858: 16,-3 - 3859: 15,-3 - 3860: 14,-3 - 3861: 13,-3 - 3862: 12,-3 - 3863: 11,-3 - 3864: 10,-3 - 3865: 9,-3 - 3866: 8,-3 - 3867: 7,-3 - 3868: 6,-3 - 3869: 5,-3 - 3870: 4,-3 - 3871: 3,-3 - 3872: 2,-3 - 3873: 1,-3 - 3874: 0,-3 - 3875: -1,-3 - 3884: 24,-8 - 3885: 25,-8 - 3886: 26,-8 - 3887: 27,-8 - 3888: -20,28 - 3889: -19,28 - 3890: -18,28 - 3891: -15,28 - 3892: -14,28 - 3893: -13,28 - 3911: -26,38 - 3912: -25,38 - 4260: 50,-5 - 4261: 51,-5 - 4262: 52,-5 - 4263: 53,-5 - 4264: 54,-5 - 4265: 55,-5 - 4266: 56,-5 - 4267: 57,-5 - 4268: 58,-5 - 4269: 58,-5 - 4270: 59,-5 - 4271: 60,-5 - 4272: 61,-5 - 4288: 57,-14 - 4396: -61,44 - 4397: -60,44 - 4398: -59,44 - 4405: -58,51 - 4411: -62,46 - 4439: 15,-24 - 4440: 14,-24 - 4441: 13,-24 - 4442: 12,-24 - 4443: 11,-24 - 4444: 10,-24 - 4445: 9,-24 - 4446: 8,-24 - 4447: 7,-24 - 4448: 6,-24 - 4449: 5,-24 - 4450: 4,-24 - 4451: 3,-24 - 4452: 2,-24 - 4453: 1,-24 - 4454: 0,-24 - 4455: -1,-24 - 4472: -29,4 - 4473: -28,4 - 4484: 80,9 - 4485: 79,9 - 4486: 78,9 + 3578: 26,-31 + 3579: 27,-31 + 3580: 28,-31 + 3581: 29,-31 + 3582: 30,-31 + 3612: 30,-36 + 3613: 29,-36 + 3614: 28,-36 + 3615: 27,-36 + 3616: 26,-36 + 3751: 16,-3 + 3752: 15,-3 + 3753: 14,-3 + 3754: 13,-3 + 3755: 12,-3 + 3756: 11,-3 + 3757: 10,-3 + 3758: 9,-3 + 3759: 8,-3 + 3760: 7,-3 + 3761: 6,-3 + 3762: 5,-3 + 3763: 4,-3 + 3764: 3,-3 + 3765: 2,-3 + 3766: 1,-3 + 3767: 0,-3 + 3768: -1,-3 + 3777: 24,-8 + 3778: 25,-8 + 3779: 26,-8 + 3780: 27,-8 + 3781: -20,28 + 3782: -19,28 + 3783: -18,28 + 3784: -15,28 + 3785: -14,28 + 3786: -13,28 + 3804: -26,38 + 3805: -25,38 + 4081: 50,-5 + 4082: 51,-5 + 4083: 52,-5 + 4084: 53,-5 + 4085: 54,-5 + 4086: 55,-5 + 4087: 56,-5 + 4088: 57,-5 + 4089: 58,-5 + 4090: 58,-5 + 4091: 59,-5 + 4092: 60,-5 + 4093: 61,-5 + 4109: 57,-14 + 4217: -61,44 + 4218: -60,44 + 4219: -59,44 + 4226: -58,51 + 4232: -62,46 + 4260: 15,-24 + 4261: 14,-24 + 4262: 13,-24 + 4263: 12,-24 + 4264: 11,-24 + 4265: 10,-24 + 4266: 9,-24 + 4267: 8,-24 + 4268: 7,-24 + 4269: 6,-24 + 4270: 5,-24 + 4271: 4,-24 + 4272: 3,-24 + 4273: 2,-24 + 4274: 1,-24 + 4275: 0,-24 + 4276: -1,-24 + 4293: -29,4 + 4294: -28,4 + 4305: 80,9 + 4306: 79,9 + 4307: 78,9 - node: color: '#FFFFFFFF' id: BrickTileSteelLineS decals: - 3696: 30,-36 - 3697: 29,-36 - 3698: 28,-36 - 3699: 27,-36 - 3700: 26,-36 - 3714: 30,-31 - 3715: 29,-31 - 3716: 28,-31 - 3717: 27,-31 - 3718: 26,-31 - 3840: -1,-5 - 3841: 0,-5 - 3842: 1,-5 - 3843: 16,-5 - 3844: 14,-5 - 3845: 15,-5 - 3846: 13,-5 - 3847: 12,-5 - 3848: 11,-5 - 3849: 10,-5 - 3850: 9,-5 - 3851: 8,-5 - 3852: 7,-5 - 3853: 6,-5 - 3854: 5,-5 - 3855: 4,-5 - 3856: 3,-5 - 3857: 2,-5 - 3880: 24,-9 - 3881: 25,-9 - 3882: 26,-9 - 3883: 27,-9 - 3913: -26,37 - 3914: -25,37 - 4275: 61,-6 - 4276: 60,-6 - 4277: 58,-6 - 4278: 57,-6 - 4296: 57,-20 - 4297: 56,-20 - 4298: 55,-20 - 4312: 53,-6 - 4313: 52,-6 - 4314: 50,-6 - 4315: 51,-6 - 4337: 59,-6 - 4382: -61,37 - 4383: -60,37 - 4384: -59,37 - 4422: -1,-26 - 4423: 0,-26 - 4424: 1,-26 - 4425: 2,-26 - 4426: 3,-26 - 4427: 4,-26 - 4428: 5,-26 - 4429: 6,-26 - 4430: 7,-26 - 4431: 8,-26 - 4432: 9,-26 - 4433: 10,-26 - 4434: 11,-26 - 4435: 12,-26 - 4436: 13,-26 - 4437: 14,-26 - 4438: 15,-26 - 4470: -29,1 - 4471: -28,1 - 4478: 78,7 - 4479: 79,7 - 4480: 80,7 - 4575: 28,56 - 4576: 27,56 + 3589: 30,-36 + 3590: 29,-36 + 3591: 28,-36 + 3592: 27,-36 + 3593: 26,-36 + 3607: 30,-31 + 3608: 29,-31 + 3609: 28,-31 + 3610: 27,-31 + 3611: 26,-31 + 3733: -1,-5 + 3734: 0,-5 + 3735: 1,-5 + 3736: 16,-5 + 3737: 14,-5 + 3738: 15,-5 + 3739: 13,-5 + 3740: 12,-5 + 3741: 11,-5 + 3742: 10,-5 + 3743: 9,-5 + 3744: 8,-5 + 3745: 7,-5 + 3746: 6,-5 + 3747: 5,-5 + 3748: 4,-5 + 3749: 3,-5 + 3750: 2,-5 + 3773: 24,-9 + 3774: 25,-9 + 3775: 26,-9 + 3776: 27,-9 + 3806: -26,37 + 3807: -25,37 + 4096: 61,-6 + 4097: 60,-6 + 4098: 58,-6 + 4099: 57,-6 + 4117: 57,-20 + 4118: 56,-20 + 4119: 55,-20 + 4133: 53,-6 + 4134: 52,-6 + 4135: 50,-6 + 4136: 51,-6 + 4158: 59,-6 + 4203: -61,37 + 4204: -60,37 + 4205: -59,37 + 4243: -1,-26 + 4244: 0,-26 + 4245: 1,-26 + 4246: 2,-26 + 4247: 3,-26 + 4248: 4,-26 + 4249: 5,-26 + 4250: 6,-26 + 4251: 7,-26 + 4252: 8,-26 + 4253: 9,-26 + 4254: 10,-26 + 4255: 11,-26 + 4256: 12,-26 + 4257: 13,-26 + 4258: 14,-26 + 4259: 15,-26 + 4291: -29,1 + 4292: -28,1 + 4299: 78,7 + 4300: 79,7 + 4301: 80,7 + 4396: 28,56 + 4397: 27,56 - node: color: '#FFFFFFFF' id: BrickTileSteelLineW decals: - 3702: 25,-35 - 3703: 25,-34 - 3704: 25,-33 - 3705: 25,-32 - 3710: 31,-35 - 3711: 31,-34 - 3712: 31,-33 - 3713: 31,-32 - 3894: -21,27 - 3895: -21,26 - 3901: -21,25 - 4027: 39,27 - 4028: 39,28 - 4029: 39,29 - 4173: -56,-27 - 4300: 54,-19 - 4301: 54,-18 - 4302: 54,-14 - 4303: 54,-13 - 4304: 54,-12 - 4305: 54,-11 - 4306: 54,-10 - 4307: 54,-9 - 4308: 54,-8 - 4309: 54,-7 - 4399: -62,43 - 4400: -62,42 - 4401: -62,41 - 4402: -62,40 - 4403: -62,39 - 4404: -62,38 - 4466: -30,2 - 4467: -30,3 - 4489: 77,8 - 4570: 29,52 - 4571: 29,53 - 4572: 29,54 - 4573: 29,55 + 3595: 25,-35 + 3596: 25,-34 + 3597: 25,-33 + 3598: 25,-32 + 3603: 31,-35 + 3604: 31,-34 + 3605: 31,-33 + 3606: 31,-32 + 3787: -21,27 + 3788: -21,26 + 3794: -21,25 + 3920: 39,27 + 3921: 39,28 + 3922: 39,29 + 3994: -56,-27 + 4121: 54,-19 + 4122: 54,-18 + 4123: 54,-14 + 4124: 54,-13 + 4125: 54,-12 + 4126: 54,-11 + 4127: 54,-10 + 4128: 54,-9 + 4129: 54,-8 + 4130: 54,-7 + 4220: -62,43 + 4221: -62,42 + 4222: -62,41 + 4223: -62,40 + 4224: -62,39 + 4225: -62,38 + 4287: -30,2 + 4288: -30,3 + 4310: 77,8 + 4391: 29,52 + 4392: 29,53 + 4393: 29,54 + 4394: 29,55 - node: color: '#334E6DC8' id: BrickTileWhiteCornerNe decals: - 3593: 5,-12 + 3486: 5,-12 - node: color: '#52B4E996' id: BrickTileWhiteCornerNe decals: - 4121: -43,-42 - 4122: -43,-40 - 4123: -43,-44 - 4124: -38,-44 - 4125: -38,-42 + 4929: -30,-35 - node: color: '#A4610696' id: BrickTileWhiteCornerNe decals: - 4046: 40,30 - 4080: 38,21 + 3939: 40,30 + 3973: 38,21 - node: color: '#D381C996' id: BrickTileWhiteCornerNe decals: - 4585: 29,56 - 4868: 16,75 - 4869: 19,74 + 4406: 29,56 + 4649: 16,75 + 4650: 19,74 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerNe decals: - 4334: 62,-5 - 4352: 58,-14 + 4155: 62,-5 + 4173: 58,-14 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerNe decals: - 3980: 29,61 - 4097: -43,-40 - 4109: -38,-42 - 4110: -43,-42 - 4111: -43,-44 - 4159: -34,-43 - 4164: -34,-43 - 4237: -17,-29 - 4623: -29,-12 + 3873: 29,61 + 4058: -17,-29 + 4444: -29,-12 - node: color: '#334E6DC8' id: BrickTileWhiteCornerNw decals: - 3620: 9,-12 + 3513: 9,-12 - node: color: '#52B4E996' id: BrickTileWhiteCornerNw decals: - 4116: -44,-40 - 4117: -44,-42 - 4118: -44,-44 - 4119: -39,-44 - 4120: -39,-42 + 4930: -40,-35 - node: color: '#A4610696' id: BrickTileWhiteCornerNw decals: - 4041: 39,30 - 4077: 35,21 + 3934: 39,30 + 3970: 35,21 - node: color: '#D381C996' id: BrickTileWhiteCornerNw decals: - 4513: 23,79 - 4582: 26,56 - 4866: 14,75 - 4867: 11,74 + 4334: 23,79 + 4403: 26,56 + 4647: 14,75 + 4648: 11,74 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerNw decals: - 4321: 49,-5 + 4142: 49,-5 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerNw decals: - 3978: 22,61 - 4098: -44,-40 - 4112: -44,-44 - 4113: -44,-42 - 4114: -39,-42 - 4115: -39,-44 - 4158: -35,-43 - 4165: -35,-43 - 4167: -35,-43 - 4235: -20,-29 - 4631: -37,-12 + 3871: 22,61 + 4056: -20,-29 + 4452: -37,-12 - node: color: '#52B4E996' id: BrickTileWhiteCornerSe decals: - 4126: -43,-41 - 4127: -43,-43 - 4128: -43,-45 - 4129: -38,-45 - 4155: -38,-43 + 4931: -30,-40 + 4932: -37,-41 - node: color: '#A4610696' id: BrickTileWhiteCornerSe decals: - 4042: 40,26 - 4071: 38,18 + 3935: 40,26 + 3964: 38,18 - node: color: '#D381C996' id: BrickTileWhiteCornerSe decals: - 4511: 31,73 - 4865: 19,72 + 4332: 31,73 + 4646: 19,72 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerSe decals: - 4335: 62,-6 - 4358: 58,-20 + 4156: 62,-6 + 4179: 58,-20 - node: color: '#F9801DFF' id: BrickTileWhiteCornerSe decals: - 4735: -30,-29 + 4542: -30,-29 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerSe decals: - 3977: 29,58 - 4104: -43,-45 - 4105: -43,-43 - 4106: -43,-41 - 4107: -38,-45 - 4108: -38,-43 - 4156: -34,-44 - 4168: -34,-44 - 4236: -17,-31 - 4621: -29,-14 + 3870: 29,58 + 4057: -17,-31 + 4442: -29,-14 - node: color: '#52B4E996' id: BrickTileWhiteCornerSw decals: - 4130: -44,-45 - 4131: -39,-45 - 4132: -39,-43 - 4133: -44,-41 - 4134: -44,-43 + 4933: -40,-41 - node: color: '#A4610696' id: BrickTileWhiteCornerSw decals: - 4040: 39,26 - 4074: 35,18 + 3933: 39,26 + 3967: 35,18 - node: color: '#D381C996' id: BrickTileWhiteCornerSw decals: - 4512: 23,73 - 4870: 11,72 + 4333: 23,73 + 4651: 11,72 - node: color: '#DE3A3A96' id: BrickTileWhiteCornerSw decals: - 4320: 49,-6 - 4362: 54,-20 + 4141: 49,-6 + 4183: 54,-20 - node: color: '#FFFFFFFF' id: BrickTileWhiteCornerSw decals: - 3979: 22,58 - 4099: -44,-41 - 4100: -44,-43 - 4101: -44,-45 - 4102: -39,-45 - 4103: -39,-43 - 4157: -35,-44 - 4166: -35,-44 - 4234: -20,-31 - 4632: -37,-13 + 3872: 22,58 + 4055: -20,-31 + 4453: -37,-13 - node: color: '#FFFFFFFF' id: BrickTileWhiteEndN decals: - 4245: 7,-39 + 4066: 7,-39 - node: color: '#FFFFFFFF' id: BrickTileWhiteEndS decals: - 4244: 7,-42 + 4065: 7,-42 - node: color: '#334E6DC8' id: BrickTileWhiteInnerNe decals: - 3598: 0,-12 - 3626: 5,-14 - 3676: -10,-3 - 4409: -59,51 + 3491: 0,-12 + 3519: 5,-14 + 3569: -10,-3 + 4230: -59,51 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerNe + decals: + 4924: -52,-37 - node: color: '#D381C996' id: BrickTileWhiteInnerNe decals: - 4871: 16,74 + 4652: 16,74 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerNe decals: - 4350: 56,-14 - 4414: -63,46 + 4171: 56,-14 + 4235: -63,46 - node: color: '#334E6DC8' id: BrickTileWhiteInnerNw decals: - 3622: 9,-14 - 3647: 14,-12 - 3677: -4,-3 - 4410: -57,51 - 4976: -24,16 + 3515: 9,-14 + 3540: 14,-12 + 3570: -4,-3 + 4231: -57,51 + 4757: -24,16 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerNw + decals: + 4923: -48,-37 - node: color: '#D381C996' id: BrickTileWhiteInnerNw decals: - 4872: 14,74 + 4653: 14,74 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerNw decals: - 4415: -61,46 + 4236: -61,46 - node: color: '#334E6DC8' id: BrickTileWhiteInnerSe decals: - 3600: 0,-10 + 3493: 0,-10 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerSe + decals: + 4916: -52,-35 + 4934: -37,-40 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerSe decals: - 4342: 56,-6 + 4163: 56,-6 - node: color: '#334E6DC8' id: BrickTileWhiteInnerSw decals: - 3614: 14,-10 - 4975: -24,19 + 3507: 14,-10 + 4756: -24,19 + - node: + color: '#52B4E996' + id: BrickTileWhiteInnerSw + decals: + 4915: -48,-35 - node: color: '#DE3A3A96' id: BrickTileWhiteInnerSw decals: - 4373: 54,-6 + 4194: 54,-6 - node: color: '#FFFFFFFF' id: BrickTileWhiteInnerSw decals: - 4635: -34,-13 + 4456: -34,-13 - node: color: '#334E6DC8' id: BrickTileWhiteLineE decals: - 3599: 0,-11 - 3627: 5,-13 + 3492: 0,-11 + 3520: 5,-13 - node: color: '#52B4E996' id: BrickTileWhiteLineE decals: - 4710: -48,-38 - 4711: -48,-37 - 4712: -48,-36 - 4713: -48,-35 + 4913: -52,-36 + 4952: -30,-36 + 4953: -30,-37 + 4954: -30,-38 + 4955: -30,-39 - node: color: '#9FED5896' id: BrickTileWhiteLineE decals: - 4928: -32,16 + 4709: -32,16 - node: color: '#A4610696' id: BrickTileWhiteLineE decals: - 4043: 40,27 - 4044: 40,28 - 4045: 40,29 - 4081: 38,20 - 4082: 38,19 + 3936: 40,27 + 3937: 40,28 + 3938: 40,29 + 3974: 38,20 + 3975: 38,19 - node: color: '#D381C996' id: BrickTileWhiteLineE decals: - 4527: 31,74 - 4528: 31,75 - 4586: 29,55 - 4587: 29,54 - 4588: 29,53 - 4589: 29,52 - 4863: 19,73 + 4348: 31,74 + 4349: 31,75 + 4407: 29,55 + 4408: 29,54 + 4409: 29,53 + 4410: 29,52 + 4644: 19,73 - node: color: '#D4D4D405' id: BrickTileWhiteLineE decals: - 4957: -29,18 - 4958: -29,17 + 4738: -29,18 + 4739: -29,17 - node: color: '#D4D4D40C' id: BrickTileWhiteLineE decals: - 4945: -28,18 - 4946: -28,17 + 4726: -28,18 + 4727: -28,17 - node: color: '#D4D4D426' id: BrickTileWhiteLineE decals: - 4949: -28,18 - 4950: -28,17 + 4730: -28,18 + 4731: -28,17 - node: color: '#D4D4D428' id: BrickTileWhiteLineE decals: - 4933: -32,19 + 4714: -32,19 - node: color: '#DE3A3A96' id: BrickTileWhiteLineE decals: - 4343: 56,-7 - 4344: 56,-8 - 4345: 56,-9 - 4346: 56,-10 - 4347: 56,-11 - 4348: 56,-12 - 4349: 56,-13 - 4353: 58,-15 - 4354: 58,-16 - 4355: 58,-17 - 4356: 58,-18 - 4357: 58,-19 - 4380: 41,0 - 4381: 41,-1 - 4930: -32,15 + 4164: 56,-7 + 4165: 56,-8 + 4166: 56,-9 + 4167: 56,-10 + 4168: 56,-11 + 4169: 56,-12 + 4170: 56,-13 + 4174: 58,-15 + 4175: 58,-16 + 4176: 58,-17 + 4177: 58,-18 + 4178: 58,-19 + 4201: 41,0 + 4202: 41,-1 + 4711: -32,15 - node: color: '#EFB34196' id: BrickTileWhiteLineE decals: - 4929: -32,20 + 4710: -32,20 - node: color: '#F9801DFF' id: BrickTileWhiteLineE decals: - 4736: -30,-28 - 4737: -30,-27 - 4738: -30,-26 - 4739: -30,-25 + 4543: -30,-28 + 4544: -30,-27 + 4545: -30,-26 + 4546: -30,-25 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineE decals: - 3995: 29,59 - 3996: 29,60 - 4243: -17,-30 - 4246: 7,-40 - 4247: 7,-41 - 4622: -29,-13 - 4934: -45,15 + 3888: 29,59 + 3889: 29,60 + 4064: -17,-30 + 4067: 7,-40 + 4068: 7,-41 + 4443: -29,-13 + 4715: -45,15 - node: color: '#334E6DC8' id: BrickTileWhiteLineN decals: - 3594: 4,-12 - 3595: 3,-12 - 3596: 2,-12 - 3597: 1,-12 - 3616: 13,-12 - 3617: 12,-12 - 3618: 11,-12 - 3619: 10,-12 - 3623: 8,-14 - 3624: 7,-14 - 3625: 6,-14 - 3673: -8,-3 - 3674: -7,-3 - 3675: -6,-3 - 4408: -58,51 + 3487: 4,-12 + 3488: 3,-12 + 3489: 2,-12 + 3490: 1,-12 + 3509: 13,-12 + 3510: 12,-12 + 3511: 11,-12 + 3512: 10,-12 + 3516: 8,-14 + 3517: 7,-14 + 3518: 6,-14 + 3566: -8,-3 + 3567: -7,-3 + 3568: -6,-3 + 4229: -58,51 - node: color: '#52B4E996' id: BrickTileWhiteLineN decals: - 4145: -42,-41 - 4146: -42,-43 - 4147: -42,-45 - 4148: -40,-45 - 4149: -40,-43 + 4920: -51,-37 + 4921: -50,-37 + 4922: -49,-37 + 4943: -39,-35 + 4944: -38,-35 + 4945: -37,-35 + 4946: -36,-35 + 4947: -35,-35 + 4948: -34,-35 + 4949: -33,-35 + 4950: -32,-35 + 4951: -31,-35 - node: color: '#A4610696' id: BrickTileWhiteLineN decals: - 4078: 36,21 - 4079: 37,21 + 3971: 36,21 + 3972: 37,21 - node: color: '#D381C996' id: BrickTileWhiteLineN decals: - 4514: 24,79 - 4543: 26,79 - 4544: 27,79 - 4583: 27,56 - 4584: 28,56 - 4859: 12,74 - 4860: 13,74 - 4861: 15,75 - 4862: 17,74 - 4882: 18,74 + 4335: 24,79 + 4364: 26,79 + 4365: 27,79 + 4404: 27,56 + 4405: 28,56 + 4640: 12,74 + 4641: 13,74 + 4642: 15,75 + 4643: 17,74 + 4663: 18,74 - node: color: '#DE3A3A96' id: BrickTileWhiteLineN decals: - 4322: 50,-5 - 4323: 51,-5 - 4324: 52,-5 - 4325: 53,-5 - 4326: 54,-5 - 4327: 55,-5 - 4328: 56,-5 - 4329: 57,-5 - 4330: 58,-5 - 4331: 59,-5 - 4332: 60,-5 - 4333: 61,-5 - 4351: 57,-14 - 4416: -62,46 + 4143: 50,-5 + 4144: 51,-5 + 4145: 52,-5 + 4146: 53,-5 + 4147: 54,-5 + 4148: 55,-5 + 4149: 56,-5 + 4150: 57,-5 + 4151: 58,-5 + 4152: 59,-5 + 4153: 60,-5 + 4154: 61,-5 + 4172: 57,-14 + 4237: -62,46 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineN decals: - 3981: 28,61 - 3982: 27,61 - 3983: 26,61 - 3984: 25,61 - 3985: 24,61 - 3986: 23,61 - 4140: -42,-41 - 4141: -42,-43 - 4142: -42,-45 - 4143: -40,-45 - 4144: -40,-43 - 4198: -53,-31 - 4199: -52,-31 - 4200: -51,-31 - 4201: -50,-31 - 4202: -49,-31 - 4203: -48,-31 - 4204: -47,-31 - 4205: -46,-31 - 4206: -45,-31 - 4207: -44,-31 - 4208: -43,-31 - 4209: -42,-31 - 4210: -41,-31 - 4211: -40,-31 - 4212: -39,-31 - 4213: -38,-31 - 4214: -37,-31 - 4215: -36,-31 - 4216: -35,-31 - 4217: -34,-31 - 4218: -33,-31 - 4219: -32,-31 - 4220: -31,-31 - 4221: -30,-31 - 4238: -19,-29 - 4239: -18,-29 - 4624: -30,-12 - 4625: -31,-12 - 4626: -32,-12 - 4627: -33,-12 - 4628: -34,-12 - 4629: -35,-12 - 4630: -36,-12 + 3874: 28,61 + 3875: 27,61 + 3876: 26,61 + 3877: 25,61 + 3878: 24,61 + 3879: 23,61 + 4019: -53,-31 + 4020: -52,-31 + 4021: -51,-31 + 4022: -50,-31 + 4023: -49,-31 + 4024: -48,-31 + 4025: -47,-31 + 4026: -46,-31 + 4027: -45,-31 + 4028: -44,-31 + 4029: -43,-31 + 4030: -42,-31 + 4031: -41,-31 + 4032: -40,-31 + 4033: -39,-31 + 4034: -38,-31 + 4035: -37,-31 + 4036: -36,-31 + 4037: -35,-31 + 4038: -34,-31 + 4039: -33,-31 + 4040: -32,-31 + 4041: -31,-31 + 4042: -30,-31 + 4059: -19,-29 + 4060: -18,-29 + 4445: -30,-12 + 4446: -31,-12 + 4447: -32,-12 + 4448: -33,-12 + 4449: -34,-12 + 4450: -35,-12 + 4451: -36,-12 - node: color: '#334E6DC8' id: BrickTileWhiteLineS decals: - 3601: 1,-10 - 3602: 2,-10 - 3603: 3,-10 - 3604: 4,-10 - 3605: 5,-10 - 3606: 6,-10 - 3607: 7,-10 - 3608: 8,-10 - 3609: 9,-10 - 3610: 10,-10 - 3611: 11,-10 - 3612: 12,-10 - 3613: 13,-10 + 3494: 1,-10 + 3495: 2,-10 + 3496: 3,-10 + 3497: 4,-10 + 3498: 5,-10 + 3499: 6,-10 + 3500: 7,-10 + 3501: 8,-10 + 3502: 9,-10 + 3503: 10,-10 + 3504: 11,-10 + 3505: 12,-10 + 3506: 13,-10 - node: color: '#52B4E996' id: BrickTileWhiteLineS decals: - 4150: -42,-41 - 4151: -42,-43 - 4152: -42,-45 - 4153: -40,-45 - 4154: -40,-43 + 4910: -51,-35 + 4911: -50,-35 + 4912: -49,-35 + 4935: -39,-41 + 4936: -38,-41 + 4937: -36,-40 + 4938: -35,-40 + 4939: -34,-40 + 4940: -33,-40 + 4941: -32,-40 + 4942: -31,-40 - node: color: '#A4610696' id: BrickTileWhiteLineS decals: - 4072: 37,18 - 4073: 36,18 + 3965: 37,18 + 3966: 36,18 - node: color: '#D381C996' id: BrickTileWhiteLineS decals: - 4520: 24,73 - 4521: 25,73 - 4522: 26,73 - 4523: 27,73 - 4524: 28,73 - 4525: 29,73 - 4526: 30,73 - 4541: 26,78 - 4542: 27,78 - 4852: 12,72 - 4853: 13,72 - 4854: 14,72 - 4855: 15,72 - 4856: 16,72 - 4857: 17,72 - 4858: 18,72 + 4341: 24,73 + 4342: 25,73 + 4343: 26,73 + 4344: 27,73 + 4345: 28,73 + 4346: 29,73 + 4347: 30,73 + 4362: 26,78 + 4363: 27,78 + 4633: 12,72 + 4634: 13,72 + 4635: 14,72 + 4636: 15,72 + 4637: 16,72 + 4638: 17,72 + 4639: 18,72 - node: color: '#DE3A3A96' id: BrickTileWhiteLineS decals: - 4316: 51,-6 - 4317: 50,-6 - 4318: 52,-6 - 4319: 53,-6 - 4336: 61,-6 - 4338: 60,-6 - 4339: 59,-6 - 4340: 58,-6 - 4341: 57,-6 - 4359: 57,-20 - 4360: 56,-20 - 4361: 55,-20 + 4137: 51,-6 + 4138: 50,-6 + 4139: 52,-6 + 4140: 53,-6 + 4157: 61,-6 + 4159: 60,-6 + 4160: 59,-6 + 4161: 58,-6 + 4162: 57,-6 + 4180: 57,-20 + 4181: 56,-20 + 4182: 55,-20 - node: color: '#F9801DFF' id: BrickTileWhiteLineS decals: - 4727: -32,-29 - 4728: -33,-29 - 4729: -34,-29 - 4730: -35,-29 - 4731: -36,-29 - 4732: -37,-29 - 4733: -38,-29 - 4734: -31,-29 + 4534: -32,-29 + 4535: -33,-29 + 4536: -34,-29 + 4537: -35,-29 + 4538: -36,-29 + 4539: -37,-29 + 4540: -38,-29 + 4541: -31,-29 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineS decals: - 3987: 23,58 - 3988: 24,58 - 3989: 25,58 - 3990: 26,58 - 3991: 27,58 - 3992: 28,58 - 4135: -42,-43 - 4136: -42,-45 - 4137: -42,-41 - 4138: -40,-43 - 4139: -40,-45 - 4174: -30,-33 - 4175: -31,-33 - 4176: -32,-33 - 4177: -33,-33 - 4178: -34,-33 - 4179: -35,-33 - 4180: -36,-33 - 4181: -37,-33 - 4182: -38,-33 - 4183: -39,-33 - 4184: -40,-33 - 4185: -41,-33 - 4186: -42,-33 - 4187: -43,-33 - 4188: -44,-33 - 4189: -45,-33 - 4190: -46,-33 - 4191: -47,-33 - 4192: -48,-33 - 4193: -49,-33 - 4194: -50,-33 - 4195: -51,-33 - 4196: -52,-33 - 4197: -53,-33 - 4240: -19,-31 - 4241: -18,-31 - 4616: -34,-14 - 4617: -33,-14 - 4618: -32,-14 - 4619: -31,-14 - 4620: -30,-14 - 4633: -36,-13 - 4634: -35,-13 + 3880: 23,58 + 3881: 24,58 + 3882: 25,58 + 3883: 26,58 + 3884: 27,58 + 3885: 28,58 + 3995: -30,-33 + 3996: -31,-33 + 3997: -32,-33 + 3998: -33,-33 + 3999: -34,-33 + 4000: -35,-33 + 4001: -36,-33 + 4002: -37,-33 + 4003: -38,-33 + 4004: -39,-33 + 4005: -40,-33 + 4006: -41,-33 + 4007: -42,-33 + 4008: -43,-33 + 4009: -44,-33 + 4010: -45,-33 + 4011: -46,-33 + 4012: -47,-33 + 4013: -48,-33 + 4014: -49,-33 + 4015: -50,-33 + 4016: -51,-33 + 4017: -52,-33 + 4018: -53,-33 + 4061: -19,-31 + 4062: -18,-31 + 4437: -34,-14 + 4438: -33,-14 + 4439: -32,-14 + 4440: -31,-14 + 4441: -30,-14 + 4454: -36,-13 + 4455: -35,-13 - node: color: '#334E6DC8' id: BrickTileWhiteLineW decals: - 3615: 14,-11 - 3621: 9,-13 - 4926: -32,20 - 4973: -24,17 - 4974: -24,18 + 3508: 14,-11 + 3514: 9,-13 + 4707: -32,20 + 4754: -24,17 + 4755: -24,18 - node: color: '#52B4E996' id: BrickTileWhiteLineW decals: - 4707: -52,-38 - 4708: -52,-37 - 4709: -52,-35 - 4745: -52,-36 - 4927: -32,15 + 4708: -32,15 + 4914: -48,-36 + 4956: -40,-40 + 4957: -40,-39 + 4958: -40,-38 + 4959: -40,-37 + 4960: -40,-36 - node: color: '#A4610696' id: BrickTileWhiteLineW decals: - 4037: 39,28 - 4038: 39,29 - 4039: 39,27 - 4075: 35,19 - 4076: 35,20 - 4932: -32,19 + 3930: 39,28 + 3931: 39,29 + 3932: 39,27 + 3968: 35,19 + 3969: 35,20 + 4713: -32,19 - node: color: '#D381C996' id: BrickTileWhiteLineW decals: - 4515: 23,78 - 4516: 23,77 - 4517: 23,76 - 4518: 23,75 - 4519: 23,74 - 4580: 26,52 - 4581: 26,53 - 4864: 11,73 - 4931: -32,16 + 4336: 23,78 + 4337: 23,77 + 4338: 23,76 + 4339: 23,75 + 4340: 23,74 + 4401: 26,52 + 4402: 26,53 + 4645: 11,73 + 4712: -32,16 - node: color: '#D4D4D407' id: BrickTileWhiteLineW decals: - 4953: -28,17 - 4954: -28,18 + 4734: -28,17 + 4735: -28,18 - node: color: '#DE3A3A96' id: BrickTileWhiteLineW decals: - 4363: 54,-19 - 4364: 54,-18 - 4365: 54,-14 - 4366: 54,-13 - 4367: 54,-12 - 4368: 54,-11 - 4369: 54,-10 - 4370: 54,-9 - 4371: 54,-8 - 4372: 54,-7 - 4378: 39,0 - 4379: 39,-1 + 4184: 54,-19 + 4185: 54,-18 + 4186: 54,-14 + 4187: 54,-13 + 4188: 54,-12 + 4189: 54,-11 + 4190: 54,-10 + 4191: 54,-9 + 4192: 54,-8 + 4193: 54,-7 + 4199: 39,0 + 4200: 39,-1 - node: color: '#FFFFFFFF' id: BrickTileWhiteLineW decals: - 3839: -34,-14 - 3993: 22,59 - 3994: 22,60 - 4242: -20,-30 - 4248: 7,-40 - 4249: 7,-41 + 3732: -34,-14 + 3886: 22,59 + 3887: 22,60 + 4063: -20,-30 + 4069: 7,-40 + 4070: 7,-41 - node: color: '#9FED58B7' id: BushAThree decals: - 4998: -1.3686488,46.73154 + 4779: -1.3686488,46.73154 - node: color: '#9FED58B7' id: BushATwo decals: - 4995: -1.8939891,47.625587 + 4776: -1.8939891,47.625587 - node: color: '#9FED5888' id: Busha1 decals: - 4987: -3.0174823,45.91548 + 4768: -3.0174823,45.91548 - node: color: '#9FED5888' id: Busha2 decals: - 4977: -1.1858082,47.7461 - 4981: -2.0945249,48.15766 - 4982: -3.1452603,46.53989 - 4984: -1.0012178,48.11507 + 4758: -1.1858082,47.7461 + 4762: -2.0945249,48.15766 + 4763: -3.1452603,46.53989 + 4765: -1.0012178,48.11507 - node: color: '#FFFFFFC0' id: Busha2 decals: - 4643: -19.715633,-0.08040953 - 4644: -18.948898,1.7076702 - 4645: -19.360664,4.00663 + 4464: -19.715633,-0.08040953 + 4465: -18.948898,1.7076702 + 4466: -19.360664,4.00663 - node: color: '#60BC5DB1' id: Busha3 decals: - 4697: -19.190277,3.2119274 + 4518: -19.190277,3.2119274 - node: color: '#9FED5896' id: Busha3 decals: - 3255: -40.3527,-18.329292 - 3256: -43.1027,-18.48207 - 3257: -42.922146,-21.50985 - 3258: -41.408257,-22.968182 - 3259: -39.96381,-23.48207 - 3260: -39.99159,-21.829292 - 3261: -41.19992,-21.815403 - 3262: -40.86659,-18.565403 - 3263: -39.811035,-17.926516 - 3264: -41.11659,-17.75985 - 3265: -42.853085,-20.88498 + 3231: -40.3527,-18.329292 + 3232: -43.1027,-18.48207 + 3233: -42.922146,-21.50985 + 3234: -41.408257,-22.968182 + 3235: -39.96381,-23.48207 + 3236: -39.99159,-21.829292 + 3237: -41.19992,-21.815403 + 3238: -40.86659,-18.565403 + 3239: -39.811035,-17.926516 + 3240: -41.11659,-17.75985 + 3241: -42.853085,-20.88498 - node: color: '#A4DF8296' id: Busha3 decals: - 1698: -7.8109317,-1.9599552 + 1686: -7.8109317,-1.9599552 - node: color: '#9FED5888' id: Bushb1 decals: - 4980: -2.7476902,46.8379 + 4761: -2.7476902,46.8379 - node: color: '#60BC5DB1' id: Bushb2 decals: - 4696: -19.928616,2.0482564 - 4698: -19.786627,0.2601776 + 4517: -19.928616,2.0482564 + 4519: -19.786627,0.2601776 - node: color: '#60E25863' id: Bushb2 decals: - 3358: -17.64635,-37.739723 + 3334: -17.64635,-37.739723 - node: color: '#60E258BA' id: Bushb2 decals: - 3359: -16.049128,-37.545277 - 3360: -15.201906,-36.309166 - 3361: -15.313017,-37.7675 - 3362: -17.03524,-36.392498 - 3363: -17.868574,-36.281387 - 3364: -17.715796,-37.948055 - 3365: -16.118574,-38.059166 - 3366: -15.243574,-36.920277 - 3367: -16.826906,-36.850834 - 3368: -17.563017,-36.809166 - 3369: -16.701906,-37.670277 - 3370: -16.688017,-36.295277 - 3371: -15.729685,-36.670277 + 3335: -16.049128,-37.545277 + 3336: -15.201906,-36.309166 + 3337: -15.313017,-37.7675 + 3338: -17.03524,-36.392498 + 3339: -17.868574,-36.281387 + 3340: -17.715796,-37.948055 + 3341: -16.118574,-38.059166 + 3342: -15.243574,-36.920277 + 3343: -16.826906,-36.850834 + 3344: -17.563017,-36.809166 + 3345: -16.701906,-37.670277 + 3346: -16.688017,-36.295277 + 3347: -15.729685,-36.670277 - node: color: '#9FED5888' id: Bushb2 decals: - 4979: -2.932261,47.646793 - 4985: -0.98705816,45.801918 + 4760: -2.932261,47.646793 + 4766: -0.98705816,45.801918 - node: color: '#9FED5896' id: Bushb2 decals: - 3330: 78.083496,7.9973173 - 3331: 79.00016,7.900096 - 3332: 79.84738,7.8862066 + 3306: 78.083496,7.9973173 + 3307: 79.00016,7.900096 + 3308: 79.84738,7.8862066 - node: color: '#9FED58B7' id: Bushb2 decals: - 4994: -1.9508109,45.96523 - 4996: -0.9142871,46.774105 + 4775: -1.9508109,45.96523 + 4777: -0.9142871,46.774105 - node: color: '#A4DF8296' id: Bushb2 decals: - 1699: -6.2553773,-1.9043994 + 1687: -6.2553773,-1.9043994 - node: color: '#FFFFFFC0' id: Bushb2 decals: - 4646: -19.999609,3.2545013 - 4647: -19.85762,1.8637729 - 4648: -18.920502,0.8420129 - 4649: -20.184193,0.5156174 - 4650: -19.062489,3.4531765 - 4651: -20.212591,4.3046427 + 4467: -19.999609,3.2545013 + 4468: -19.85762,1.8637729 + 4469: -18.920502,0.8420129 + 4470: -20.184193,0.5156174 + 4471: -19.062489,3.4531765 + 4472: -20.212591,4.3046427 - node: color: '#60BC5DB1' id: Bushb3 decals: - 4693: -19.247074,3.6518526 - 4694: -19.871819,1.7928166 - 4695: -19.829224,0.13245726 - 4699: -18.948898,3.5241327 + 4514: -19.247074,3.6518526 + 4515: -19.871819,1.7928166 + 4516: -19.829224,0.13245726 + 4520: -18.948898,3.5241327 - node: color: '#9FED5888' id: Bushb3 decals: - 4978: -3.0174766,46.241875 - 4983: -3.1594381,47.859665 + 4759: -3.0174766,46.241875 + 4764: -3.1594381,47.859665 - node: color: '#9FED58B7' id: Bushb3 decals: - 4997: -1.666812,47.42691 + 4778: -1.666812,47.42691 - node: color: '#9FED5888' id: Bushc1 decals: - 4986: -2.8187013,45.81614 + 4767: -2.8187013,45.81614 - node: color: '#FFFFFFC0' id: Bushc1 decals: - 4641: -20.013807,2.6159015 - 4642: -20.042206,1.2393641 + 4462: -20.013807,2.6159015 + 4463: -20.042206,1.2393641 - node: color: '#9FED5896' id: Bushc3 decals: - 3266: -43.038807,-18.0765 + 3242: -43.038807,-18.0765 - node: color: '#FFFFFFFF' id: Bushg1 decals: - 5002: -16.08111,-40.251266 + 4783: -16.08111,-40.251266 - node: color: '#FFFFFFFF' id: Bushg2 decals: - 5001: -17.983753,-40.59182 + 4782: -17.983753,-40.59182 - node: color: '#FFFFFFFF' id: Bushg3 decals: - 4999: -14.888399,-39.371437 + 4780: -14.888399,-39.371437 - node: color: '#FFFFFFFF' id: Bushg4 decals: - 5000: -15.484749,-39.442383 + 4781: -15.484749,-39.442383 - node: color: '#A4DF8296' id: Bushj3 decals: - 1701: -7.4513307,-22.276455 - 1702: -9.062441,-22.720898 - 1703: -8.867998,-23.748676 - 1704: -7.340218,-23.748676 + 1689: -7.4513307,-22.276455 + 1690: -9.062441,-22.720898 + 1691: -8.867998,-23.748676 + 1692: -7.340218,-23.748676 - node: color: '#A4DF8296' id: Bushk1 decals: - 1700: -8.284664,-23.526455 - 1705: -7.340218,-22.970898 + 1688: -8.284664,-23.526455 + 1693: -7.340218,-22.970898 - node: color: '#FFFFFF6C' id: Bushk1 decals: - 4639: -18.991495,3.5808964 + 4460: -18.991495,3.5808964 - node: color: '#FFFFFFC0' id: Bushk1 decals: - 4640: -19.062489,2.7720032 + 4461: -19.062489,2.7720032 - node: color: '#60E25873' id: Bushm1 decals: - 3412: -59.97946,38.265724 - 3413: -60.02113,39.390724 - 3414: -59.99335,40.724056 - 3415: -59.91002,42.335167 - 3416: -60.090576,43.071278 - 3417: -60.10446,41.279613 - 3418: -60.04891,39.765724 + 3388: -59.97946,38.265724 + 3389: -60.02113,39.390724 + 3390: -59.99335,40.724056 + 3391: -59.91002,42.335167 + 3392: -60.090576,43.071278 + 3393: -60.10446,41.279613 + 3394: -60.04891,39.765724 - node: color: '#52B4E95A' id: CheckerNESW decals: - 5015: 73,-1 - 5016: 72,-1 - 5017: 72,0 - 5018: 73,0 - 5019: 85,-1 - 5020: 85,0 - 5021: 86,0 - 5022: 86,-1 + 4796: 73,-1 + 4797: 72,-1 + 4798: 72,0 + 4799: 73,0 + 4800: 85,-1 + 4801: 85,0 + 4802: 86,0 + 4803: 86,-1 + - node: + color: '#52B4E996' + id: CheckerNESW + decals: + 4881: -34,-43 + 4882: -34,-44 + 4917: -51,-36 + 4918: -50,-36 + 4919: -49,-36 - node: color: '#52B4E996' id: CheckerNWSE decals: - 3298: -46,-35 - 3299: -46,-36 - 3300: -45,-35 - 3301: -45,-36 - 3302: -44,-35 - 3303: -44,-36 - 3304: -43,-35 - 3305: -43,-36 - 3306: -42,-35 - 3307: -42,-36 + 3274: -46,-35 + 3275: -46,-36 + 3276: -45,-35 + 3277: -45,-36 + 3278: -44,-35 + 3279: -44,-36 + 3280: -43,-35 + 3281: -43,-36 + 3282: -42,-35 + 3283: -42,-36 - node: color: '#D381C996' id: CheckerNWSE decals: - 974: 21,65 - 975: 21,64 - 976: 21,63 - 977: 22,65 - 978: 22,64 - 979: 22,63 - 980: 23,65 - 981: 23,64 - 982: 23,63 - 983: 24,65 - 984: 24,64 - 985: 24,63 + 962: 21,65 + 963: 21,64 + 964: 21,63 + 965: 22,65 + 966: 22,64 + 967: 22,63 + 968: 23,65 + 969: 23,64 + 970: 23,63 + 971: 24,65 + 972: 24,64 + 973: 24,63 - node: color: '#FED83D79' id: CheckerNWSE decals: - 5007: 85,-1 - 5008: 85,0 - 5009: 86,0 - 5010: 86,-1 - 5011: 72,-1 - 5012: 72,0 - 5013: 73,0 - 5014: 73,-1 + 4788: 85,-1 + 4789: 85,0 + 4790: 86,0 + 4791: 86,-1 + 4792: 72,-1 + 4793: 72,0 + 4794: 73,0 + 4795: 73,-1 - node: color: '#334E6DC8' id: Delivery decals: - 509: -6,-1 + 497: -6,-1 - node: color: '#79150096' id: Delivery decals: - 3321: 81,16 - 3322: 82,16 - 3323: 83,16 - 3324: 84,16 - 3325: 74,16 - 3326: 75,16 - 3327: 76,16 - 3328: 77,16 + 3297: 81,16 + 3298: 82,16 + 3299: 83,16 + 3300: 84,16 + 3301: 74,16 + 3302: 75,16 + 3303: 76,16 + 3304: 77,16 - node: color: '#EFB34196' id: Delivery decals: - 1058: 37,29 - 1219: -64,39 + 1046: 37,29 + 1207: -64,39 - node: color: '#EFB34196' id: DeliveryGreyscale decals: - 1123: 36,13 - 1124: 37,13 - 1125: 38,13 - 1130: 42,22 - 1131: 43,22 - 1134: 42,20 - 1135: 43,20 + 1111: 36,13 + 1112: 37,13 + 1113: 38,13 + 1118: 42,22 + 1119: 43,22 + 1122: 42,20 + 1123: 43,20 - node: color: '#52B4E996' id: DiagonalCheckerBOverlay decals: - 4222: -20,-29 - 4223: -20,-30 - 4224: -20,-31 - 4225: -19,-29 - 4226: -19,-30 - 4227: -19,-31 - 4228: -18,-29 - 4229: -18,-30 - 4230: -18,-31 - 4231: -17,-29 - 4232: -17,-30 - 4233: -17,-31 + 4043: -20,-29 + 4044: -20,-30 + 4045: -20,-31 + 4046: -19,-29 + 4047: -19,-30 + 4048: -19,-31 + 4049: -18,-29 + 4050: -18,-30 + 4051: -18,-31 + 4052: -17,-29 + 4053: -17,-30 + 4054: -17,-31 - node: color: '#D381C996' id: DiagonalCheckerBOverlay decals: - 3945: 22,58 - 3946: 22,59 - 3947: 22,61 - 3948: 22,60 - 3949: 23,61 - 3950: 23,60 - 3951: 23,59 - 3952: 23,58 - 3953: 24,58 - 3954: 24,59 - 3955: 24,60 - 3956: 24,61 - 3957: 25,61 - 3958: 25,60 - 3959: 25,59 - 3960: 25,58 - 3961: 26,58 - 3962: 26,59 - 3963: 26,60 - 3964: 26,61 - 3965: 27,61 - 3966: 27,60 - 3967: 27,59 - 3968: 27,58 - 3969: 28,58 - 3970: 28,59 - 3971: 28,60 - 3972: 28,61 - 3973: 29,61 - 3974: 29,60 - 3975: 29,59 - 3976: 29,58 + 3838: 22,58 + 3839: 22,59 + 3840: 22,61 + 3841: 22,60 + 3842: 23,61 + 3843: 23,60 + 3844: 23,59 + 3845: 23,58 + 3846: 24,58 + 3847: 24,59 + 3848: 24,60 + 3849: 24,61 + 3850: 25,61 + 3851: 25,60 + 3852: 25,59 + 3853: 25,58 + 3854: 26,58 + 3855: 26,59 + 3856: 26,60 + 3857: 26,61 + 3858: 27,61 + 3859: 27,60 + 3860: 27,59 + 3861: 27,58 + 3862: 28,58 + 3863: 28,59 + 3864: 28,60 + 3865: 28,61 + 3866: 29,61 + 3867: 29,60 + 3868: 29,59 + 3869: 29,58 - node: color: '#FFFFFFFF' id: DiagonalCheckerBOverlay decals: - 3823: -34,-14 - 3824: -33,-14 - 3825: -33,-13 - 3826: -29,-14 - 3827: -30,-14 - 3828: -31,-14 - 3829: -32,-14 - 3830: -32,-13 - 3831: -32,-12 - 3832: -33,-12 - 3833: -31,-12 - 3834: -31,-13 - 3835: -30,-12 - 3836: -30,-13 - 3837: -29,-13 - 3838: -29,-12 - 4608: -34,-13 - 4609: -34,-12 - 4610: -35,-12 - 4611: -35,-13 - 4612: -36,-13 - 4613: -36,-12 - 4614: -37,-13 - 4615: -37,-12 + 3716: -34,-14 + 3717: -33,-14 + 3718: -33,-13 + 3719: -29,-14 + 3720: -30,-14 + 3721: -31,-14 + 3722: -32,-14 + 3723: -32,-13 + 3724: -32,-12 + 3725: -33,-12 + 3726: -31,-12 + 3727: -31,-13 + 3728: -30,-12 + 3729: -30,-13 + 3730: -29,-13 + 3731: -29,-12 + 4429: -34,-13 + 4430: -34,-12 + 4431: -35,-12 + 4432: -35,-13 + 4433: -36,-13 + 4434: -36,-12 + 4435: -37,-13 + 4436: -37,-12 - node: cleanable: True color: '#8354328B' id: Dirt decals: - 4771: -38,-10 - 4772: -38,-13 - 4773: -32,-12 - 4774: -34,-13 - 4775: -34,-12 - 4776: -35,-12 - 4777: -36,-12 - 4778: -37,-13 - 4779: -35,-13 - 4780: -34,-13 - 4781: -33,-14 - 4782: -32,-14 - 4783: -31,-14 - 4784: -31,-12 - 4785: -30,-12 - 4786: -29,-14 - 4787: -29,-13 - 4788: -29,-12 - 4789: -31,-12 - 4790: -31,-14 - 4791: -29,-14 - 4792: -32,-16 - 4793: -33,-16 - 4794: -34,-16 - 4795: -37,-10 - 4796: -28,-12 - 4797: -32,-8 - 4798: -34,-9 - 4799: -31,-8 - 4800: -30,-7 - 4801: -33,-8 - 4802: -33,-8 - 4803: -34,-7 - 4819: -51,-35 - 4820: -51,-36 - 4821: -51,-37 - 4822: -49,-37 - 4823: -49,-36 - 4824: -49,-35 - 4825: -48,-38 - 4826: -52,-38 - 4827: -48,-38 - 4828: -52,-37 - 4829: -48,-37 - 4830: -52,-37 + 4572: -38,-10 + 4573: -38,-13 + 4574: -32,-12 + 4575: -34,-13 + 4576: -34,-12 + 4577: -35,-12 + 4578: -36,-12 + 4579: -37,-13 + 4580: -35,-13 + 4581: -34,-13 + 4582: -33,-14 + 4583: -32,-14 + 4584: -31,-14 + 4585: -31,-12 + 4586: -30,-12 + 4587: -29,-14 + 4588: -29,-13 + 4589: -29,-12 + 4590: -31,-12 + 4591: -31,-14 + 4592: -29,-14 + 4593: -32,-16 + 4594: -33,-16 + 4595: -34,-16 + 4596: -37,-10 + 4597: -28,-12 + 4598: -32,-8 + 4599: -34,-9 + 4600: -31,-8 + 4601: -30,-7 + 4602: -33,-8 + 4603: -33,-8 + 4604: -34,-7 - node: color: '#A4610696' id: Dirt decals: - 3419: -3,-35 - 3420: 1,-36 - 3421: -1,-36 - 3422: 2,-35 - 3423: 4,-36 - 3424: 8,-36 - 3425: 10,-35 - 3426: 11,-36 - 3427: 13,-36 - 3428: 15,-35 - 3429: 17,-36 - 3430: 7,-35 - 3431: 6,-35 - 3432: 4,-35 - 3433: 6,-36 - 3434: 2,-36 - 3435: 1,-35 - 3436: 3,-35 - 3437: 9,-36 - 3438: 11,-36 - 3439: 14,-36 + 3395: -3,-35 + 3396: 1,-36 + 3397: -1,-36 + 3398: 2,-35 + 3399: 4,-36 + 3400: 8,-36 + 3401: 10,-35 + 3402: 11,-36 + 3403: 13,-36 + 3404: 15,-35 + 3405: 17,-36 + 3406: 7,-35 + 3407: 6,-35 + 3408: 4,-35 + 3409: 6,-36 + 3410: 2,-36 + 3411: 1,-35 + 3412: 3,-35 + 3413: 9,-36 + 3414: 11,-36 + 3415: 14,-36 - node: cleanable: True color: '#A4610696' id: Dirt decals: - 1719: -5,50 - 1720: -6,46 - 1721: -7,44 - 1722: -4,48 - 1723: -1,50 - 1724: 2,49 - 1725: 5,49 - 1726: 6,51 - 1727: 7,49 - 1728: 9,50 - 1729: 13,49 - 1730: 16,51 - 1731: 19,49 - 1732: 23,50 - 1733: 23,49 - 1734: 29,51 - 1735: 31,51 - 1736: 32,49 - 1737: 33,47 - 1738: 31,48 - 1739: 34,53 - 1740: 33,49 - 1741: 30,49 - 1742: 32,42 - 1743: 33,40 - 1744: 33,36 - 1745: 32,34 - 1746: 32,32 - 1747: 33,33 - 1748: 32,29 - 1749: 31,27 - 1750: 32,28 - 1751: 33,24 - 1752: 32,22 - 1753: 33,23 - 1754: 31,21 - 1755: 33,19 - 1756: 32,17 - 1757: 31,16 - 1758: 32,15 - 1759: 33,14 - 1760: 31,12 - 1761: 31,11 - 1762: 33,9 - 1763: 32,8 - 1764: 31,7 - 1765: 33,4 - 1766: 30,3 - 1767: 30,2 - 1768: 30,2 - 1769: 28,1 - 1770: 28,0 - 1771: 29,0 - 1772: 27,-1 - 1773: 27,-2 - 1774: 28,-4 - 1775: 26,-4 - 1776: 25,-4 - 1777: 24,-5 - 1778: 22,-5 - 1779: 21,-4 - 1780: 20,-3 - 1781: 18,-4 - 1782: 12,-4 - 1783: 9,-4 - 1784: 7,-4 - 1785: 3,-4 - 1786: 0,-4 - 1787: 1,-4 - 1788: -5,-4 - 1789: -6,-5 - 1790: -7,-5 - 1791: -6,-4 - 1792: -10,-4 - 1793: -12,-5 - 1794: -14,-5 - 1795: -14,-4 - 1796: -16,-4 - 1797: -17,-5 - 1798: -18,-5 - 1799: -23,-5 - 1800: -24,-5 - 1801: -32,-4 - 1802: -38,-4 - 1803: -39,-4 - 1804: -40,-5 - 1805: -42,-5 - 1806: -42,-6 - 1807: -42,-7 - 1808: -42,-10 - 1809: -42,-12 - 1810: -42,-14 - 1811: -40,-16 - 1812: -42,-17 - 1813: -38,-7 - 1814: -38,-8 - 1815: -37,-7 - 1816: -33,-7 - 1817: -26,-4 - 1818: -24,-1 - 1819: -23,0 - 1820: -23,2 - 1821: -24,3 - 1822: -23,5 - 1823: -23,6 - 1824: -24,6 - 1825: -23,7 - 1826: -23,10 - 1827: -30,5 - 1828: -31,1 - 1829: -31,4 - 1830: -26,1 - 1831: -26,2 - 1832: -22,8 - 1833: -24,9 - 1834: -22,10 - 1835: -24,8 - 1836: -23,9 - 1837: -22,13 - 1838: -24,15 - 1839: -23,16 - 1840: -22,17 - 1841: -25,18 - 1842: -23,18 - 1843: -23,19 - 1844: -25,22 - 1845: -23,23 - 1846: -23,24 - 1847: -24,25 - 1848: -22,26 - 1849: -23,27 - 1850: -24,28 - 1851: -22,30 - 1852: -23,30 - 1853: -24,31 - 1854: -26,29 - 1855: -27,30 - 1856: -29,30 - 1857: -27,29 - 1858: -31,29 - 1859: -32,30 - 1860: -34,29 - 1861: -36,29 - 1862: -37,30 - 1863: -39,29 - 1864: -40,29 - 1865: -42,30 - 1866: -43,30 - 1867: -45,29 - 1868: -46,30 - 1869: -47,30 - 1870: -46,29 - 1871: -51,30 - 1872: -52,31 - 1873: -53,29 - 1874: -54,30 - 1875: -55,31 - 1876: -57,29 - 1877: -58,30 - 1878: -57,32 - 1879: -58,34 - 1880: -56,36 - 1881: -57,39 - 1882: -56,40 - 1883: -57,45 - 1884: -57,46 - 1885: -59,48 - 1886: -57,49 - 1887: -59,50 - 1888: -58,49 - 1889: -59,47 - 1890: -58,45 - 1891: -62,49 - 1892: -64,49 - 1893: -64,49 - 1894: -64,48 - 1895: -62,48 - 1896: -61,54 - 1897: -59,54 - 1898: -59,54 - 1899: -59,53 - 1900: -62,45 - 1901: -63,43 - 1902: -63,40 - 1903: -63,40 - 1904: -62,36 - 1905: -61,35 - 1906: -56,35 - 1907: -45,29 - 1908: -40,30 - 1909: -43,26 - 1910: -41,26 - 1911: -40,26 - 1912: -38,26 - 1913: -37,26 - 1914: -40,27 - 1915: -20,34 - 1916: -20,35 - 1917: -21,41 - 1918: -20,43 - 1919: -20,44 - 1920: -21,46 - 1921: -20,47 - 1922: -20,49 - 1923: -21,50 - 1924: -21,51 - 1925: -20,53 - 1926: -20,54 - 1927: -24,53 - 1928: -26,53 - 1929: -27,53 - 1930: -28,54 - 1931: -29,54 - 1932: -28,56 - 1933: -28,57 - 1934: -28,58 - 1935: -27,59 - 1936: -25,59 - 1937: -24,58 - 1938: -24,56 - 1939: -21,55 - 1940: -20,52 - 1941: -19,51 - 1942: -20,42 - 1943: -20,40 - 1944: -16,44 - 1945: -14,43 - 1946: -13,44 - 1947: -11,45 - 1948: -10,44 - 1949: -12,48 - 1950: -13,47 - 1951: -14,48 - 1952: -11,47 - 1953: -10,48 - 1954: -10,52 - 1955: -11,53 - 1956: -14,53 - 1957: -15,53 - 1958: -17,53 - 1959: -17,51 - 1960: -10,39 - 1961: -11,38 - 1962: -14,38 - 1963: -14,37 - 1964: -15,36 - 1965: -16,38 - 1966: -16,40 - 1967: -14,41 - 1968: -11,39 - 1969: -17,39 - 1970: -8,44 - 1971: -8,45 - 1972: -7,42 - 1973: -6,41 - 1974: -5,46 - 1975: -6,49 - 1976: -7,49 - 1977: 2,44 - 1978: -6,29 - 1979: -4,31 - 1980: -2,31 - 1981: 0,30 - 1982: 2,30 - 1983: 4,31 - 1984: 5,31 - 1985: 7,30 - 1986: 9,30 - 1987: 10,31 - 1988: 11,31 - 1989: 10,30 - 1990: 14,31 - 1991: 15,31 - 1992: 17,30 - 1993: 18,31 - 1994: 22,23 - 1995: 23,23 - 1996: 23,22 - 1997: 22,22 - 1998: 21,23 - 1999: 21,23 - 2000: 20,24 - 2001: 20,23 - 2002: 21,21 - 2003: 20,20 - 2004: 20,19 - 2005: 22,19 - 2006: 24,19 - 2007: 27,19 - 2008: 29,19 - 2009: 29,19 - 2010: 24,19 - 2011: 22,21 - 2012: 20,23 - 2013: 20,26 - 2014: 20,29 - 2015: 20,31 - 2016: 23,31 - 2017: 27,31 - 2018: 29,31 - 2019: 29,30 - 2020: 27,30 - 2021: 24,30 - 2022: 21,31 - 2023: 20,33 - 2024: 21,35 - 2025: 22,35 - 2026: 26,37 - 2027: 25,35 - 2028: 25,36 - 2029: 26,34 - 2030: 27,34 - 2031: 28,36 - 2032: 28,37 - 2033: 27,34 - 2034: 28,35 - 2035: 26,34 - 2036: 25,33 - 2037: 24,34 - 2038: 24,36 - 2039: 25,38 - 2040: 27,38 - 2041: 29,37 - 2042: 29,35 - 2043: 20,38 - 2044: 21,40 - 2045: 22,41 - 2046: 23,40 - 2047: 21,41 - 2048: 21,43 - 2049: 21,43 - 2050: 20,45 - 2051: 17,45 - 2052: 20,46 - 2053: 14,45 - 2054: 12,45 - 2055: 11,41 - 2056: 10,41 - 2057: 8,41 - 2058: 6,41 - 2059: 5,39 - 2060: 5,38 - 2061: 4,43 - 2062: 5,45 - 2063: 5,47 - 2064: 6,47 - 2065: 9,47 - 2066: 25,47 - 2067: 25,46 - 2068: 26,45 - 2069: 26,45 - 2070: 22,8 - 2071: 21,8 - 2072: 22,9 - 2073: 21,10 - 2074: 20,10 - 2075: 21,13 - 2076: 20,14 - 2077: 21,15 - 2078: 19,14 - 2079: 18,16 - 2080: 18,16 - 2081: 17,15 - 2082: -4,11 - 2083: -4,10 - 2084: -5,10 - 2085: -6,10 - 2086: -7,10 - 2087: -7,8 - 2088: -7,7 - 2089: -9,8 - 2090: -6,12 - 2091: -6,16 - 2092: 29,7 - 2093: 29,8 - 2094: 29,9 - 2095: 28,10 - 2096: 26,9 - 2097: 25,8 - 2098: 25,7 - 2099: 29,8 - 2100: 27,8 - 2101: 47,29 - 2102: 45,29 - 2103: 43,29 - 2104: 42,29 - 2105: 42,28 - 2106: 44,28 - 2107: 46,27 - 2108: 46,27 - 2109: 44,27 - 2110: 43,27 - 2111: 45,26 - 2112: 44,25 - 2113: 43,25 - 2114: 44,24 - 2115: 41,23 - 2116: 43,22 - 2117: 43,22 - 2118: 42,21 - 2119: 43,20 - 2120: 42,19 - 2121: 43,19 - 2122: 41,18 - 2123: 43,17 - 2124: 42,17 - 2125: 43,20 - 2126: 42,21 - 2127: 43,21 - 2128: 45,20 - 2129: 43,20 - 2130: 45,21 - 2131: 46,21 - 2132: 45,22 - 2133: 44,22 - 2134: 44,21 - 2135: 45,21 - 2136: 44,23 - 2137: 44,23 - 2138: 47,23 - 2139: 48,23 - 2140: 48,23 - 2141: 48,23 - 2142: 47,23 - 2143: 48,22 - 2144: 48,21 - 2145: 47,21 - 2146: 47,21 - 2147: 47,21 - 2148: 48,21 - 2149: 45,22 - 2150: 45,23 - 2151: 44,23 - 2152: 45,24 - 2153: 43,18 - 2154: 41,17 - 2155: 42,16 - 2156: 43,15 - 2157: 43,15 - 2158: 42,14 - 2159: 41,13 - 2160: 42,12 - 2161: 43,14 - 2162: 43,13 - 2163: 39,14 - 2164: 39,12 - 2165: 37,12 - 2166: 36,13 - 2167: 35,14 - 2168: 34,13 - 2169: 38,33 - 2170: 39,33 - 2171: 41,33 - 2172: 42,33 - 2173: 44,33 - 2174: 45,36 - 2175: 46,36 - 2176: 46,35 - 2177: 46,33 - 2178: 44,32 - 2179: 43,33 - 2180: 40,33 - 2181: 43,34 - 2182: 45,37 - 2183: 46,36 - 2184: 47,33 - 2185: 47,33 - 2186: 39,33 - 2187: 43,33 - 2188: 37,33 - 2189: 35,33 - 2190: 34,34 - 2191: 32,37 - 2192: 32,42 - 2193: 33,44 - 2194: 32,47 - 2195: 33,48 - 2196: 33,50 - 2197: 13,55 - 2198: 14,55 - 2199: 15,55 - 2200: 15,54 - 2201: 15,54 - 2202: 14,54 - 2203: 13,54 - 2204: 14,53 - 2205: 15,53 - 2206: 14,53 - 2207: 13,53 - 2208: 16,53 - 2209: 16,53 - 2210: 16,55 - 2211: 16,56 - 2212: 14,56 - 2213: 14,56 - 2214: 16,57 - 2215: 14,57 - 2216: 13,57 - 2217: 12,57 - 2218: 11,55 - 2219: 12,54 - 2220: 11,53 - 2221: 19,60 - 2222: 19,57 - 2223: 18,60 - 2224: 18,64 - 2225: 20,65 - 2226: 22,66 - 2227: 21,66 - 2228: 22,64 - 2229: 21,64 - 2230: 23,65 - 2231: 24,66 - 2232: 23,67 - 2233: 23,69 - 2234: 24,71 - 2235: 26,71 - 2236: 26,69 - 2237: 27,68 - 2238: 29,69 - 2239: 11,72 - 2240: 20,74 - 2241: 20,73 - 2242: 23,47 - 2243: 23,47 - 2244: 23,47 - 2245: 23,46 - 2246: 23,46 - 2247: 22,47 - 2248: 35,57 - 2249: 36,56 - 2250: 36,56 - 2251: 37,56 - 2252: 36,56 - 2253: 36,55 - 2254: 36,54 - 2255: 36,53 - 2256: 38,53 - 2257: 40,53 - 2258: 40,55 - 2259: 40,56 - 2260: 41,57 - 2261: 41,56 - 2262: 39,56 - 2263: 40,55 - 2264: 41,53 - 2265: 41,53 - 2266: 43,54 - 2267: 43,55 - 2268: 43,57 - 2269: 43,55 - 2270: 43,53 - 2271: 43,52 - 2272: 43,50 - 2273: 45,50 - 2274: 46,50 - 2275: 47,50 - 2276: 47,49 - 2277: 47,47 - 2278: 47,46 - 2279: 47,46 - 2280: 46,44 - 2281: 46,44 - 2282: 46,45 - 2283: 46,46 - 2284: 46,47 - 2285: 40,50 - 2286: 40,48 - 2287: 40,46 - 2288: 39,45 - 2289: 37,46 - 2290: 35,46 - 2291: 40,50 - 2292: 40,52 - 2293: 40,51 - 2294: 40,50 - 2295: 40,43 - 2296: 40,43 - 2297: 40,44 - 2298: 39,44 - 2299: 39,44 - 2300: 39,43 - 2301: 39,42 - 2302: 39,40 - 2303: 39,39 - 2304: 40,39 - 2305: 43,39 - 2306: 45,39 - 2307: 46,39 - 2308: 47,39 - 2309: 47,40 - 2310: 46,41 - 2311: 47,42 - 2312: 47,44 - 2313: 47,46 - 2314: 47,48 - 2315: 43,44 - 2316: 44,44 - 2317: 42,43 - 2318: 42,42 - 2319: 43,41 - 2320: 44,41 - 2321: 44,43 - 2322: 43,45 - 2323: 43,47 - 2324: 44,48 - 2325: 44,48 - 2326: 49,33 - 2327: 49,34 - 2328: 50,35 - 2329: 50,36 - 2330: 50,36 - 2331: 35,7 - 2332: 35,8 - 2333: 36,8 - 2334: 37,8 - 2335: 40,8 - 2336: 40,8 - 2337: 40,7 - 2338: 38,7 - 2339: 38,7 - 2340: 41,9 - 2341: 44,9 - 2342: 42,9 - 2343: 46,9 - 2344: 47,9 - 2345: 49,9 - 2346: 49,9 - 2347: 50,9 - 2348: 38,4 - 2349: 35,4 - 2350: 39,2 - 2351: 43,3 + 1707: -5,50 + 1708: -6,46 + 1709: -7,44 + 1710: -4,48 + 1711: -1,50 + 1712: 2,49 + 1713: 5,49 + 1714: 6,51 + 1715: 7,49 + 1716: 9,50 + 1717: 13,49 + 1718: 16,51 + 1719: 19,49 + 1720: 23,50 + 1721: 23,49 + 1722: 29,51 + 1723: 31,51 + 1724: 32,49 + 1725: 33,47 + 1726: 31,48 + 1727: 34,53 + 1728: 33,49 + 1729: 30,49 + 1730: 32,42 + 1731: 33,40 + 1732: 33,36 + 1733: 32,34 + 1734: 32,32 + 1735: 33,33 + 1736: 32,29 + 1737: 31,27 + 1738: 32,28 + 1739: 33,24 + 1740: 32,22 + 1741: 33,23 + 1742: 31,21 + 1743: 33,19 + 1744: 32,17 + 1745: 31,16 + 1746: 32,15 + 1747: 33,14 + 1748: 31,12 + 1749: 31,11 + 1750: 33,9 + 1751: 32,8 + 1752: 31,7 + 1753: 33,4 + 1754: 30,3 + 1755: 30,2 + 1756: 30,2 + 1757: 28,1 + 1758: 28,0 + 1759: 29,0 + 1760: 27,-1 + 1761: 27,-2 + 1762: 28,-4 + 1763: 26,-4 + 1764: 25,-4 + 1765: 24,-5 + 1766: 22,-5 + 1767: 21,-4 + 1768: 20,-3 + 1769: 18,-4 + 1770: 12,-4 + 1771: 9,-4 + 1772: 7,-4 + 1773: 3,-4 + 1774: 0,-4 + 1775: 1,-4 + 1776: -5,-4 + 1777: -6,-5 + 1778: -7,-5 + 1779: -6,-4 + 1780: -10,-4 + 1781: -12,-5 + 1782: -14,-5 + 1783: -14,-4 + 1784: -16,-4 + 1785: -17,-5 + 1786: -18,-5 + 1787: -23,-5 + 1788: -24,-5 + 1789: -32,-4 + 1790: -38,-4 + 1791: -39,-4 + 1792: -40,-5 + 1793: -42,-5 + 1794: -42,-6 + 1795: -42,-7 + 1796: -42,-10 + 1797: -42,-12 + 1798: -42,-14 + 1799: -40,-16 + 1800: -42,-17 + 1801: -38,-7 + 1802: -38,-8 + 1803: -37,-7 + 1804: -33,-7 + 1805: -26,-4 + 1806: -24,-1 + 1807: -23,0 + 1808: -23,2 + 1809: -24,3 + 1810: -23,5 + 1811: -23,6 + 1812: -24,6 + 1813: -23,7 + 1814: -23,10 + 1815: -30,5 + 1816: -31,1 + 1817: -31,4 + 1818: -26,1 + 1819: -26,2 + 1820: -22,8 + 1821: -24,9 + 1822: -22,10 + 1823: -24,8 + 1824: -23,9 + 1825: -22,13 + 1826: -24,15 + 1827: -23,16 + 1828: -22,17 + 1829: -25,18 + 1830: -23,18 + 1831: -23,19 + 1832: -25,22 + 1833: -23,23 + 1834: -23,24 + 1835: -24,25 + 1836: -22,26 + 1837: -23,27 + 1838: -24,28 + 1839: -22,30 + 1840: -23,30 + 1841: -24,31 + 1842: -26,29 + 1843: -27,30 + 1844: -29,30 + 1845: -27,29 + 1846: -31,29 + 1847: -32,30 + 1848: -34,29 + 1849: -36,29 + 1850: -37,30 + 1851: -39,29 + 1852: -40,29 + 1853: -42,30 + 1854: -43,30 + 1855: -45,29 + 1856: -46,30 + 1857: -47,30 + 1858: -46,29 + 1859: -51,30 + 1860: -52,31 + 1861: -53,29 + 1862: -54,30 + 1863: -55,31 + 1864: -57,29 + 1865: -58,30 + 1866: -57,32 + 1867: -58,34 + 1868: -56,36 + 1869: -57,39 + 1870: -56,40 + 1871: -57,45 + 1872: -57,46 + 1873: -59,48 + 1874: -57,49 + 1875: -59,50 + 1876: -58,49 + 1877: -59,47 + 1878: -58,45 + 1879: -62,49 + 1880: -64,49 + 1881: -64,49 + 1882: -64,48 + 1883: -62,48 + 1884: -61,54 + 1885: -59,54 + 1886: -59,54 + 1887: -59,53 + 1888: -62,45 + 1889: -63,43 + 1890: -63,40 + 1891: -63,40 + 1892: -62,36 + 1893: -61,35 + 1894: -56,35 + 1895: -45,29 + 1896: -40,30 + 1897: -43,26 + 1898: -41,26 + 1899: -40,26 + 1900: -38,26 + 1901: -37,26 + 1902: -40,27 + 1903: -20,34 + 1904: -20,35 + 1905: -21,41 + 1906: -20,43 + 1907: -20,44 + 1908: -21,46 + 1909: -20,47 + 1910: -20,49 + 1911: -21,50 + 1912: -21,51 + 1913: -20,53 + 1914: -20,54 + 1915: -24,53 + 1916: -26,53 + 1917: -27,53 + 1918: -28,54 + 1919: -29,54 + 1920: -28,56 + 1921: -28,57 + 1922: -28,58 + 1923: -27,59 + 1924: -25,59 + 1925: -24,58 + 1926: -24,56 + 1927: -21,55 + 1928: -20,52 + 1929: -19,51 + 1930: -20,42 + 1931: -20,40 + 1932: -16,44 + 1933: -14,43 + 1934: -13,44 + 1935: -11,45 + 1936: -10,44 + 1937: -12,48 + 1938: -13,47 + 1939: -14,48 + 1940: -11,47 + 1941: -10,48 + 1942: -10,52 + 1943: -11,53 + 1944: -14,53 + 1945: -15,53 + 1946: -17,53 + 1947: -17,51 + 1948: -10,39 + 1949: -11,38 + 1950: -14,38 + 1951: -14,37 + 1952: -15,36 + 1953: -16,38 + 1954: -16,40 + 1955: -14,41 + 1956: -11,39 + 1957: -17,39 + 1958: -8,44 + 1959: -8,45 + 1960: -7,42 + 1961: -6,41 + 1962: -5,46 + 1963: -6,49 + 1964: -7,49 + 1965: 2,44 + 1966: -6,29 + 1967: -4,31 + 1968: -2,31 + 1969: 0,30 + 1970: 2,30 + 1971: 4,31 + 1972: 5,31 + 1973: 7,30 + 1974: 9,30 + 1975: 10,31 + 1976: 11,31 + 1977: 10,30 + 1978: 14,31 + 1979: 15,31 + 1980: 17,30 + 1981: 18,31 + 1982: 22,23 + 1983: 23,23 + 1984: 23,22 + 1985: 22,22 + 1986: 21,23 + 1987: 21,23 + 1988: 20,24 + 1989: 20,23 + 1990: 21,21 + 1991: 20,20 + 1992: 20,19 + 1993: 22,19 + 1994: 24,19 + 1995: 27,19 + 1996: 29,19 + 1997: 29,19 + 1998: 24,19 + 1999: 22,21 + 2000: 20,23 + 2001: 20,26 + 2002: 20,29 + 2003: 20,31 + 2004: 23,31 + 2005: 27,31 + 2006: 29,31 + 2007: 29,30 + 2008: 27,30 + 2009: 24,30 + 2010: 21,31 + 2011: 20,33 + 2012: 21,35 + 2013: 22,35 + 2014: 26,37 + 2015: 25,35 + 2016: 25,36 + 2017: 26,34 + 2018: 27,34 + 2019: 28,36 + 2020: 28,37 + 2021: 27,34 + 2022: 28,35 + 2023: 26,34 + 2024: 25,33 + 2025: 24,34 + 2026: 24,36 + 2027: 25,38 + 2028: 27,38 + 2029: 29,37 + 2030: 29,35 + 2031: 20,38 + 2032: 21,40 + 2033: 22,41 + 2034: 23,40 + 2035: 21,41 + 2036: 21,43 + 2037: 21,43 + 2038: 20,45 + 2039: 17,45 + 2040: 20,46 + 2041: 14,45 + 2042: 12,45 + 2043: 11,41 + 2044: 10,41 + 2045: 8,41 + 2046: 6,41 + 2047: 5,39 + 2048: 5,38 + 2049: 4,43 + 2050: 5,45 + 2051: 5,47 + 2052: 6,47 + 2053: 9,47 + 2054: 25,47 + 2055: 25,46 + 2056: 26,45 + 2057: 26,45 + 2058: 22,8 + 2059: 21,8 + 2060: 22,9 + 2061: 21,10 + 2062: 20,10 + 2063: 21,13 + 2064: 20,14 + 2065: 21,15 + 2066: 19,14 + 2067: 18,16 + 2068: 18,16 + 2069: 17,15 + 2070: -4,11 + 2071: -4,10 + 2072: -5,10 + 2073: -6,10 + 2074: -7,10 + 2075: -7,8 + 2076: -7,7 + 2077: -9,8 + 2078: -6,12 + 2079: -6,16 + 2080: 29,7 + 2081: 29,8 + 2082: 29,9 + 2083: 28,10 + 2084: 26,9 + 2085: 25,8 + 2086: 25,7 + 2087: 29,8 + 2088: 27,8 + 2089: 47,29 + 2090: 45,29 + 2091: 43,29 + 2092: 42,29 + 2093: 42,28 + 2094: 44,28 + 2095: 46,27 + 2096: 46,27 + 2097: 44,27 + 2098: 43,27 + 2099: 45,26 + 2100: 44,25 + 2101: 43,25 + 2102: 44,24 + 2103: 41,23 + 2104: 43,22 + 2105: 43,22 + 2106: 42,21 + 2107: 43,20 + 2108: 42,19 + 2109: 43,19 + 2110: 41,18 + 2111: 43,17 + 2112: 42,17 + 2113: 43,20 + 2114: 42,21 + 2115: 43,21 + 2116: 45,20 + 2117: 43,20 + 2118: 45,21 + 2119: 46,21 + 2120: 45,22 + 2121: 44,22 + 2122: 44,21 + 2123: 45,21 + 2124: 44,23 + 2125: 44,23 + 2126: 47,23 + 2127: 48,23 + 2128: 48,23 + 2129: 48,23 + 2130: 47,23 + 2131: 48,22 + 2132: 48,21 + 2133: 47,21 + 2134: 47,21 + 2135: 47,21 + 2136: 48,21 + 2137: 45,22 + 2138: 45,23 + 2139: 44,23 + 2140: 45,24 + 2141: 43,18 + 2142: 41,17 + 2143: 42,16 + 2144: 43,15 + 2145: 43,15 + 2146: 42,14 + 2147: 41,13 + 2148: 42,12 + 2149: 43,14 + 2150: 43,13 + 2151: 39,14 + 2152: 39,12 + 2153: 37,12 + 2154: 36,13 + 2155: 35,14 + 2156: 34,13 + 2157: 38,33 + 2158: 39,33 + 2159: 41,33 + 2160: 42,33 + 2161: 44,33 + 2162: 45,36 + 2163: 46,36 + 2164: 46,35 + 2165: 46,33 + 2166: 44,32 + 2167: 43,33 + 2168: 40,33 + 2169: 43,34 + 2170: 45,37 + 2171: 46,36 + 2172: 47,33 + 2173: 47,33 + 2174: 39,33 + 2175: 43,33 + 2176: 37,33 + 2177: 35,33 + 2178: 34,34 + 2179: 32,37 + 2180: 32,42 + 2181: 33,44 + 2182: 32,47 + 2183: 33,48 + 2184: 33,50 + 2185: 13,55 + 2186: 14,55 + 2187: 15,55 + 2188: 15,54 + 2189: 15,54 + 2190: 14,54 + 2191: 13,54 + 2192: 14,53 + 2193: 15,53 + 2194: 14,53 + 2195: 13,53 + 2196: 16,53 + 2197: 16,53 + 2198: 16,55 + 2199: 16,56 + 2200: 14,56 + 2201: 14,56 + 2202: 16,57 + 2203: 14,57 + 2204: 13,57 + 2205: 12,57 + 2206: 11,55 + 2207: 12,54 + 2208: 11,53 + 2209: 19,60 + 2210: 19,57 + 2211: 18,60 + 2212: 18,64 + 2213: 20,65 + 2214: 22,66 + 2215: 21,66 + 2216: 22,64 + 2217: 21,64 + 2218: 23,65 + 2219: 24,66 + 2220: 23,67 + 2221: 23,69 + 2222: 24,71 + 2223: 26,71 + 2224: 26,69 + 2225: 27,68 + 2226: 29,69 + 2227: 11,72 + 2228: 20,74 + 2229: 20,73 + 2230: 23,47 + 2231: 23,47 + 2232: 23,47 + 2233: 23,46 + 2234: 23,46 + 2235: 22,47 + 2236: 35,57 + 2237: 36,56 + 2238: 36,56 + 2239: 37,56 + 2240: 36,56 + 2241: 36,55 + 2242: 36,54 + 2243: 36,53 + 2244: 38,53 + 2245: 40,53 + 2246: 40,55 + 2247: 40,56 + 2248: 41,57 + 2249: 41,56 + 2250: 39,56 + 2251: 40,55 + 2252: 41,53 + 2253: 41,53 + 2254: 43,54 + 2255: 43,55 + 2256: 43,57 + 2257: 43,55 + 2258: 43,53 + 2259: 43,52 + 2260: 43,50 + 2261: 45,50 + 2262: 46,50 + 2263: 47,50 + 2264: 47,49 + 2265: 47,47 + 2266: 47,46 + 2267: 47,46 + 2268: 46,44 + 2269: 46,44 + 2270: 46,45 + 2271: 46,46 + 2272: 46,47 + 2273: 40,50 + 2274: 40,48 + 2275: 40,46 + 2276: 39,45 + 2277: 37,46 + 2278: 35,46 + 2279: 40,50 + 2280: 40,52 + 2281: 40,51 + 2282: 40,50 + 2283: 40,43 + 2284: 40,43 + 2285: 40,44 + 2286: 39,44 + 2287: 39,44 + 2288: 39,43 + 2289: 39,42 + 2290: 39,40 + 2291: 39,39 + 2292: 40,39 + 2293: 43,39 + 2294: 45,39 + 2295: 46,39 + 2296: 47,39 + 2297: 47,40 + 2298: 46,41 + 2299: 47,42 + 2300: 47,44 + 2301: 47,46 + 2302: 47,48 + 2303: 43,44 + 2304: 44,44 + 2305: 42,43 + 2306: 42,42 + 2307: 43,41 + 2308: 44,41 + 2309: 44,43 + 2310: 43,45 + 2311: 43,47 + 2312: 44,48 + 2313: 44,48 + 2314: 49,33 + 2315: 49,34 + 2316: 50,35 + 2317: 50,36 + 2318: 50,36 + 2319: 35,7 + 2320: 35,8 + 2321: 36,8 + 2322: 37,8 + 2323: 40,8 + 2324: 40,8 + 2325: 40,7 + 2326: 38,7 + 2327: 38,7 + 2328: 41,9 + 2329: 44,9 + 2330: 42,9 + 2331: 46,9 + 2332: 47,9 + 2333: 49,9 + 2334: 49,9 + 2335: 50,9 + 2336: 38,4 + 2337: 35,4 + 2338: 39,2 + 2339: 43,3 + 2340: 45,3 + 2341: 44,0 + 2342: 44,-1 + 2343: 47,-1 + 2344: 44,-1 + 2345: 46,-1 + 2346: 46,-1 + 2347: 45,-1 + 2348: 46,0 + 2349: 45,0 + 2350: 46,3 + 2351: 47,3 2352: 45,3 - 2353: 44,0 - 2354: 44,-1 - 2355: 47,-1 - 2356: 44,-1 - 2357: 46,-1 - 2358: 46,-1 - 2359: 45,-1 - 2360: 46,0 - 2361: 45,0 - 2362: 46,3 - 2363: 47,3 - 2364: 45,3 - 2365: 46,4 - 2366: 49,3 - 2367: 51,3 - 2368: 48,2 - 2369: 53,3 - 2370: 55,3 - 2371: 57,2 - 2372: 59,3 - 2373: 61,2 - 2374: 63,4 - 2375: 64,2 - 2376: 65,3 - 2377: 66,3 - 2378: 69,3 - 2379: 69,3 - 2380: 72,4 - 2381: 73,3 - 2382: 75,3 - 2383: 76,3 - 2384: 78,3 - 2385: 79,3 - 2386: 81,3 - 2387: 83,4 - 2388: 84,2 - 2389: 85,3 - 2390: 86,4 - 2391: 83,7 - 2392: 80,7 - 2393: 78,6 - 2394: 76,8 - 2395: 77,9 - 2396: 80,9 - 2397: 83,9 - 2398: 82,12 - 2399: 82,13 - 2400: 83,14 - 2401: 83,14 - 2402: 83,13 - 2403: 75,13 - 2404: 75,15 - 2405: 76,15 - 2406: 76,14 - 2407: 76,9 - 2408: 76,6 - 2409: 77,6 - 2410: 83,6 - 2411: 83,8 - 2412: 84,3 - 2413: 67,2 - 2414: 66,4 - 2415: 61,2 - 2416: 58,4 - 2417: 57,3 - 2418: 56,2 - 2419: 52,4 - 2420: 51,3 - 2421: 53,-13 - 2422: 60,-20 - 2423: 62,-21 - 2424: 61,-22 - 2425: 60,-19 - 2426: 43,-16 - 2427: 41,-16 - 2428: 38,-16 - 2429: 37,-16 - 2430: 37,-19 - 2431: 37,-20 - 2432: 37,-20 - 2433: 36,-20 - 2434: 37,-20 - 2435: 37,-20 - 2436: 40,-19 - 2437: 40,-19 - 2438: 39,-19 - 2439: 40,-20 - 2440: 43,-19 - 2441: 43,-20 - 2442: 42,-20 - 2443: 45,-19 - 2444: 45,-20 - 2445: 45,-20 - 2446: 46,-20 - 2447: 38,-16 - 2448: 36,-14 - 2449: 35,-13 - 2450: 35,-11 - 2451: 34,-9 - 2452: 35,-7 - 2453: 36,-6 - 2454: 36,-4 - 2455: 36,-3 - 2456: 38,-5 - 2457: 40,-3 - 2458: 39,-3 - 2459: 41,-3 - 2460: 39,2 - 2461: 41,2 - 2462: 31,2 - 2463: 30,3 - 2464: 28,1 - 2465: 28,3 - 2466: 29,0 - 2467: 23,-7 - 2468: 28,-7 - 2469: 7,-16 - 2470: 7,-16 - 2471: 7,-17 - 2472: -9,-2 - 2473: -9,-1 - 2474: -8,-1 - 2475: -7,-1 - 2476: -6,-1 - 2477: -5,-2 - 2478: -5,-6 - 2479: -5,-15 - 2480: -4,-15 - 2481: -6,-19 - 2482: -5,-17 - 2483: -6,-20 - 2484: -4,-22 - 2485: -4,-24 - 2486: -5,-26 - 2487: -8,-26 - 2488: -9,-26 - 2489: -10,-25 - 2490: -11,-27 - 2491: -10,-28 - 2492: -7,-28 - 2493: -13,-25 - 2494: -14,-26 - 2495: -17,-26 - 2496: -19,-25 - 2497: -20,-27 - 2498: -22,-26 - 2499: -25,-26 - 2500: -26,-29 - 2501: -27,-30 - 2502: -26,-31 - 2503: -27,-31 - 2504: -27,-33 - 2505: -25,-34 - 2506: -26,-35 - 2507: -24,-35 - 2508: -23,-35 - 2509: -23,-34 - 2510: -27,-26 - 2511: -28,-26 - 2512: -31,-28 - 2513: -33,-28 - 2514: -37,-28 - 2515: -31,-28 - 2516: -31,-27 - 2517: -37,-28 - 2518: -31,-31 - 2519: -33,-32 - 2520: -34,-33 - 2521: -36,-32 - 2522: -37,-32 - 2523: -39,-33 - 2524: -37,-32 - 2525: -41,-31 + 2353: 46,4 + 2354: 49,3 + 2355: 51,3 + 2356: 48,2 + 2357: 53,3 + 2358: 55,3 + 2359: 57,2 + 2360: 59,3 + 2361: 61,2 + 2362: 63,4 + 2363: 64,2 + 2364: 65,3 + 2365: 66,3 + 2366: 69,3 + 2367: 69,3 + 2368: 72,4 + 2369: 73,3 + 2370: 75,3 + 2371: 76,3 + 2372: 78,3 + 2373: 79,3 + 2374: 81,3 + 2375: 83,4 + 2376: 84,2 + 2377: 85,3 + 2378: 86,4 + 2379: 83,7 + 2380: 80,7 + 2381: 78,6 + 2382: 76,8 + 2383: 77,9 + 2384: 80,9 + 2385: 83,9 + 2386: 82,12 + 2387: 82,13 + 2388: 83,14 + 2389: 83,14 + 2390: 83,13 + 2391: 75,13 + 2392: 75,15 + 2393: 76,15 + 2394: 76,14 + 2395: 76,9 + 2396: 76,6 + 2397: 77,6 + 2398: 83,6 + 2399: 83,8 + 2400: 84,3 + 2401: 67,2 + 2402: 66,4 + 2403: 61,2 + 2404: 58,4 + 2405: 57,3 + 2406: 56,2 + 2407: 52,4 + 2408: 51,3 + 2409: 53,-13 + 2410: 60,-20 + 2411: 62,-21 + 2412: 61,-22 + 2413: 60,-19 + 2414: 43,-16 + 2415: 41,-16 + 2416: 38,-16 + 2417: 37,-16 + 2418: 37,-19 + 2419: 37,-20 + 2420: 37,-20 + 2421: 36,-20 + 2422: 37,-20 + 2423: 37,-20 + 2424: 40,-19 + 2425: 40,-19 + 2426: 39,-19 + 2427: 40,-20 + 2428: 43,-19 + 2429: 43,-20 + 2430: 42,-20 + 2431: 45,-19 + 2432: 45,-20 + 2433: 45,-20 + 2434: 46,-20 + 2435: 38,-16 + 2436: 36,-14 + 2437: 35,-13 + 2438: 35,-11 + 2439: 34,-9 + 2440: 35,-7 + 2441: 36,-6 + 2442: 36,-4 + 2443: 36,-3 + 2444: 38,-5 + 2445: 40,-3 + 2446: 39,-3 + 2447: 41,-3 + 2448: 39,2 + 2449: 41,2 + 2450: 31,2 + 2451: 30,3 + 2452: 28,1 + 2453: 28,3 + 2454: 29,0 + 2455: 23,-7 + 2456: 28,-7 + 2457: 7,-16 + 2458: 7,-16 + 2459: 7,-17 + 2460: -9,-2 + 2461: -9,-1 + 2462: -8,-1 + 2463: -7,-1 + 2464: -6,-1 + 2465: -5,-2 + 2466: -5,-6 + 2467: -5,-15 + 2468: -4,-15 + 2469: -6,-19 + 2470: -5,-17 + 2471: -6,-20 + 2472: -4,-22 + 2473: -4,-24 + 2474: -5,-26 + 2475: -8,-26 + 2476: -9,-26 + 2477: -10,-25 + 2478: -11,-27 + 2479: -10,-28 + 2480: -7,-28 + 2481: -13,-25 + 2482: -14,-26 + 2483: -17,-26 + 2484: -19,-25 + 2485: -20,-27 + 2486: -22,-26 + 2487: -25,-26 + 2488: -26,-29 + 2489: -27,-30 + 2490: -26,-31 + 2491: -27,-31 + 2492: -27,-33 + 2493: -25,-34 + 2494: -26,-35 + 2495: -24,-35 + 2496: -23,-35 + 2497: -23,-34 + 2498: -27,-26 + 2499: -28,-26 + 2500: -31,-28 + 2501: -33,-28 + 2502: -37,-28 + 2503: -31,-28 + 2504: -31,-27 + 2505: -37,-28 + 2506: -31,-31 + 2507: -33,-32 + 2508: -34,-33 + 2509: -36,-32 + 2510: -37,-32 + 2511: -39,-33 + 2512: -37,-32 + 2513: -41,-31 + 2514: -42,-32 + 2515: -43,-32 + 2516: -45,-31 + 2517: -46,-32 + 2518: -46,-32 + 2519: -48,-31 + 2520: -49,-32 + 2521: -49,-32 + 2522: -50,-31 + 2523: -51,-32 + 2524: -52,-32 + 2525: -44,-33 2526: -42,-32 - 2527: -43,-32 - 2528: -45,-31 - 2529: -46,-32 - 2530: -46,-32 - 2531: -48,-31 - 2532: -49,-32 - 2533: -49,-32 - 2534: -50,-31 - 2535: -51,-32 - 2536: -52,-32 - 2537: -44,-33 - 2538: -42,-32 - 2539: -41,-31 - 2540: -39,-32 - 2541: -38,-33 - 2542: -37,-33 - 2543: -32,-33 - 2544: -37,-36 - 2545: -38,-37 - 2546: -39,-38 - 2547: -39,-39 - 2548: -40,-40 - 2549: -41,-39 - 2550: -40,-42 - 2551: -40,-44 - 2552: -35,-36 - 2553: -32,-37 - 2554: -31,-37 - 2555: -30,-38 - 2556: -31,-38 - 2557: -31,-39 - 2558: -30,-39 - 2559: -27,-41 - 2560: -27,-39 - 2561: -26,-39 - 2562: -23,-40 - 2563: -24,-41 - 2564: -26,-39 - 2565: -23,-39 - 2566: -24,-39 - 2567: -25,-39 - 2568: -25,-38 - 2569: -35,-41 - 2570: -35,-40 - 2571: -35,-39 - 2572: -39,-39 - 2573: -39,-37 - 2574: -37,-36 - 2575: -32,-36 - 2576: -32,-36 - 2577: -39,-36 - 2578: -49,-28 - 2579: -50,-27 - 2580: -52,-27 - 2581: -52,-28 - 2582: -51,-29 - 2583: -50,-29 - 2584: -50,-28 - 2585: -55,-32 - 2586: -56,-31 - 2587: -57,-31 - 2588: -57,-29 - 2589: -56,-29 - 2590: -55,-29 - 2591: -56,-25 - 2592: -55,-28 - 2593: -57,-27 - 2594: -57,-25 - 2595: -55,-26 - 2596: -55,-27 - 2597: -54,-22 - 2598: -55,-23 - 2599: -55,-23 - 2600: -56,-22 - 2601: -57,-23 - 2602: -59,-23 - 2603: -59,-23 - 2604: -60,-24 - 2605: -60,-25 - 2606: -61,-26 - 2607: -66,-26 - 2608: -64,-26 - 2609: -63,-26 - 2610: -61,-27 - 2611: -61,-29 - 2612: -60,-29 - 2613: -60,-31 - 2614: -60,-33 - 2615: -61,-33 - 2616: -61,-34 - 2617: -61,-36 - 2618: -61,-38 - 2619: -63,-36 - 2620: -64,-36 + 2527: -41,-31 + 2528: -39,-32 + 2529: -38,-33 + 2530: -37,-33 + 2531: -32,-33 + 2532: -39,-38 + 2533: -39,-39 + 2534: -41,-39 + 2535: -31,-37 + 2536: -31,-38 + 2537: -31,-39 + 2538: -27,-41 + 2539: -27,-39 + 2540: -26,-39 + 2541: -23,-40 + 2542: -24,-41 + 2543: -26,-39 + 2544: -23,-39 + 2545: -24,-39 + 2546: -25,-39 + 2547: -25,-38 + 2548: -35,-41 + 2549: -39,-39 + 2550: -39,-37 + 2551: -32,-36 + 2552: -32,-36 + 2553: -39,-36 + 2554: -49,-28 + 2555: -50,-27 + 2556: -52,-27 + 2557: -52,-28 + 2558: -51,-29 + 2559: -50,-29 + 2560: -50,-28 + 2561: -55,-32 + 2562: -56,-31 + 2563: -57,-31 + 2564: -57,-29 + 2565: -56,-29 + 2566: -55,-29 + 2567: -56,-25 + 2568: -55,-28 + 2569: -57,-27 + 2570: -57,-25 + 2571: -55,-26 + 2572: -55,-27 + 2573: -54,-22 + 2574: -55,-23 + 2575: -55,-23 + 2576: -56,-22 + 2577: -57,-23 + 2578: -59,-23 + 2579: -59,-23 + 2580: -60,-24 + 2581: -60,-25 + 2582: -61,-26 + 2583: -66,-26 + 2584: -64,-26 + 2585: -63,-26 + 2586: -61,-27 + 2587: -61,-29 + 2588: -60,-29 + 2589: -60,-31 + 2590: -60,-33 + 2591: -61,-33 + 2592: -61,-34 + 2593: -61,-36 + 2594: -61,-38 + 2595: -63,-36 + 2596: -64,-36 + 2597: -65,-36 + 2598: -65,-35 + 2599: -64,-34 + 2600: -63,-34 + 2601: -65,-34 + 2602: -65,-34 + 2603: -64,-35 + 2604: -64,-37 + 2605: -64,-37 + 2606: -64,-38 + 2607: -63,-37 + 2608: -63,-37 + 2609: -63,-38 + 2610: -64,-38 + 2611: -64,-37 + 2612: -65,-37 + 2613: -65,-36 + 2614: -64,-36 + 2615: -63,-36 + 2616: -64,-35 + 2617: -63,-34 + 2618: -64,-34 + 2619: -63,-34 + 2620: -64,-34 2621: -65,-36 - 2622: -65,-35 - 2623: -64,-34 - 2624: -63,-34 - 2625: -65,-34 - 2626: -65,-34 + 2622: -65,-37 + 2623: -63,-37 + 2624: -63,-38 + 2625: -65,-35 + 2626: -63,-35 2627: -64,-35 - 2628: -64,-37 - 2629: -64,-37 - 2630: -64,-38 - 2631: -63,-37 - 2632: -63,-37 - 2633: -63,-38 - 2634: -64,-38 - 2635: -64,-37 - 2636: -65,-37 - 2637: -65,-36 - 2638: -64,-36 - 2639: -63,-36 - 2640: -64,-35 - 2641: -63,-34 - 2642: -64,-34 - 2643: -63,-34 - 2644: -64,-34 - 2645: -65,-36 - 2646: -65,-37 - 2647: -63,-37 - 2648: -63,-38 - 2649: -65,-35 - 2650: -63,-35 - 2651: -64,-35 - 2652: -64,-35 - 2653: -63,-35 - 2654: -65,-35 - 2655: -61,-41 - 2656: -62,-41 - 2657: -63,-41 - 2658: -63,-43 - 2659: -63,-44 - 2660: -64,-45 - 2661: -66,-44 - 2662: -66,-44 - 2663: -66,-44 - 2664: -66,-43 - 2665: -59,-41 - 2666: -58,-41 - 2667: -58,-40 - 2668: -58,-39 - 2669: -57,-40 - 2670: -57,-43 - 2671: -59,-43 - 2672: -59,-43 - 2673: -60,-44 - 2674: -61,-44 - 2675: -36,-8 - 2676: -32,-12 - 2677: -37,-15 - 2678: -37,-16 - 2679: -38,-16 - 2680: -38,-16 - 2681: -36,-14 - 2682: -36,-16 - 2683: -37,-14 - 2684: -36,-15 - 2685: -32,-19 - 2686: -36,-19 - 2687: -37,-19 - 2688: -37,-21 - 2689: -35,-21 - 2690: -32,-22 - 2691: -33,-22 - 2692: -35,-23 - 2693: -36,-24 - 2694: -21,-8 - 2695: -20,-9 - 2696: -20,-10 - 2697: -24,-11 - 2698: -24,-13 - 2699: -21,-13 - 2700: -22,-16 - 2701: -24,-16 - 2702: -24,-17 - 2703: -23,-18 - 2704: -22,-18 - 2705: -24,-19 - 2706: -24,-20 - 2707: -23,-21 - 2708: -22,-21 - 2709: -26,-20 - 2710: -25,-18 - 2711: -25,-16 - 2712: -25,-15 - 2713: -21,-13 - 2714: -21,-15 - 2715: -21,-17 - 2716: -21,-18 - 2717: -22,-8 - 2718: -25,-10 - 2719: -25,-12 - 2720: -24,-12 - 2721: -24,-8 - 2722: -21,-10 - 2723: -22,-10 - 2724: -22,-13 - 2725: -8,-8 - 2726: -8,-10 - 2727: -8,-11 - 2728: -8,-13 - 2729: -8,-19 - 2730: -9,-17 - 2731: -11,-18 - 2732: -11,-18 - 2733: -11,-17 - 2734: -10,-16 - 2735: -8,-16 - 2736: -8,-17 - 2737: -10,-17 - 2738: -9,-18 - 2739: -8,-19 - 2740: -9,-20 - 2741: -8,-18 - 2742: -9,-17 - 2743: -10,-17 - 2744: -10,-18 - 2745: -9,-17 - 2746: -8,-18 - 2747: -9,-19 - 2748: -9,-19 - 2749: -4,-9 - 2750: -5,-11 - 2751: -4,-10 - 2752: -5,-12 - 2753: -5,-14 - 2754: -7,-25 - 2755: -7,-26 - 2756: -6,-28 - 2757: 18,-35 - 2758: -2,-34 - 2759: 12,-32 - 2760: 11,-32 - 2761: 11,-33 - 2762: 12,-33 - 2763: 13,-32 - 2764: 16,-32 - 2765: 17,-32 - 2766: 16,-32 - 2767: 17,-32 - 2768: 16,-32 - 2769: 17,-32 - 2770: 6,-32 - 2771: 7,-33 - 2772: 8,-32 - 2773: -3,-39 - 2774: -3,-39 - 2775: -2,-40 - 2776: -1,-39 - 2777: -1,-38 - 2778: -2,-33 - 2779: -3,-33 - 2780: -3,-32 - 2781: -2,-32 - 2782: -2,-33 - 2783: -3,-33 - 2784: -3,-32 - 2785: -2,-32 - 2786: 7,-45 - 2787: 7,-46 - 2788: 8,-46 - 2789: 9,-46 - 2790: 9,-45 - 2791: 8,-45 - 2792: 8,-46 - 2793: 9,-45 - 2794: 8,-46 - 2795: 13,-43 - 2796: 12,-43 - 2797: 13,-43 - 2798: 12,-43 - 2799: 11,-45 - 2800: 11,-43 - 2801: 11,-46 - 2802: 13,-45 - 2803: 13,-46 - 2804: 13,-45 - 2805: 13,-46 - 2806: 13,-48 - 2807: 14,-49 - 2808: 14,-50 - 2809: 15,-51 - 2810: 16,-50 - 2811: 17,-49 - 2812: 17,-49 - 2813: 16,-48 - 2814: 14,-48 - 2815: 16,-51 - 2816: 16,-52 - 2817: 20,-58 - 2818: 21,-58 - 2819: 20,-57 - 2820: 19,-56 - 2821: 20,-56 - 2822: 20,-54 - 2823: 19,-54 - 2824: 20,-52 - 2825: 19,-51 - 2826: 20,-50 - 2827: 21,-49 - 2828: 19,-48 - 2829: 21,-46 - 2830: 21,-45 - 2831: 19,-44 - 2832: 21,-46 - 2833: 20,-42 - 2834: 19,-41 - 2835: 21,-40 - 2836: 19,-39 - 2837: 21,-38 - 2838: 20,-37 - 2839: 19,-36 - 2840: 21,-35 - 2841: 19,-34 - 2842: 20,-41 - 2843: 20,-38 - 2844: 20,-38 - 2845: 23,-28 - 2846: 21,-29 - 2847: 20,-29 - 2848: 19,-28 - 2849: 25,-28 - 2850: 28,-28 - 2851: 30,-26 - 2852: 31,-26 - 2853: 18,-25 - 2854: 20,-26 - 2855: 21,-24 - 2856: 20,-21 - 2857: 19,-20 - 2858: 21,-21 - 2859: 18,-22 - 2860: 19,-23 - 2861: 20,-24 - 2862: 17,-24 - 2863: 17,-26 - 2864: 12,-24 - 2865: 13,-26 - 2866: 14,-24 - 2867: 10,-24 - 2868: 9,-25 - 2869: 7,-25 - 2870: 8,-26 - 2871: 6,-24 - 2872: 5,-27 - 2873: 4,-25 - 2874: 2,-26 - 2875: 2,-27 - 2876: -2,-24 - 2877: -3,-26 - 2878: -4,-26 - 2879: -5,-24 - 2880: 2,-24 - 2881: 0,-24 - 2882: 0,-26 - 2883: 2,-26 - 2884: 9,-26 - 2885: 11,-26 - 2886: 15,-24 - 2887: 14,-25 - 2888: 21,-26 - 2889: 20,-21 - 2890: 19,-20 - 2891: 19,-19 - 2892: 19,-18 - 2893: 19,-17 - 2894: 19,-11 - 2895: 20,-11 - 2896: 19,-11 - 2897: 20,-12 - 2898: 19,-11 - 2899: 18,-10 - 2900: 19,-7 - 2901: 19,-6 - 2902: 18,-5 - 2903: 22,-15 - 2904: 23,-15 - 2905: 25,-15 - 2906: 25,-14 - 2907: 25,-13 - 2908: 23,-12 - 2909: 22,-12 - 2910: 25,-12 - 2911: 27,-12 - 2912: 28,-13 - 2913: 30,-13 - 2914: 31,-13 - 2915: 31,-12 - 2916: 31,-11 - 2917: 31,-10 - 2918: 31,-8 - 2919: 31,-8 - 2920: 31,-7 - 2921: 31,-4 - 2922: 33,-4 - 2923: 33,-4 - 2924: 32,-5 - 2925: 30,-16 - 2926: 30,-18 - 2927: 31,-15 - 2928: 31,-16 - 2929: 33,-16 - 2930: 33,-15 - 2931: 32,-16 - 2932: 32,-15 - 2933: 51,9 - 2934: 48,9 - 2935: 45,9 - 2936: 42,9 - 2937: 42,8 - 2938: 38,8 - 2939: 35,24 - 2940: 37,24 - 2941: 35,27 - 2942: 35,28 - 2943: 36,30 - 2944: 31,31 - 2945: 32,32 - 2946: 31,35 - 2947: 32,35 - 2948: 33,36 - 2949: 31,39 - 2950: 31,42 - 2951: 33,41 - 2952: 32,40 - 2953: 32,39 - 2954: 0,53 - 2955: 0,52 - 2956: 0,51 - 2957: 0,49 - 2958: 2,51 - 2959: 0,55 - 2960: 1,55 - 2961: 1,59 - 2962: 2,61 - 2963: 1,61 - 2964: -2,61 - 2965: -2,59 - 2966: -1,56 - 2967: -38,51 - 2968: -42,51 - 2969: -45,48 - 2970: -45,45 - 2971: -41,46 - 2972: -37,46 - 2973: -38,44 - 2974: -42,44 - 2975: -44,43 - 2976: -41,41 - 2977: -36,41 - 2978: -35,41 - 2979: -42,40 - 2980: -46,40 - 2981: -39,40 - 2982: -35,41 - 2983: -39,42 - 2984: -45,43 - 2985: -35,44 - 2986: -34,45 - 2987: -42,45 - 2988: -37,47 - 2989: -34,47 - 2990: -44,48 - 2991: -38,49 - 2992: -35,50 - 2993: -43,50 - 2994: -33,51 - 2995: -36,49 - 2996: -43,48 - 2997: -39,48 - 2998: -33,47 - 2999: -39,46 - 3000: -45,45 - 3001: -39,44 - 3002: -34,43 - 3003: -36,41 - 3004: -41,41 - 3005: -41,41 - 3006: -34,40 - 3007: -36,41 - 3008: -39,41 - 3009: -32,41 - 3010: -32,41 - 3011: -31,44 - 3012: -31,48 - 3013: -31,51 - 3014: -28,45 - 3015: -26,45 - 3016: -28,41 - 3017: -26,41 - 3018: -24,41 - 3019: -23,39 - 3161: 50,-37 - 3162: 53,-37 - 3163: 56,-38 - 3164: 55,-38 - 3165: 54,-39 - 3166: 53,-40 - 3167: 53,-42 - 3168: 51,-45 - 3169: 51,-46 - 3170: 46,-47 - 3171: 46,-46 - 3172: 48,-43 - 3173: 46,-45 - 3174: 45,-46 - 3175: 43,-46 - 3176: 47,-43 - 3177: 52,-46 - 3178: 52,-42 - 3179: 53,-42 - 3180: 50,-42 - 3181: 50,-40 - 3182: 50,-37 - 3183: 52,-36 - 3184: 55,-37 - 3185: 55,-38 - 3186: 53,-40 - 3187: 53,-42 - 3188: 52,-45 - 3189: 50,-45 - 3190: 54,-47 - 3191: 51,-47 - 3192: 46,-47 - 3193: 45,-47 - 3194: 44,-46 - 3195: 44,-44 - 3679: -5,-1 - 4596: 28,54 - 4597: 27,55 - 4598: 27,56 - 4599: 26,56 - 4600: 26,55 - 4601: 26,54 - 4602: 27,54 - 4603: 28,52 - 4604: 27,51 - 4605: 28,53 + 2628: -64,-35 + 2629: -63,-35 + 2630: -65,-35 + 2631: -61,-41 + 2632: -62,-41 + 2633: -63,-41 + 2634: -63,-43 + 2635: -63,-44 + 2636: -64,-45 + 2637: -66,-44 + 2638: -66,-44 + 2639: -66,-44 + 2640: -66,-43 + 2641: -59,-41 + 2642: -58,-41 + 2643: -58,-40 + 2644: -58,-39 + 2645: -57,-40 + 2646: -57,-43 + 2647: -59,-43 + 2648: -59,-43 + 2649: -60,-44 + 2650: -61,-44 + 2651: -36,-8 + 2652: -32,-12 + 2653: -37,-15 + 2654: -37,-16 + 2655: -38,-16 + 2656: -38,-16 + 2657: -36,-14 + 2658: -36,-16 + 2659: -37,-14 + 2660: -36,-15 + 2661: -32,-19 + 2662: -36,-19 + 2663: -37,-19 + 2664: -37,-21 + 2665: -35,-21 + 2666: -32,-22 + 2667: -33,-22 + 2668: -35,-23 + 2669: -36,-24 + 2670: -21,-8 + 2671: -20,-9 + 2672: -20,-10 + 2673: -24,-11 + 2674: -24,-13 + 2675: -21,-13 + 2676: -22,-16 + 2677: -24,-16 + 2678: -24,-17 + 2679: -23,-18 + 2680: -22,-18 + 2681: -24,-19 + 2682: -24,-20 + 2683: -23,-21 + 2684: -22,-21 + 2685: -26,-20 + 2686: -25,-18 + 2687: -25,-16 + 2688: -25,-15 + 2689: -21,-13 + 2690: -21,-15 + 2691: -21,-17 + 2692: -21,-18 + 2693: -22,-8 + 2694: -25,-10 + 2695: -25,-12 + 2696: -24,-12 + 2697: -24,-8 + 2698: -21,-10 + 2699: -22,-10 + 2700: -22,-13 + 2701: -8,-8 + 2702: -8,-10 + 2703: -8,-11 + 2704: -8,-13 + 2705: -8,-19 + 2706: -9,-17 + 2707: -11,-18 + 2708: -11,-18 + 2709: -11,-17 + 2710: -10,-16 + 2711: -8,-16 + 2712: -8,-17 + 2713: -10,-17 + 2714: -9,-18 + 2715: -8,-19 + 2716: -9,-20 + 2717: -8,-18 + 2718: -9,-17 + 2719: -10,-17 + 2720: -10,-18 + 2721: -9,-17 + 2722: -8,-18 + 2723: -9,-19 + 2724: -9,-19 + 2725: -4,-9 + 2726: -5,-11 + 2727: -4,-10 + 2728: -5,-12 + 2729: -5,-14 + 2730: -7,-25 + 2731: -7,-26 + 2732: -6,-28 + 2733: 18,-35 + 2734: -2,-34 + 2735: 12,-32 + 2736: 11,-32 + 2737: 11,-33 + 2738: 12,-33 + 2739: 13,-32 + 2740: 16,-32 + 2741: 17,-32 + 2742: 16,-32 + 2743: 17,-32 + 2744: 16,-32 + 2745: 17,-32 + 2746: 6,-32 + 2747: 7,-33 + 2748: 8,-32 + 2749: -3,-39 + 2750: -3,-39 + 2751: -2,-40 + 2752: -1,-39 + 2753: -1,-38 + 2754: -2,-33 + 2755: -3,-33 + 2756: -3,-32 + 2757: -2,-32 + 2758: -2,-33 + 2759: -3,-33 + 2760: -3,-32 + 2761: -2,-32 + 2762: 7,-45 + 2763: 7,-46 + 2764: 8,-46 + 2765: 9,-46 + 2766: 9,-45 + 2767: 8,-45 + 2768: 8,-46 + 2769: 9,-45 + 2770: 8,-46 + 2771: 13,-43 + 2772: 12,-43 + 2773: 13,-43 + 2774: 12,-43 + 2775: 11,-45 + 2776: 11,-43 + 2777: 11,-46 + 2778: 13,-45 + 2779: 13,-46 + 2780: 13,-45 + 2781: 13,-46 + 2782: 13,-48 + 2783: 14,-49 + 2784: 14,-50 + 2785: 15,-51 + 2786: 16,-50 + 2787: 17,-49 + 2788: 17,-49 + 2789: 16,-48 + 2790: 14,-48 + 2791: 16,-51 + 2792: 16,-52 + 2793: 20,-58 + 2794: 21,-58 + 2795: 20,-57 + 2796: 19,-56 + 2797: 20,-56 + 2798: 20,-54 + 2799: 19,-54 + 2800: 20,-52 + 2801: 19,-51 + 2802: 20,-50 + 2803: 21,-49 + 2804: 19,-48 + 2805: 21,-46 + 2806: 21,-45 + 2807: 19,-44 + 2808: 21,-46 + 2809: 20,-42 + 2810: 19,-41 + 2811: 21,-40 + 2812: 19,-39 + 2813: 21,-38 + 2814: 20,-37 + 2815: 19,-36 + 2816: 21,-35 + 2817: 19,-34 + 2818: 20,-41 + 2819: 20,-38 + 2820: 20,-38 + 2821: 23,-28 + 2822: 21,-29 + 2823: 20,-29 + 2824: 19,-28 + 2825: 25,-28 + 2826: 28,-28 + 2827: 30,-26 + 2828: 31,-26 + 2829: 18,-25 + 2830: 20,-26 + 2831: 21,-24 + 2832: 20,-21 + 2833: 19,-20 + 2834: 21,-21 + 2835: 18,-22 + 2836: 19,-23 + 2837: 20,-24 + 2838: 17,-24 + 2839: 17,-26 + 2840: 12,-24 + 2841: 13,-26 + 2842: 14,-24 + 2843: 10,-24 + 2844: 9,-25 + 2845: 7,-25 + 2846: 8,-26 + 2847: 6,-24 + 2848: 5,-27 + 2849: 4,-25 + 2850: 2,-26 + 2851: 2,-27 + 2852: -2,-24 + 2853: -3,-26 + 2854: -4,-26 + 2855: -5,-24 + 2856: 2,-24 + 2857: 0,-24 + 2858: 0,-26 + 2859: 2,-26 + 2860: 9,-26 + 2861: 11,-26 + 2862: 15,-24 + 2863: 14,-25 + 2864: 21,-26 + 2865: 20,-21 + 2866: 19,-20 + 2867: 19,-19 + 2868: 19,-18 + 2869: 19,-17 + 2870: 19,-11 + 2871: 20,-11 + 2872: 19,-11 + 2873: 20,-12 + 2874: 19,-11 + 2875: 18,-10 + 2876: 19,-7 + 2877: 19,-6 + 2878: 18,-5 + 2879: 22,-15 + 2880: 23,-15 + 2881: 25,-15 + 2882: 25,-14 + 2883: 25,-13 + 2884: 23,-12 + 2885: 22,-12 + 2886: 25,-12 + 2887: 27,-12 + 2888: 28,-13 + 2889: 30,-13 + 2890: 31,-13 + 2891: 31,-12 + 2892: 31,-11 + 2893: 31,-10 + 2894: 31,-8 + 2895: 31,-8 + 2896: 31,-7 + 2897: 31,-4 + 2898: 33,-4 + 2899: 33,-4 + 2900: 32,-5 + 2901: 30,-16 + 2902: 30,-18 + 2903: 31,-15 + 2904: 31,-16 + 2905: 33,-16 + 2906: 33,-15 + 2907: 32,-16 + 2908: 32,-15 + 2909: 51,9 + 2910: 48,9 + 2911: 45,9 + 2912: 42,9 + 2913: 42,8 + 2914: 38,8 + 2915: 35,24 + 2916: 37,24 + 2917: 35,27 + 2918: 35,28 + 2919: 36,30 + 2920: 31,31 + 2921: 32,32 + 2922: 31,35 + 2923: 32,35 + 2924: 33,36 + 2925: 31,39 + 2926: 31,42 + 2927: 33,41 + 2928: 32,40 + 2929: 32,39 + 2930: 0,53 + 2931: 0,52 + 2932: 0,51 + 2933: 0,49 + 2934: 2,51 + 2935: 0,55 + 2936: 1,55 + 2937: 1,59 + 2938: 2,61 + 2939: 1,61 + 2940: -2,61 + 2941: -2,59 + 2942: -1,56 + 2943: -38,51 + 2944: -42,51 + 2945: -45,48 + 2946: -45,45 + 2947: -41,46 + 2948: -37,46 + 2949: -38,44 + 2950: -42,44 + 2951: -44,43 + 2952: -41,41 + 2953: -36,41 + 2954: -35,41 + 2955: -42,40 + 2956: -46,40 + 2957: -39,40 + 2958: -35,41 + 2959: -39,42 + 2960: -45,43 + 2961: -35,44 + 2962: -34,45 + 2963: -42,45 + 2964: -37,47 + 2965: -34,47 + 2966: -44,48 + 2967: -38,49 + 2968: -35,50 + 2969: -43,50 + 2970: -33,51 + 2971: -36,49 + 2972: -43,48 + 2973: -39,48 + 2974: -33,47 + 2975: -39,46 + 2976: -45,45 + 2977: -39,44 + 2978: -34,43 + 2979: -36,41 + 2980: -41,41 + 2981: -41,41 + 2982: -34,40 + 2983: -36,41 + 2984: -39,41 + 2985: -32,41 + 2986: -32,41 + 2987: -31,44 + 2988: -31,48 + 2989: -31,51 + 2990: -28,45 + 2991: -26,45 + 2992: -28,41 + 2993: -26,41 + 2994: -24,41 + 2995: -23,39 + 3137: 50,-37 + 3138: 53,-37 + 3139: 56,-38 + 3140: 55,-38 + 3141: 54,-39 + 3142: 53,-40 + 3143: 53,-42 + 3144: 51,-45 + 3145: 51,-46 + 3146: 46,-47 + 3147: 46,-46 + 3148: 48,-43 + 3149: 46,-45 + 3150: 45,-46 + 3151: 43,-46 + 3152: 47,-43 + 3153: 52,-46 + 3154: 52,-42 + 3155: 53,-42 + 3156: 50,-42 + 3157: 50,-40 + 3158: 50,-37 + 3159: 52,-36 + 3160: 55,-37 + 3161: 55,-38 + 3162: 53,-40 + 3163: 53,-42 + 3164: 52,-45 + 3165: 50,-45 + 3166: 54,-47 + 3167: 51,-47 + 3168: 46,-47 + 3169: 45,-47 + 3170: 44,-46 + 3171: 44,-44 + 3572: -5,-1 + 4417: 28,54 + 4418: 27,55 + 4419: 27,56 + 4420: 26,56 + 4421: 26,55 + 4422: 26,54 + 4423: 27,54 + 4424: 28,52 + 4425: 27,51 + 4426: 28,53 - node: cleanable: True color: '#FFFFFFFF' id: Dirt decals: - 3315: -65,-33 - - node: - cleanable: True - color: '#8354328B' - id: DirtHeavy - decals: - 4811: -49,-35 - 4812: -49,-37 - 4813: -51,-37 + 3291: -65,-33 - node: cleanable: True color: '#835432B7' id: DirtHeavy decals: - 4746: -28,-13 - 4747: -31,-11 - 4748: -30,-11 - 4749: -37,-10 - 4750: -37,-8 - 4751: -39,-8 - 4752: -38,-12 - 4753: -38,-11 - 4754: -36,-11 - 4755: -34,-15 - 4756: -34,-16 - 4757: -33,-15 - 4758: -32,-16 - 4759: -31,-16 - 4760: -31,-15 - 4761: -30,-15 + 4547: -28,-13 + 4548: -31,-11 + 4549: -30,-11 + 4550: -37,-10 + 4551: -37,-8 + 4552: -39,-8 + 4553: -38,-12 + 4554: -38,-11 + 4555: -36,-11 + 4556: -34,-15 + 4557: -34,-16 + 4558: -33,-15 + 4559: -32,-16 + 4560: -31,-16 + 4561: -31,-15 + 4562: -30,-15 - node: cleanable: True color: '#A4610696' id: DirtHeavy decals: - 3020: -20,45 - 3021: -20,52 - 3022: -21,35 - 3023: -19,37 - 3024: -19,35 - 3025: -20,35 - 3026: -11,40 - 3027: -10,44 - 3028: -10,48 - 3029: -15,48 - 3030: -5,43 - 3031: -2,50 - 3032: 5,50 - 3033: 12,50 - 3034: 15,55 - 3035: 18,58 - 3036: 19,63 - 3037: 23,67 - 3038: 33,47 - 3039: 31,40 - 3040: 26,35 - 3041: 33,31 - 3042: 32,25 - 3043: 31,22 - 3044: 36,23 - 3045: 37,27 - 3046: 42,30 - 3047: 43,27 - 3048: 44,21 - 3049: 42,16 - 3050: 41,13 - 3051: 43,15 - 3052: 44,19 - 3053: 32,8 - 3054: 27,7 - 3055: 40,3 - 3056: 46,3 - 3057: 56,3 - 3058: 64,3 - 3059: 70,3 - 3060: 73,3 - 3061: 83,3 - 3062: 83,10 - 3063: 76,9 - 3064: 80,6 - 3065: 53,-2 - 3066: 46,-16 - 3067: 38,-12 - 3068: 35,-6 - 3069: 32,-4 - 3070: 26,-5 - 3071: 21,-4 - 3072: 12,-4 - 3073: -5,-4 - 3074: -34,-4 - 3075: -41,-5 - 3076: -46,-33 - 3077: -36,-33 - 3078: -32,-36 - 3079: -39,-39 - 3080: -29,-38 - 3081: -26,-39 - 3082: -24,-35 - 3083: -26,-30 - 3084: -23,-26 - 3085: -17,-26 - 3086: -8,-27 - 3087: -5,-31 - 3088: -6,-37 - 3089: -6,-43 - 3090: -6,-48 - 3091: -6,-53 - 3092: -5,-57 - 3093: 5,-53 - 3094: 3,-53 - 3095: 6,-52 - 3096: 5,-52 - 3097: 4,-52 - 3098: 5,-53 - 3099: 6,-53 - 3100: 28,-27 - 3101: -8,-1 - 3102: -31,-4 - 3103: -25,-17 - 3104: -26,1 - 3105: -23,13 - 3106: -21,19 - 3107: -17,20 - 3108: -13,20 - 3109: -18,14 - 3110: -13,14 - 3111: -23,26 - 3112: -23,30 - 3113: -31,30 - 3114: -42,29 - 3115: -50,30 - 3116: -50,29 - 3117: -56,29 - 3118: -58,35 - 3119: -57,44 - 3120: -58,49 - 3121: -64,43 - 3122: -63,38 - 3123: -52,31 - 3124: -40,29 - 3125: -29,30 - 3126: -22,30 - 3127: -21,32 - 3128: -20,37 - 3129: -20,42 - 3130: -19,51 - 3131: -25,54 - 3132: -27,53 - 3133: -11,47 - 3134: -9,45 - 3135: -5,47 - 3136: 4,50 - 3137: 7,49 - 3138: 16,49 - 3139: 23,50 - 3140: 26,50 - 3141: 19,54 - 3142: 19,63 - 3143: 23,68 - 3144: 32,43 - 3145: 32,36 - 3146: 32,29 - 3147: 32,22 - 3148: 32,19 - 3149: 33,9 - 3150: 33,20 - 3151: 31,26 - 3152: 33,35 - 3153: 15,30 - 3154: 8,30 - 3155: 0,30 - 3156: -8,9 - 3157: -4,10 - 3158: 20,15 - 3159: 21,9 - 3160: 29,4 - 3196: 52,-43 - 3197: 50,-47 - 3198: 45,-46 - 3199: 46,-43 - 3200: 52,-40 - 3201: 55,-37 - 3202: 55,-38 - 3203: 47,-45 - 3204: 44,-47 - 3205: 54,-47 - 3206: 53,-47 - 4606: 27,55 - 4607: 28,52 + 2996: -20,45 + 2997: -20,52 + 2998: -21,35 + 2999: -19,37 + 3000: -19,35 + 3001: -20,35 + 3002: -11,40 + 3003: -10,44 + 3004: -10,48 + 3005: -15,48 + 3006: -5,43 + 3007: -2,50 + 3008: 5,50 + 3009: 12,50 + 3010: 15,55 + 3011: 18,58 + 3012: 19,63 + 3013: 23,67 + 3014: 33,47 + 3015: 31,40 + 3016: 26,35 + 3017: 33,31 + 3018: 32,25 + 3019: 31,22 + 3020: 36,23 + 3021: 37,27 + 3022: 42,30 + 3023: 43,27 + 3024: 44,21 + 3025: 42,16 + 3026: 41,13 + 3027: 43,15 + 3028: 44,19 + 3029: 32,8 + 3030: 27,7 + 3031: 40,3 + 3032: 46,3 + 3033: 56,3 + 3034: 64,3 + 3035: 70,3 + 3036: 73,3 + 3037: 83,3 + 3038: 83,10 + 3039: 76,9 + 3040: 80,6 + 3041: 53,-2 + 3042: 46,-16 + 3043: 38,-12 + 3044: 35,-6 + 3045: 32,-4 + 3046: 26,-5 + 3047: 21,-4 + 3048: 12,-4 + 3049: -5,-4 + 3050: -34,-4 + 3051: -41,-5 + 3052: -46,-33 + 3053: -36,-33 + 3054: -32,-36 + 3055: -39,-39 + 3056: -29,-38 + 3057: -26,-39 + 3058: -24,-35 + 3059: -26,-30 + 3060: -23,-26 + 3061: -17,-26 + 3062: -8,-27 + 3063: -5,-31 + 3064: -6,-37 + 3065: -6,-43 + 3066: -6,-48 + 3067: -6,-53 + 3068: -5,-57 + 3069: 5,-53 + 3070: 3,-53 + 3071: 6,-52 + 3072: 5,-52 + 3073: 4,-52 + 3074: 5,-53 + 3075: 6,-53 + 3076: 28,-27 + 3077: -8,-1 + 3078: -31,-4 + 3079: -25,-17 + 3080: -26,1 + 3081: -23,13 + 3082: -21,19 + 3083: -17,20 + 3084: -13,20 + 3085: -18,14 + 3086: -13,14 + 3087: -23,26 + 3088: -23,30 + 3089: -31,30 + 3090: -42,29 + 3091: -50,30 + 3092: -50,29 + 3093: -56,29 + 3094: -58,35 + 3095: -57,44 + 3096: -58,49 + 3097: -64,43 + 3098: -63,38 + 3099: -52,31 + 3100: -40,29 + 3101: -29,30 + 3102: -22,30 + 3103: -21,32 + 3104: -20,37 + 3105: -20,42 + 3106: -19,51 + 3107: -25,54 + 3108: -27,53 + 3109: -11,47 + 3110: -9,45 + 3111: -5,47 + 3112: 4,50 + 3113: 7,49 + 3114: 16,49 + 3115: 23,50 + 3116: 26,50 + 3117: 19,54 + 3118: 19,63 + 3119: 23,68 + 3120: 32,43 + 3121: 32,36 + 3122: 32,29 + 3123: 32,22 + 3124: 32,19 + 3125: 33,9 + 3126: 33,20 + 3127: 31,26 + 3128: 33,35 + 3129: 15,30 + 3130: 8,30 + 3131: 0,30 + 3132: -8,9 + 3133: -4,10 + 3134: 20,15 + 3135: 21,9 + 3136: 29,4 + 3172: 52,-43 + 3173: 50,-47 + 3174: 45,-46 + 3175: 46,-43 + 3176: 52,-40 + 3177: 55,-37 + 3178: 55,-38 + 3179: 47,-45 + 3180: 44,-47 + 3181: 54,-47 + 3182: 53,-47 + 4427: 27,55 + 4428: 28,52 - node: cleanable: True color: '#8354328B' id: DirtLight decals: - 4804: -33,-8 - 4805: -32,-8 - 4806: -30,-7 - 4807: -29,-8 - 4814: -51,-35 - 4815: -49,-35 - 4816: -49,-37 + 4605: -33,-8 + 4606: -32,-8 + 4607: -30,-7 + 4608: -29,-8 - node: cleanable: True color: '#FFFFFFFF' id: DirtLight decals: - 3312: -65,-33 - 3313: -64,-33 - 3314: -63,-33 + 3288: -65,-33 + 3289: -64,-33 + 3290: -63,-33 - node: cleanable: True color: '#8354328B' id: DirtMedium decals: - 4808: -28,-8 - 4809: -28,-9 - 4810: -30,-9 - 4817: -51,-37 - 4818: -49,-35 + 4609: -28,-8 + 4610: -28,-9 + 4611: -30,-9 - node: cleanable: True color: '#835432B7' id: DirtMedium decals: - 4762: -31,-15 - 4763: -29,-15 - 4764: -28,-14 - 4765: -30,-11 - 4766: -32,-11 - 4767: -38,-13 - 4768: -38,-11 - 4769: -39,-8 - 4770: -28,-12 + 4563: -31,-15 + 4564: -29,-15 + 4565: -28,-14 + 4566: -30,-11 + 4567: -32,-11 + 4568: -38,-13 + 4569: -38,-11 + 4570: -39,-8 + 4571: -28,-12 - node: color: '#9FED58B7' id: FlowersBROne decals: - 4990: -2.6908832,47.53326 + 4771: -2.6908832,47.53326 - node: color: '#9FED5873' id: Flowersbr1 decals: - 3339: 78.72238,7.9556513 - 3340: 79.69461,7.9278736 + 3315: 78.72238,7.9556513 + 3316: 79.69461,7.9278736 - node: color: '#FFFFFFE3' id: Flowersbr1 decals: - 4665: -19.119284,3.6234694 - 4666: -19.829224,1.4664211 + 4486: -19.119284,3.6234694 + 4487: -19.829224,1.4664211 - node: color: '#FFFFFFFF' id: Flowersbr1 decals: - 3379: -17.368574,-37.531387 + 3355: -17.368574,-37.531387 - node: color: '#FFFFFFE3' id: Flowersbr2 decals: - 4667: -19.900217,3.027443 - 4668: -19.005693,2.0766392 + 4488: -19.900217,3.027443 + 4489: -19.005693,2.0766392 - node: color: '#FFFFFFFF' id: Flowersbr2 decals: - 3382: -15.424128,-36.586945 + 3358: -15.424128,-36.586945 - node: color: '#9FED58B7' id: Flowersbr3 decals: - 4989: -1.1716373,46.099934 + 4770: -1.1716373,46.099934 - node: color: '#FFFFFFE3' id: Flowersbr3 decals: - 4669: -19.886019,-0.0094537735 - 4670: -18.82111,0.8136306 + 4490: -19.886019,-0.0094537735 + 4491: -18.82111,0.8136306 - node: color: '#FFFFFFFF' id: Flowersbr3 decals: - 3383: -16.14635,-36.989723 - 3409: -60.04891,40.960167 - 3410: -60.00724,39.210167 - 3411: -60.02113,42.890724 + 3359: -16.14635,-36.989723 + 3385: -60.04891,40.960167 + 3386: -60.00724,39.210167 + 3387: -60.02113,42.890724 - node: color: '#9FED58B7' id: Flowerspv1 decals: - 4988: -2.7477016,46.156727 - 4991: -2.7050896,47.10753 - 4992: -1.4556177,45.858692 + 4769: -2.7477016,46.156727 + 4772: -2.7050896,47.10753 + 4773: -1.4556177,45.858692 - node: color: '#A4DF8296' id: Flowerspv1 decals: - 1714: -7.423552,-22.998676 - 1715: -8.506886,-23.19312 - 1716: -8.8402195,-23.776455 - 1717: -7.2846637,-23.80423 - 1718: -7.3957734,-22.05423 + 1702: -7.423552,-22.998676 + 1703: -8.506886,-23.19312 + 1704: -8.8402195,-23.776455 + 1705: -7.2846637,-23.80423 + 1706: -7.3957734,-22.05423 - node: color: '#FFFFFFE3' id: Flowerspv1 decals: - 4672: -19.928616,2.0766392 + 4493: -19.928616,2.0766392 - node: color: '#9FED5896' id: Flowerspv2 decals: - 3245: -40.505478,-22.24596 - 3246: -40.186035,-23.329292 - 3247: -41.505478,-22.968182 + 3221: -40.505478,-22.24596 + 3222: -40.186035,-23.329292 + 3223: -41.505478,-22.968182 - node: color: '#FFFFFFE3' id: Flowerspv2 decals: - 4671: -19.04829,0.0047369003 - 4673: -18.877905,2.8429594 - 4676: -18.82111,1.3387012 - 4681: -20.028008,-0.22232056 + 4492: -19.04829,0.0047369003 + 4494: -18.877905,2.8429594 + 4497: -18.82111,1.3387012 + 4502: -20.028008,-0.22232056 - node: color: '#FFFFFFFF' id: Flowerspv2 decals: - 3380: -15.688017,-37.836945 + 3356: -15.688017,-37.836945 - node: color: '#9FED5896' id: Flowerspv3 decals: - 3248: -43.172146,-21.537628 - 3249: -40.94992,-18.676516 - 3250: -40.061035,-18.162628 - 3251: -40.436035,-19.176516 - 3252: -43.061035,-17.85707 - 3253: -43.158257,-19.662628 - 3254: -40.99159,-23.49596 + 3224: -43.172146,-21.537628 + 3225: -40.94992,-18.676516 + 3226: -40.061035,-18.162628 + 3227: -40.436035,-19.176516 + 3228: -43.061035,-17.85707 + 3229: -43.158257,-19.662628 + 3230: -40.99159,-23.49596 - node: color: '#FFFFFFE3' id: Flowerspv3 decals: - 4674: -20.0848,3.8505278 - 4675: -19.786627,0.6575284 + 4495: -20.0848,3.8505278 + 4496: -19.786627,0.6575284 - node: color: '#FFFFFFFF' id: Flowerspv3 decals: - 3381: -17.27135,-36.48972 - 3406: -60.00724,38.321278 - 3407: -59.965576,40.001835 - 3408: -59.965576,41.821278 + 3357: -17.27135,-36.48972 + 3382: -60.00724,38.321278 + 3383: -59.965576,40.001835 + 3384: -59.965576,41.821278 - node: color: '#60E25873' id: Flowersy1 decals: - 3398: -60.062798,38.779613 - 3399: -59.965576,40.112946 - 3400: -59.97946,41.404613 + 3374: -60.062798,38.779613 + 3375: -59.965576,40.112946 + 3376: -59.97946,41.404613 - node: color: '#9FED5896' id: Flowersy1 decals: - 3241: -42.811035,-21.551517 - 3242: -42.99159,-18.176516 - 3243: -40.811035,-22.218182 - 3244: -42.894367,-22.87096 + 3217: -42.811035,-21.551517 + 3218: -42.99159,-18.176516 + 3219: -40.811035,-22.218182 + 3220: -42.894367,-22.87096 - node: color: '#A4DF8296' id: Flowersy1 decals: - 1711: -7.4791064,-22.526455 - 1712: -9.145773,-22.720898 - 1713: -8.673552,-23.748676 + 1699: -7.4791064,-22.526455 + 1700: -9.145773,-22.720898 + 1701: -8.673552,-23.748676 - node: color: '#FFFFFFE3' id: Flowersy1 decals: - 4677: -19.005693,3.8079538 + 4498: -19.005693,3.8079538 - node: color: '#FFFFFFE3' id: Flowersy2 decals: - 4678: -19.729832,2.999061 + 4499: -19.729832,2.999061 - node: color: '#9FED5896' id: Flowersy3 decals: - 3239: -41.672146,-22.10707 - 3240: -40.172146,-23.204292 + 3215: -41.672146,-22.10707 + 3216: -40.172146,-23.204292 - node: color: '#FFFFFFE3' id: Flowersy3 decals: - 4679: -19.332266,2.1475945 + 4500: -19.332266,2.1475945 - node: color: '#60E25873' id: Flowersy4 decals: - 3393: -59.937798,42.696278 - 3394: -59.99335,41.751835 - 3395: -60.00724,40.571278 - 3396: -60.062798,39.418503 - 3397: -59.965576,38.085167 + 3369: -59.937798,42.696278 + 3370: -59.99335,41.751835 + 3371: -60.00724,40.571278 + 3372: -60.062798,39.418503 + 3373: -59.965576,38.085167 - node: color: '#9FED5896' id: Flowersy4 decals: - 3236: -40.24159,-18.343182 - 3237: -41.172146,-18.63485 - 3238: -40.283257,-19.10707 + 3212: -40.24159,-18.343182 + 3213: -41.172146,-18.63485 + 3214: -40.283257,-19.10707 - node: color: '#FFFFFFE3' id: Flowersy4 decals: - 4680: -19.687237,1.0832615 + 4501: -19.687237,1.0832615 - node: color: '#D4D4D428' id: FullTileOverlayGreyscale decals: - 5023: 86,-2 - 5024: 85,-2 - 5025: 85,1 - 5026: 86,1 - 5027: 73,1 - 5028: 72,1 - 5029: 72,-2 - 5030: 73,-2 + 4804: 86,-2 + 4805: 85,-2 + 4806: 85,1 + 4807: 86,1 + 4808: 73,1 + 4809: 72,1 + 4810: 72,-2 + 4811: 73,-2 - node: color: '#A4DF8296' id: Grassa4 decals: - 1695: -7.8109317,-1.9877326 + 1683: -7.8109317,-1.9877326 - node: color: '#FFFFFF85' id: Grassd3 decals: - 4655: -19.488453,1.96311 - 4656: -18.70752,2.7436213 - 4657: -18.892103,0.898777 - 4658: -19.829224,-0.023644924 - 4659: -20.0848,2.4456081 - 4660: -20.311981,-0.37842274 + 4476: -19.488453,1.96311 + 4477: -18.70752,2.7436213 + 4478: -18.892103,0.898777 + 4479: -19.829224,-0.023644924 + 4480: -20.0848,2.4456081 + 4481: -20.311981,-0.37842274 - node: color: '#60E25873' id: Grasse1 decals: - 3384: -17.39635,-36.50361 - 3385: -15.813017,-36.434166 - 3386: -15.2157955,-36.545277 - 3387: -15.729685,-37.656387 - 3388: -17.590796,-37.531387 - 3389: -16.063017,-36.961945 - 3390: -15.674128,-37.948055 - 3391: -14.951906,-37.128613 - 3392: -15.229685,-38.073055 + 3360: -17.39635,-36.50361 + 3361: -15.813017,-36.434166 + 3362: -15.2157955,-36.545277 + 3363: -15.729685,-37.656387 + 3364: -17.590796,-37.531387 + 3365: -16.063017,-36.961945 + 3366: -15.674128,-37.948055 + 3367: -14.951906,-37.128613 + 3368: -15.229685,-38.073055 - node: color: '#FFFFFF85' id: Grasse1 decals: - 4661: -20.269386,0.16083956 - 4662: -18.792713,3.3112655 - 4663: -19.147682,2.431417 - 4664: -18.806911,4.205305 + 4482: -20.269386,0.16083956 + 4483: -18.792713,3.3112655 + 4484: -19.147682,2.431417 + 4485: -18.806911,4.205305 - node: color: '#60FF5D92' id: Grasse2 decals: - 4682: -20.0848,0.047310352 - 4683: -19.729832,0.99811506 - 4684: -18.906303,2.4172258 - 4685: -18.9347,3.7937632 - 4686: -19.985409,4.077585 - 4687: -20.028008,2.6726656 - 4688: -19.062489,1.1967907 - 4689: -19.957012,0.88458633 + 4503: -20.0848,0.047310352 + 4504: -19.729832,0.99811506 + 4505: -18.906303,2.4172258 + 4506: -18.9347,3.7937632 + 4507: -19.985409,4.077585 + 4508: -20.028008,2.6726656 + 4509: -19.062489,1.1967907 + 4510: -19.957012,0.88458633 - node: color: '#FFFFFF85' id: Grasse2 decals: - 4652: -19.034092,3.6092787 - 4653: -19.729832,3.0700169 - 4654: -20.0848,2.1475945 + 4473: -19.034092,3.6092787 + 4474: -19.729832,3.0700169 + 4475: -20.0848,2.1475945 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale decals: - 1236: -62,55 - 1237: -61,55 - 1238: -60,55 - 1239: -59,55 - 1240: -58,55 + 1224: -62,55 + 1225: -61,55 + 1226: -60,55 + 1227: -59,55 + 1228: -58,55 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale @@ -4388,144 +4342,143 @@ entities: 291: -51,-31 292: -52,-31 293: -53,-31 - 301: -36,-42 - 302: -35,-42 - 303: -34,-42 - 304: -33,-42 - 305: -32,-42 - 306: -31,-42 - 307: -30,-42 - 515: -41,-38 + 297: -32,-42 + 298: -31,-42 + 299: -30,-42 + 503: -41,-38 + 4886: -35,-42 + 4887: -34,-42 + 4888: -33,-42 - node: color: '#A4610696' id: HalfTileOverlayGreyscale decals: - 1051: 35,30 - 1052: 36,30 - 1053: 37,30 - 1060: 39,24 - 1061: 40,24 - 1062: 41,24 - 1063: 42,30 - 1064: 43,30 - 1065: 46,30 - 1066: 47,30 - 1073: 44,30 - 1074: 45,30 - 1519: 35,34 - 1520: 36,34 - 1521: 37,34 - 1522: 38,34 - 1523: 39,34 - 1524: 40,34 - 1525: 41,34 - 1526: 42,37 - 1527: 43,37 - 1528: 44,37 - 1529: 45,37 - 1530: 46,37 - 1531: 47,37 + 1039: 35,30 + 1040: 36,30 + 1041: 37,30 + 1048: 39,24 + 1049: 40,24 + 1050: 41,24 + 1051: 42,30 + 1052: 43,30 + 1053: 46,30 + 1054: 47,30 + 1061: 44,30 + 1062: 45,30 + 1507: 35,34 + 1508: 36,34 + 1509: 37,34 + 1510: 38,34 + 1511: 39,34 + 1512: 40,34 + 1513: 41,34 + 1514: 42,37 + 1515: 43,37 + 1516: 44,37 + 1517: 45,37 + 1518: 46,37 + 1519: 47,37 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale decals: - 1251: -54,31 - 1252: -53,31 - 1253: -52,31 - 1254: -51,31 - 1255: -50,31 - 1256: -49,31 - 1257: -48,31 - 1258: -47,31 - 1259: -46,31 - 1260: -45,31 - 1261: -44,31 - 1262: -43,31 - 1263: -42,31 - 1264: -41,31 - 1265: -40,31 - 1266: -39,31 - 1267: -38,31 - 1268: -37,31 - 1269: -36,31 - 1270: -35,31 - 1326: 17,31 - 1327: 16,31 - 1328: 15,31 - 1329: 14,31 - 1330: 13,31 - 1331: 12,31 - 1332: 11,31 - 1333: 9,31 - 1334: 8,31 - 1335: 7,31 - 1336: 5,31 - 1337: 4,31 - 1338: 3,31 - 1339: 2,31 - 1340: 1,31 - 1341: 0,31 - 1342: -1,31 - 1343: -2,31 - 1344: -3,31 + 1239: -54,31 + 1240: -53,31 + 1241: -52,31 + 1242: -51,31 + 1243: -50,31 + 1244: -49,31 + 1245: -48,31 + 1246: -47,31 + 1247: -46,31 + 1248: -45,31 + 1249: -44,31 + 1250: -43,31 + 1251: -42,31 + 1252: -41,31 + 1253: -40,31 + 1254: -39,31 + 1255: -38,31 + 1256: -37,31 + 1257: -36,31 + 1258: -35,31 + 1314: 17,31 + 1315: 16,31 + 1316: 15,31 + 1317: 14,31 + 1318: 13,31 + 1319: 12,31 + 1320: 11,31 + 1321: 9,31 + 1322: 8,31 + 1323: 7,31 + 1324: 5,31 + 1325: 4,31 + 1326: 3,31 + 1327: 2,31 + 1328: 1,31 + 1329: 0,31 + 1330: -1,31 + 1331: -2,31 + 1332: -3,31 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale decals: - 782: -11,-25 - 783: -10,-25 - 784: -9,-25 - 785: -8,-25 - 786: -7,-25 - 821: -16,-3 - 822: -14,-3 - 823: -12,-3 - 824: -11,-3 - 829: 17,-3 - 830: 18,-3 - 831: 20,-3 - 832: 21,-3 - 833: 23,-3 - 834: 24,-3 - 835: 25,-3 - 836: 26,-3 - 875: 22,-31 - 876: 23,-31 - 877: 24,-31 - 911: 35,4 - 912: 36,4 - 913: 37,4 - 914: 38,4 - 915: 39,4 - 916: 40,4 - 917: 41,4 - 918: 42,4 - 919: 43,4 - 920: 44,4 - 921: 45,4 - 922: 46,4 - 923: 47,4 - 924: 48,4 - 925: 49,4 - 926: 50,4 - 927: 51,4 - 928: 52,4 - 929: 53,4 - 930: 55,4 - 931: 56,4 - 932: 57,4 - 933: 58,4 - 934: 59,4 - 935: 60,4 - 936: 61,4 - 937: 62,4 - 938: 63,4 - 939: 64,4 - 940: 65,4 - 941: 66,4 - 942: 67,4 - 943: 68,4 - 944: 69,4 + 770: -11,-25 + 771: -10,-25 + 772: -9,-25 + 773: -8,-25 + 774: -7,-25 + 809: -16,-3 + 810: -14,-3 + 811: -12,-3 + 812: -11,-3 + 817: 17,-3 + 818: 18,-3 + 819: 20,-3 + 820: 21,-3 + 821: 23,-3 + 822: 24,-3 + 823: 25,-3 + 824: 26,-3 + 863: 22,-31 + 864: 23,-31 + 865: 24,-31 + 899: 35,4 + 900: 36,4 + 901: 37,4 + 902: 38,4 + 903: 39,4 + 904: 40,4 + 905: 41,4 + 906: 42,4 + 907: 43,4 + 908: 44,4 + 909: 45,4 + 910: 46,4 + 911: 47,4 + 912: 48,4 + 913: 49,4 + 914: 50,4 + 915: 51,4 + 916: 52,4 + 917: 53,4 + 918: 55,4 + 919: 56,4 + 920: 57,4 + 921: 58,4 + 922: 59,4 + 923: 60,4 + 924: 61,4 + 925: 62,4 + 926: 63,4 + 927: 64,4 + 928: 65,4 + 929: 66,4 + 930: 67,4 + 931: 68,4 + 932: 69,4 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale @@ -4535,44 +4488,44 @@ entities: 251: -25,-38 252: -24,-38 253: -23,-38 - 350: 38,-3 - 351: 39,-3 - 352: 40,-3 - 353: 41,-3 - 354: 42,-3 - 355: 43,-3 - 356: 44,-3 - 357: 45,-3 - 358: 46,-3 - 403: 34,-7 - 516: -32,27 - 517: -31,27 - 518: -30,27 - 519: -28,27 - 520: -27,27 - 521: -26,27 - 531: -29,26 - 1220: -64,51 - 1221: -63,51 - 1222: -61,51 - 1475: 36,51 - 1476: 37,51 - 1614: 60,-19 - 1615: 61,-19 - 1616: 62,-19 + 338: 38,-3 + 339: 39,-3 + 340: 40,-3 + 341: 41,-3 + 342: 42,-3 + 343: 43,-3 + 344: 44,-3 + 345: 45,-3 + 346: 46,-3 + 391: 34,-7 + 504: -32,27 + 505: -31,27 + 506: -30,27 + 507: -28,27 + 508: -27,27 + 509: -26,27 + 519: -29,26 + 1208: -64,51 + 1209: -63,51 + 1210: -61,51 + 1463: 36,51 + 1464: 37,51 + 1602: 60,-19 + 1603: 61,-19 + 1604: 62,-19 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale decals: - 615: -18,45 - 616: -17,45 - 617: -16,45 - 618: -15,45 - 619: -14,45 - 620: -13,45 - 621: -12,45 - 622: -11,45 - 623: -10,45 + 603: -18,45 + 604: -17,45 + 605: -16,45 + 606: -15,45 + 607: -14,45 + 608: -13,45 + 609: -12,45 + 610: -11,45 + 611: -10,45 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale180 @@ -4599,195 +4552,194 @@ entities: 267: -48,-33 268: -50,-33 269: -52,-33 - 294: -33,-45 - 295: -34,-45 - 296: -35,-45 - 297: -36,-45 - 298: -32,-45 - 299: -31,-45 - 300: -30,-45 - 312: -32,-33 - 313: -33,-33 - 314: -37,-33 - 315: -38,-33 - 316: -44,-33 - 317: -49,-33 - 318: -51,-33 - 319: -53,-33 - 1510: -43,-33 + 294: -32,-45 + 295: -31,-45 + 296: -30,-45 + 300: -32,-33 + 301: -33,-33 + 302: -37,-33 + 303: -38,-33 + 304: -44,-33 + 305: -49,-33 + 306: -51,-33 + 307: -53,-33 + 1498: -43,-33 + 4883: -33,-45 + 4884: -34,-45 + 4885: -35,-45 - node: color: '#A4610696' id: HalfTileOverlayGreyscale180 decals: - 1048: 35,23 - 1049: 36,23 - 1050: 37,23 - 1067: 47,26 - 1068: 46,26 - 1532: 44,32 - 1533: 45,32 - 1534: 43,32 - 1535: 42,32 - 1536: 41,32 - 1537: 40,32 - 1538: 39,32 - 1539: 38,32 - 1540: 37,32 - 1541: 36,32 - 1542: 35,32 - 1543: 46,32 - 1544: 47,32 + 1036: 35,23 + 1037: 36,23 + 1038: 37,23 + 1055: 47,26 + 1056: 46,26 + 1520: 44,32 + 1521: 45,32 + 1522: 43,32 + 1523: 42,32 + 1524: 41,32 + 1525: 40,32 + 1526: 39,32 + 1527: 38,32 + 1528: 37,32 + 1529: 36,32 + 1530: 35,32 + 1531: 46,32 + 1532: 47,32 - node: color: '#D381C996' id: HalfTileOverlayGreyscale180 decals: - 971: 21,66 - 972: 22,66 - 986: 23,66 - 987: 24,66 + 959: 21,66 + 960: 22,66 + 974: 23,66 + 975: 24,66 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale180 decals: - 1182: -25,29 - 1183: -26,29 - 1184: -27,29 - 1185: -28,29 - 1186: -29,29 - 1187: -30,29 - 1188: -31,29 - 1189: -32,29 - 1190: -33,29 - 1191: -36,29 - 1192: -37,29 - 1193: -38,29 - 1194: -39,29 - 1195: -42,29 - 1196: -43,29 - 1197: -44,29 - 1198: -45,29 - 1199: -46,29 - 1200: -48,29 - 1201: -49,29 - 1202: -50,29 - 1203: -51,29 - 1204: -52,29 - 1205: -53,29 - 1206: -54,29 - 1207: -56,29 - 1208: -57,29 - 1288: -21,29 - 1289: -20,29 - 1290: -19,29 - 1291: -18,29 - 1292: -17,29 - 1293: -16,29 - 1294: -15,29 - 1295: -14,29 - 1296: -13,29 - 1297: -12,29 - 1298: -11,29 - 1299: -10,29 - 1300: -9,29 - 1301: -8,29 - 1302: -5,29 - 1303: -3,30 - 1304: -2,30 - 1305: -1,30 - 1306: 0,30 - 1307: 1,30 - 1308: 2,30 - 1309: 3,30 - 1310: 4,30 - 1311: 5,30 - 1312: 6,30 - 1313: 7,30 - 1314: 8,30 - 1315: 9,30 - 1316: 10,30 - 1317: 11,30 - 1318: 12,30 - 1319: 13,30 - 1320: 14,30 - 1321: 15,30 - 1322: 16,30 - 1323: 17,30 - 1360: -3,49 - 1361: -2,49 - 1362: -1,49 - 1363: 0,49 - 1364: 1,49 - 1365: 2,49 - 1366: 4,49 - 1367: 5,49 - 1368: 6,49 - 1369: 7,49 - 1370: 8,49 - 1371: 9,49 - 1372: 10,49 - 1373: 11,49 - 1374: 12,49 - 1375: 13,49 - 1376: 11,49 - 1377: 13,49 - 1378: 14,49 - 1379: 15,49 - 1380: 16,49 - 1381: 17,49 - 1382: 18,49 - 1383: 19,49 - 1384: 21,49 - 1385: 22,49 - 1386: 23,49 - 1387: 25,49 - 1388: 26,49 - 1389: 24,49 - 1390: 27,49 - 1391: 29,49 - 1392: 28,49 - 1393: 20,49 + 1170: -25,29 + 1171: -26,29 + 1172: -27,29 + 1173: -28,29 + 1174: -29,29 + 1175: -30,29 + 1176: -31,29 + 1177: -32,29 + 1178: -33,29 + 1179: -36,29 + 1180: -37,29 + 1181: -38,29 + 1182: -39,29 + 1183: -42,29 + 1184: -43,29 + 1185: -44,29 + 1186: -45,29 + 1187: -46,29 + 1188: -48,29 + 1189: -49,29 + 1190: -50,29 + 1191: -51,29 + 1192: -52,29 + 1193: -53,29 + 1194: -54,29 + 1195: -56,29 + 1196: -57,29 + 1276: -21,29 + 1277: -20,29 + 1278: -19,29 + 1279: -18,29 + 1280: -17,29 + 1281: -16,29 + 1282: -15,29 + 1283: -14,29 + 1284: -13,29 + 1285: -12,29 + 1286: -11,29 + 1287: -10,29 + 1288: -9,29 + 1289: -8,29 + 1290: -5,29 + 1291: -3,30 + 1292: -2,30 + 1293: -1,30 + 1294: 0,30 + 1295: 1,30 + 1296: 2,30 + 1297: 3,30 + 1298: 4,30 + 1299: 5,30 + 1300: 6,30 + 1301: 7,30 + 1302: 8,30 + 1303: 9,30 + 1304: 10,30 + 1305: 11,30 + 1306: 12,30 + 1307: 13,30 + 1308: 14,30 + 1309: 15,30 + 1310: 16,30 + 1311: 17,30 + 1348: -3,49 + 1349: -2,49 + 1350: -1,49 + 1351: 0,49 + 1352: 1,49 + 1353: 2,49 + 1354: 4,49 + 1355: 5,49 + 1356: 6,49 + 1357: 7,49 + 1358: 8,49 + 1359: 9,49 + 1360: 10,49 + 1361: 11,49 + 1362: 12,49 + 1363: 13,49 + 1364: 11,49 + 1365: 13,49 + 1366: 14,49 + 1367: 15,49 + 1368: 16,49 + 1369: 17,49 + 1370: 18,49 + 1371: 19,49 + 1372: 21,49 + 1373: 22,49 + 1374: 23,49 + 1375: 25,49 + 1376: 26,49 + 1377: 24,49 + 1378: 27,49 + 1379: 29,49 + 1380: 28,49 + 1381: 20,49 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale180 decals: - 771: -4,-26 - 772: -3,-26 - 773: 17,-26 - 774: 18,-26 - 775: -8,-28 - 776: -9,-28 - 777: -10,-28 - 778: -11,-28 - 804: -7,-5 - 805: -9,-5 - 806: -10,-5 - 807: -11,-5 - 808: -13,-5 - 809: -14,-5 - 810: -15,-5 - 811: -16,-5 - 812: -17,-5 - 813: -19,-5 - 814: -22,-5 - 815: -23,-5 - 816: -24,-5 - 817: -40,-5 - 841: 28,-5 - 842: 27,-5 - 843: 26,-5 - 844: 25,-5 - 845: 24,-5 - 846: 23,-5 - 847: 22,-5 - 848: 21,-5 - 878: 24,-36 - 879: 23,-36 - 880: 22,-36 - 945: 65,2 - 946: 66,2 - 947: 67,2 - 948: 68,2 - 949: 69,2 + 759: -4,-26 + 760: -3,-26 + 761: 17,-26 + 762: 18,-26 + 763: -8,-28 + 764: -9,-28 + 765: -10,-28 + 766: -11,-28 + 792: -7,-5 + 793: -9,-5 + 794: -10,-5 + 795: -11,-5 + 796: -13,-5 + 797: -14,-5 + 798: -15,-5 + 799: -16,-5 + 800: -17,-5 + 801: -19,-5 + 802: -22,-5 + 803: -23,-5 + 804: -24,-5 + 805: -40,-5 + 829: 28,-5 + 830: 27,-5 + 831: 26,-5 + 832: 25,-5 + 833: 24,-5 + 834: 23,-5 + 835: 22,-5 + 836: 21,-5 + 866: 24,-36 + 867: 23,-36 + 868: 22,-36 + 933: 65,2 + 934: 66,2 + 935: 67,2 + 936: 68,2 + 937: 69,2 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale180 @@ -4795,798 +4747,688 @@ entities: 239: -26,-40 240: -23,-41 254: -24,-41 - 345: 44,-1 - 346: 45,-1 - 347: 46,-1 - 389: 46,-17 - 390: 45,-17 - 391: 44,-17 - 392: 43,-17 - 393: 42,-17 - 394: 41,-17 - 395: 40,-17 - 396: 39,-17 - 397: 38,-17 - 398: 37,-17 - 522: -32,25 - 523: -31,25 - 524: -30,25 - 525: -29,25 - 526: -28,25 - 527: -27,25 - 528: -26,25 - 1227: -63,48 - 1231: -62,48 - 1478: 36,48 - 1479: 37,48 - 1617: 60,-23 - 1618: 61,-23 - 1619: 62,-23 + 333: 44,-1 + 334: 45,-1 + 335: 46,-1 + 377: 46,-17 + 378: 45,-17 + 379: 44,-17 + 380: 43,-17 + 381: 42,-17 + 382: 41,-17 + 383: 40,-17 + 384: 39,-17 + 385: 38,-17 + 386: 37,-17 + 510: -32,25 + 511: -31,25 + 512: -30,25 + 513: -29,25 + 514: -28,25 + 515: -27,25 + 516: -26,25 + 1215: -63,48 + 1219: -62,48 + 1466: 36,48 + 1467: 37,48 + 1605: 60,-23 + 1606: 61,-23 + 1607: 62,-23 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale180 decals: - 624: -10,43 - 625: -11,43 - 626: -12,43 - 627: -13,43 - 628: -14,43 - 629: -15,43 - 630: -16,43 - 631: -17,43 - 632: -18,43 + 612: -10,43 + 613: -11,43 + 614: -12,43 + 615: -13,43 + 616: -14,43 + 617: -15,43 + 618: -16,43 + 619: -17,43 + 620: -18,43 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale270 decals: - 1241: -63,54 - 1242: -63,53 - 1551: 18,-60 - 1552: 17,-61 - 1553: 17,-62 - 1554: 18,-63 + 1229: -63,54 + 1230: -63,53 + 1539: 18,-60 + 1540: 17,-61 + 1541: 17,-62 + 1542: 18,-63 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale270 decals: 227: -26,-26 - 310: -36,-39 - 311: -36,-40 + 4961: -36,-37 + 4962: -35,-37 + 4963: -34,-37 + 4964: -35,-36 + 4965: -35,-38 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale270 decals: - 1511: -8,-60 - 1512: -9,-61 - 1513: -9,-62 - 1514: -8,-63 + 1499: -8,-60 + 1500: -9,-61 + 1501: -9,-62 + 1502: -8,-63 - node: color: '#A4610696' id: HalfTileOverlayGreyscale270 decals: - 1069: 40,21 - 1070: 40,18 - 1071: 40,19 - 1072: 40,20 - 1082: 41,17 - 1083: 41,16 - 1084: 41,15 - 1085: 41,14 - 1086: 41,13 - 1087: 41,12 + 1057: 40,21 + 1058: 40,18 + 1059: 40,19 + 1060: 40,20 + 1070: 41,17 + 1071: 41,16 + 1072: 41,15 + 1073: 41,14 + 1074: 41,13 + 1075: 41,12 - node: color: '#D381C996' id: HalfTileOverlayGreyscale270 decals: - 959: 18,54 - 960: 18,57 - 961: 18,58 - 962: 18,59 - 963: 18,60 - 964: 18,61 - 965: 18,62 - 966: 18,63 - 967: 18,64 - 968: 18,65 - 969: 18,66 + 947: 18,54 + 948: 18,57 + 949: 18,58 + 950: 18,59 + 951: 18,60 + 952: 18,61 + 953: 18,62 + 954: 18,63 + 955: 18,64 + 956: 18,65 + 957: 18,66 - node: color: '#D4D4D40F' id: HalfTileOverlayGreyscale270 decals: - 4941: -28,18 - 4942: -28,17 + 4722: -28,18 + 4723: -28,17 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale270 decals: - 1154: -24,-1 - 1155: -24,0 - 1156: -24,1 - 1157: -24,2 - 1158: -24,3 - 1159: -24,4 - 1160: -24,5 - 1161: -24,6 - 1162: -24,7 - 1163: -24,8 - 1164: -24,10 - 1165: -24,11 - 1166: -24,12 - 1167: -24,13 - 1168: -24,14 - 1169: -24,15 - 1170: -24,16 - 1171: -24,18 - 1172: -24,19 - 1173: -24,20 - 1174: -24,21 - 1175: -24,22 - 1176: -24,23 - 1177: -24,24 - 1178: -24,26 - 1179: -24,27 - 1210: -58,30 - 1211: -58,31 - 1212: -58,32 + 1142: -24,-1 + 1143: -24,0 + 1144: -24,1 + 1145: -24,2 + 1146: -24,3 + 1147: -24,4 + 1148: -24,5 + 1149: -24,6 + 1150: -24,7 + 1151: -24,8 + 1152: -24,10 + 1153: -24,11 + 1154: -24,12 + 1155: -24,13 + 1156: -24,14 + 1157: -24,15 + 1158: -24,16 + 1159: -24,18 + 1160: -24,19 + 1161: -24,20 + 1162: -24,21 + 1163: -24,22 + 1164: -24,23 + 1165: -24,24 + 1166: -24,26 + 1167: -24,27 + 1198: -58,30 + 1199: -58,31 + 1200: -58,32 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale270 decals: - 740: -7,-30 - 741: -7,-31 - 742: -7,-32 - 743: -7,-36 - 744: -7,-37 - 745: -7,-38 - 746: -7,-39 - 747: -7,-40 - 748: -7,-41 - 749: -7,-45 - 750: -7,-47 - 751: -7,-48 - 752: -7,-49 - 753: -7,-51 - 754: -7,-53 - 755: -7,-54 - 756: -7,-55 - 757: -7,-56 - 758: -7,-57 - 759: -7,-58 - 788: -6,-24 - 789: -6,-23 - 790: -6,-22 - 791: -6,-20 - 792: -6,-19 - 793: -6,-18 - 794: -6,-16 - 795: -6,-15 - 796: -6,-13 - 797: -6,-12 - 798: -6,-11 - 799: -6,-10 - 800: -6,-9 - 801: -6,-8 - 802: -6,-6 - 904: 19,-57 - 905: 19,-56 - 906: 19,-55 - 907: 19,-54 + 728: -7,-30 + 729: -7,-31 + 730: -7,-32 + 731: -7,-36 + 732: -7,-37 + 733: -7,-38 + 734: -7,-39 + 735: -7,-40 + 736: -7,-41 + 737: -7,-45 + 738: -7,-47 + 739: -7,-48 + 740: -7,-49 + 741: -7,-51 + 742: -7,-53 + 743: -7,-54 + 744: -7,-55 + 745: -7,-56 + 746: -7,-57 + 747: -7,-58 + 776: -6,-24 + 777: -6,-23 + 778: -6,-22 + 779: -6,-20 + 780: -6,-19 + 781: -6,-18 + 782: -6,-16 + 783: -6,-15 + 784: -6,-13 + 785: -6,-12 + 786: -6,-11 + 787: -6,-10 + 788: -6,-9 + 789: -6,-8 + 790: -6,-6 + 892: 19,-57 + 893: 19,-56 + 894: 19,-55 + 895: 19,-54 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale270 decals: 245: -28,-40 246: -28,-39 - 342: 43,1 - 343: 43,0 - 344: 43,-1 - 360: 35,-3 - 361: 35,-4 - 362: 35,-5 - 363: 35,-6 - 364: 33,-7 - 365: 33,-8 - 366: 34,-9 - 367: 34,-10 - 368: 34,-11 - 369: 34,-12 - 370: 34,-13 - 371: 35,-14 - 372: 35,-15 - 373: 36,-16 - 374: 36,-17 - 530: -32,26 - 1228: -64,49 - 1229: -64,50 - 1473: 35,49 - 1474: 35,50 + 330: 43,1 + 331: 43,0 + 332: 43,-1 + 348: 35,-3 + 349: 35,-4 + 350: 35,-5 + 351: 35,-6 + 352: 33,-7 + 353: 33,-8 + 354: 34,-9 + 355: 34,-10 + 356: 34,-11 + 357: 34,-12 + 358: 34,-13 + 359: 35,-14 + 360: 35,-15 + 361: 36,-16 + 362: 36,-17 + 518: -32,26 + 1216: -64,49 + 1217: -64,50 + 1461: 35,49 + 1462: 35,50 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale270 decals: - 595: -21,54 - 596: -21,53 - 597: -21,52 - 598: -21,51 - 599: -21,50 - 600: -21,49 - 601: -21,48 - 602: -21,47 - 603: -21,46 - 604: -21,45 - 605: -21,44 - 606: -21,43 - 607: -21,42 - 608: -21,41 - 609: -21,40 - 610: -21,39 - 611: -21,38 - 612: -21,37 - 613: -21,36 - 614: -21,35 + 583: -21,54 + 584: -21,53 + 585: -21,52 + 586: -21,51 + 587: -21,50 + 588: -21,49 + 589: -21,48 + 590: -21,47 + 591: -21,46 + 592: -21,45 + 593: -21,44 + 594: -21,43 + 595: -21,42 + 596: -21,41 + 597: -21,40 + 598: -21,39 + 599: -21,38 + 600: -21,37 + 601: -21,36 + 602: -21,35 - node: color: '#334E6DC8' id: HalfTileOverlayGreyscale90 decals: - 1243: -57,54 - 1244: -57,53 - 1547: 23,-61 - 1548: 23,-62 - 1549: 22,-63 - 1550: 22,-60 + 1231: -57,54 + 1232: -57,53 + 1535: 23,-61 + 1536: 23,-62 + 1537: 22,-63 + 1538: 22,-60 - node: color: '#52B4E996' id: HalfTileOverlayGreyscale90 decals: - 308: -34,-39 - 309: -34,-40 + 4966: -36,-37 + 4967: -35,-36 + 4968: -35,-37 + 4969: -35,-38 + 4970: -34,-37 - node: color: '#9FED5896' id: HalfTileOverlayGreyscale90 decals: - 1515: -4,-60 - 1516: -3,-61 - 1517: -3,-62 - 1518: -4,-63 + 1503: -4,-60 + 1504: -3,-61 + 1505: -3,-62 + 1506: -4,-63 - node: color: '#A4610696' id: HalfTileOverlayGreyscale90 decals: - 1075: 45,25 - 1076: 45,24 - 1077: 45,21 - 1078: 45,20 - 1079: 45,19 - 1080: 44,17 - 1081: 44,16 - 1088: 43,12 - 1089: 43,14 - 1090: 43,13 - 1091: 43,15 - 1637: 45,22 - 1638: 45,23 + 1063: 45,25 + 1064: 45,24 + 1065: 45,21 + 1066: 45,20 + 1067: 45,19 + 1068: 44,17 + 1069: 44,16 + 1076: 43,12 + 1077: 43,14 + 1078: 43,13 + 1079: 43,15 + 1625: 45,22 + 1626: 45,23 - node: color: '#D381C996' id: HalfTileOverlayGreyscale90 decals: - 950: 20,56 - 951: 20,57 - 952: 20,58 - 953: 20,59 - 954: 20,61 - 955: 20,62 - 956: 20,63 - 957: 20,64 - 958: 20,65 - 989: 24,67 - 990: 24,68 - 991: 24,70 + 938: 20,56 + 939: 20,57 + 940: 20,58 + 941: 20,59 + 942: 20,61 + 943: 20,62 + 944: 20,63 + 945: 20,64 + 946: 20,65 + 977: 24,67 + 978: 24,68 + 979: 24,70 - node: color: '#D4D4D405' id: HalfTileOverlayGreyscale90 decals: - 4943: -29,18 - 4944: -29,17 + 4724: -29,18 + 4725: -29,17 - node: color: '#D4D4D419' id: HalfTileOverlayGreyscale90 decals: - 1136: -22,5 - 1137: -22,7 - 1138: -22,8 - 1139: -22,9 - 1140: -22,10 - 1141: -22,11 - 1142: -22,12 - 1143: -22,13 - 1144: -22,14 - 1145: -22,15 - 1146: -22,17 - 1147: -22,20 - 1148: -22,22 - 1149: -22,23 - 1150: -22,24 - 1151: -22,25 - 1152: -22,26 - 1153: -22,27 - 1214: -56,32 - 1215: -56,33 - 1345: -4,33 - 1346: -4,34 - 1347: -4,36 - 1348: -4,37 - 1349: -4,38 - 1350: -4,39 - 1351: -4,40 - 1352: -4,41 - 1353: -4,42 - 1354: -4,44 - 1355: -4,45 - 1356: -4,46 - 1357: -4,47 - 1358: -4,48 - 4939: -28,18 - 4940: -28,17 + 1124: -22,5 + 1125: -22,7 + 1126: -22,8 + 1127: -22,9 + 1128: -22,10 + 1129: -22,11 + 1130: -22,12 + 1131: -22,13 + 1132: -22,14 + 1133: -22,15 + 1134: -22,17 + 1135: -22,20 + 1136: -22,22 + 1137: -22,23 + 1138: -22,24 + 1139: -22,25 + 1140: -22,26 + 1141: -22,27 + 1202: -56,32 + 1203: -56,33 + 1333: -4,33 + 1334: -4,34 + 1335: -4,36 + 1336: -4,37 + 1337: -4,38 + 1338: -4,39 + 1339: -4,40 + 1340: -4,41 + 1341: -4,42 + 1342: -4,44 + 1343: -4,45 + 1344: -4,46 + 1345: -4,47 + 1346: -4,48 + 4720: -28,18 + 4721: -28,17 - node: color: '#D4D4D433' id: HalfTileOverlayGreyscale90 decals: - 760: -5,-58 - 761: -5,-57 - 762: -5,-56 - 763: -5,-55 - 764: -5,-54 - 765: -5,-53 - 766: -5,-51 - 767: -5,-50 - 768: -5,-28 - 769: -5,-27 - 819: -41,-11 - 838: 29,-3 - 839: 29,-4 - 850: 20,-6 - 851: 20,-8 - 852: 20,-9 - 853: 20,-10 - 854: 20,-11 - 855: 20,-12 - 856: 20,-14 - 857: 20,-15 - 858: 20,-16 - 861: 21,-18 - 862: 21,-19 - 863: 21,-20 - 864: 21,-21 - 865: 21,-22 - 866: 21,-23 - 867: 21,-24 - 868: 21,-25 - 869: 21,-26 - 870: 21,-27 - 871: 21,-28 - 872: 21,-29 - 873: 21,-30 - 882: 21,-38 - 883: 21,-39 - 884: 21,-40 - 885: 21,-41 - 886: 21,-42 - 887: 21,-43 - 888: 21,-44 - 889: 21,-45 - 890: 21,-46 - 891: 21,-47 - 892: 21,-48 - 893: 21,-49 - 894: 21,-50 - 895: 21,-51 - 896: 21,-52 - 897: 21,-53 - 898: 21,-54 - 899: 21,-55 - 900: 21,-56 - 901: 21,-57 - 908: 29,-1 - 909: 29,0 - 910: 29,1 + 748: -5,-58 + 749: -5,-57 + 750: -5,-56 + 751: -5,-55 + 752: -5,-54 + 753: -5,-53 + 754: -5,-51 + 755: -5,-50 + 756: -5,-28 + 757: -5,-27 + 807: -41,-11 + 826: 29,-3 + 827: 29,-4 + 838: 20,-6 + 839: 20,-8 + 840: 20,-9 + 841: 20,-10 + 842: 20,-11 + 843: 20,-12 + 844: 20,-14 + 845: 20,-15 + 846: 20,-16 + 849: 21,-18 + 850: 21,-19 + 851: 21,-20 + 852: 21,-21 + 853: 21,-22 + 854: 21,-23 + 855: 21,-24 + 856: 21,-25 + 857: 21,-26 + 858: 21,-27 + 859: 21,-28 + 860: 21,-29 + 861: 21,-30 + 870: 21,-38 + 871: 21,-39 + 872: 21,-40 + 873: 21,-41 + 874: 21,-42 + 875: 21,-43 + 876: 21,-44 + 877: 21,-45 + 878: 21,-46 + 879: 21,-47 + 880: 21,-48 + 881: 21,-49 + 882: 21,-50 + 883: 21,-51 + 884: 21,-52 + 885: 21,-53 + 886: 21,-54 + 887: 21,-55 + 888: 21,-56 + 889: 21,-57 + 896: 29,-1 + 897: 29,0 + 898: 29,1 - node: color: '#DE3A3A96' id: HalfTileOverlayGreyscale90 decals: 247: -22,-40 248: -22,-39 - 339: 47,1 - 340: 47,0 - 341: 47,-1 - 375: 46,-11 - 376: 46,-10 - 377: 46,-9 - 378: 46,-8 - 379: 46,-7 - 380: 47,-6 - 381: 47,-5 - 382: 47,-4 - 529: -26,26 - 1224: -61,50 - 1225: -61,49 - 1467: 38,51 - 1468: 38,50 - 1469: 38,49 - 1620: 46,-16 - 1621: 46,-13 + 327: 47,1 + 328: 47,0 + 329: 47,-1 + 363: 46,-11 + 364: 46,-10 + 365: 46,-9 + 366: 46,-8 + 367: 46,-7 + 368: 47,-6 + 369: 47,-5 + 370: 47,-4 + 517: -26,26 + 1212: -61,50 + 1213: -61,49 + 1455: 38,51 + 1456: 38,50 + 1457: 38,49 + 1608: 46,-16 + 1609: 46,-13 - node: color: '#EFB34196' id: HalfTileOverlayGreyscale90 decals: - 578: -19,35 - 579: -19,36 - 580: -19,37 - 581: -19,38 - 582: -19,39 - 583: -19,40 - 584: -19,41 - 585: -19,42 - 586: -19,46 - 587: -19,47 - 588: -19,48 - 589: -19,49 - 590: -19,50 - 591: -19,51 - 592: -19,52 - 593: -19,53 - 594: -19,54 + 566: -19,35 + 567: -19,36 + 568: -19,37 + 569: -19,38 + 570: -19,39 + 571: -19,40 + 572: -19,41 + 573: -19,42 + 574: -19,46 + 575: -19,47 + 576: -19,48 + 577: -19,49 + 578: -19,50 + 579: -19,51 + 580: -19,52 + 581: -19,53 + 582: -19,54 - node: color: '#EFB34196' id: LoadingArea decals: - 501: 75,10 - 502: 76,10 + 489: 75,10 + 490: 76,10 - node: angle: 3.141592653589793 rad color: '#EFB34196' id: LoadingArea decals: - 503: 82,10 - 504: 83,10 + 491: 82,10 + 492: 83,10 - node: angle: 4.71238898038469 rad color: '#EFB34196' id: LoadingArea decals: - 1059: 36,29 - 1216: -64,46 - 1217: -64,40 - 1218: -64,38 - 1232: -64,48 + 1047: 36,29 + 1204: -64,46 + 1205: -64,40 + 1206: -64,38 + 1220: -64,48 - node: color: '#334E6DC8' id: LoadingAreaGreyscale decals: - 510: -5,-2 + 498: -5,-2 - node: angle: 3.141592653589793 rad color: '#334E6DC8' id: LoadingAreaGreyscale decals: - 511: -9,-2 + 499: -9,-2 - node: color: '#52B4E996' id: MiniTileCheckerAOverlay decals: - 3728: 26,-35 - 3729: 27,-35 - 3730: 28,-35 - 3731: 29,-35 - 3732: 30,-35 - 3733: 30,-34 - 3734: 29,-34 - 3735: 28,-34 - 3736: 27,-34 - 3737: 26,-34 - 3738: 26,-33 - 3739: 26,-32 - 3740: 27,-32 - 3741: 28,-32 - 3742: 29,-32 - 3743: 30,-32 - 3744: 30,-33 - 3745: 29,-33 - 3746: 28,-33 - 3747: 27,-33 + 3621: 26,-35 + 3622: 27,-35 + 3623: 28,-35 + 3624: 29,-35 + 3625: 30,-35 + 3626: 30,-34 + 3627: 29,-34 + 3628: 28,-34 + 3629: 27,-34 + 3630: 26,-34 + 3631: 26,-33 + 3632: 26,-32 + 3633: 27,-32 + 3634: 28,-32 + 3635: 29,-32 + 3636: 30,-32 + 3637: 30,-33 + 3638: 29,-33 + 3639: 28,-33 + 3640: 27,-33 - node: color: '#334E6DC8' id: MiniTileCheckerBOverlay decals: - 4906: -33,18 - 4907: -33,17 - 4908: -32,17 - 4909: -31,17 - 4910: -31,18 - 4911: -32,18 + 4687: -33,18 + 4688: -33,17 + 4689: -32,17 + 4690: -31,17 + 4691: -31,18 + 4692: -32,18 - node: color: '#FFFFFFFF' id: MiniTileCheckerBOverlay decals: - 3748: 26,-32 - 3749: 26,-33 - 3750: 26,-34 - 3751: 26,-35 - 3752: 27,-35 - 3753: 28,-35 - 3754: 29,-35 - 3755: 30,-35 - 3756: 30,-34 - 3757: 30,-33 - 3758: 30,-32 - 3759: 29,-32 - 3760: 28,-32 - 3761: 27,-32 - 3762: 27,-33 - 3763: 27,-34 - 3764: 28,-34 - 3765: 28,-33 - 3766: 29,-33 - 3767: 29,-34 + 3641: 26,-32 + 3642: 26,-33 + 3643: 26,-34 + 3644: 26,-35 + 3645: 27,-35 + 3646: 28,-35 + 3647: 29,-35 + 3648: 30,-35 + 3649: 30,-34 + 3650: 30,-33 + 3651: 30,-32 + 3652: 29,-32 + 3653: 28,-32 + 3654: 27,-32 + 3655: 27,-33 + 3656: 27,-34 + 3657: 28,-34 + 3658: 28,-33 + 3659: 29,-33 + 3660: 29,-34 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerNe decals: - 3469: 46,36 + 3445: 46,36 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerNw decals: - 3467: 43,36 + 3443: 43,36 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerSe decals: - 3468: 46,33 + 3444: 46,33 - node: color: '#FFFFFFFF' id: MiniTileDarkCornerSw decals: - 3466: 43,33 + 3442: 43,33 - node: color: '#FFFFFFFF' id: MiniTileDarkInnerSw decals: - 3579: -24,-18 + 3472: -24,-18 - node: color: '#FFFFFFFF' id: MiniTileDarkLineE decals: - 3472: 46,35 - 3473: 46,34 + 3448: 46,35 + 3449: 46,34 - node: color: '#FFFFFFFF' id: MiniTileDarkLineN decals: - 3470: 44,36 - 3471: 45,36 + 3446: 44,36 + 3447: 45,36 - node: color: '#FFFFFFFF' id: MiniTileDarkLineS decals: - 3474: 44,33 - 3475: 45,33 - 3580: -25,-18 - 3581: -26,-18 - 3582: -27,-18 - 3590: 25,-1 - 3591: 25,-1 + 3450: 44,33 + 3451: 45,33 + 3473: -25,-18 + 3474: -26,-18 + 3475: -27,-18 + 3483: 25,-1 + 3484: 25,-1 - node: color: '#FFFFFFFF' id: MiniTileDarkLineW decals: - 3476: 43,34 - 3477: 43,35 - 3576: -24,-21 - 3577: -24,-20 - 3578: -24,-19 + 3452: 43,34 + 3453: 43,35 + 3469: -24,-21 + 3470: -24,-20 + 3471: -24,-19 - node: color: '#666C6CA4' id: MiniTileDiagonalCheckerBOverlay decals: - 4474: 58,-37 - 4475: 58,-38 - 4476: 59,-38 - 4477: 59,-37 + 4295: 58,-37 + 4296: 58,-38 + 4297: 59,-38 + 4298: 59,-37 - node: color: '#FFFFFFFF' id: MiniTileSteelEndE decals: - 3479: 41,-9 + 3455: 41,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelEndW decals: - 3478: 39,-9 + 3454: 39,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelLineN decals: - 3480: 40,-9 + 3456: 40,-9 - node: color: '#FFFFFFFF' id: MiniTileSteelLineS decals: - 3481: 40,-9 + 3457: 40,-9 - node: - color: '#FFFFFFFF' + color: '#52B4E996' id: MiniTileWhiteCornerNe decals: - 3498: -30,-35 + 4894: -40,-43 - node: - color: '#FFFFFFFF' - id: MiniTileWhiteCornerNw + zIndex: 1 + color: '#52B4E996' + id: MiniTileWhiteCornerNe decals: - 3497: -40,-35 + 4907: -42,-40 - node: color: '#52B4E996' - id: MiniTileWhiteCornerSe + id: MiniTileWhiteCornerNw decals: - 3546: -30,-40 + 4895: -44,-40 - node: - color: '#FFFFFFFF' + color: '#52B4E996' id: MiniTileWhiteCornerSe decals: - 3543: -30,-40 + 4892: -40,-45 - node: color: '#52B4E996' id: MiniTileWhiteCornerSw decals: - 3545: -32,-40 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteCornerSw - decals: - 3542: -32,-40 + 4893: -44,-45 - node: color: '#52B4E996' - id: MiniTileWhiteInnerNw + id: MiniTileWhiteInnerNe decals: - 3564: -40,-40 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteInnerNw - decals: - 3505: -40,-40 + 4896: -42,-43 - node: color: '#52B4E996' - id: MiniTileWhiteInnerSe - decals: - 3538: -38,-37 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteInnerSe - decals: - 3496: -38,-37 - - node: - color: '#52B4E996' - id: MiniTileWhiteInnerSw - decals: - 3539: -32,-37 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteInnerSw - decals: - 3495: -32,-37 - - node: - color: '#52B4E996' - id: MiniTileWhiteLineE - decals: - 3548: -30,-39 - 3549: -30,-38 - 3550: -30,-37 - 3551: -30,-36 - 3552: -30,-35 - 3554: -38,-38 - 3555: -38,-39 - 3556: -38,-40 - 3557: -38,-41 - - node: - color: '#FFFFFFFF' id: MiniTileWhiteLineE decals: - 3485: -38,-38 - 3486: -38,-39 - 3487: -38,-40 - 3488: -38,-41 - 3489: -30,-36 - 3490: -30,-37 - 3491: -30,-38 - 3492: -30,-39 + 4902: -42,-41 + 4903: -42,-42 + 4908: -40,-44 - node: color: '#52B4E996' id: MiniTileWhiteLineN decals: - 3527: -39,-35 - 3528: -38,-35 - 3529: -37,-35 - 3530: -36,-35 - 3531: -35,-35 - 3532: -34,-35 - 3533: -33,-35 - 3534: -32,-35 - 3535: -31,-35 - 3536: -30,-35 - 3537: -40,-35 - 3563: -41,-40 - - node: - color: '#52B4E9FF' - id: MiniTileWhiteLineN - decals: - 3482: -43,-44 - 3483: -43,-42 - 3484: -39,-44 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteLineN - decals: - 3506: -41,-40 - 3518: -39,-35 - 3519: -38,-35 - 3520: -37,-35 - 3521: -36,-35 - 3522: -35,-35 - 3523: -34,-35 - 3524: -33,-35 - 3525: -32,-35 - 3526: -31,-35 + 4900: -43,-40 + 4901: -41,-43 - node: color: '#52B4E996' id: MiniTileWhiteLineS decals: - 3513: -37,-37 - 3514: -36,-37 - 3515: -35,-37 - 3516: -34,-37 - 3517: -33,-37 - 3547: -31,-40 - 3553: -41,-45 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteLineS - decals: - 3507: -41,-45 - 3508: -37,-37 - 3509: -36,-37 - 3510: -35,-37 - 3511: -34,-37 - 3512: -33,-37 - 3544: -31,-40 + 4889: -43,-45 + 4890: -42,-45 + 4891: -41,-45 - node: color: '#52B4E996' id: MiniTileWhiteLineW decals: - 3540: -32,-38 - 3541: -32,-39 - 3558: -40,-35 - 3559: -40,-36 - 3560: -40,-37 - 3561: -40,-38 - 3562: -40,-39 - - node: - color: '#FFFFFFFF' - id: MiniTileWhiteLineW - decals: - 3493: -32,-39 - 3494: -32,-38 - 3499: -40,-36 - 3500: -40,-37 - 3501: -40,-36 - 3502: -40,-38 - 3503: -40,-37 - 3504: -40,-39 - - node: - color: '#52B4E996' - id: OffsetCheckerBOverlay - decals: - 4160: -35,-44 - 4161: -35,-43 - 4162: -34,-43 - 4163: -34,-44 + 4897: -44,-43 + 4898: -44,-42 + 4899: -44,-41 + 4909: -44,-44 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale @@ -5643,13 +5485,13 @@ entities: 217: -23,-33 218: -24,-33 231: -26,-34 - 699: 25,10 - 700: 27,10 - 701: 29,10 - 706: 25,6 - 707: 24,7 - 708: 24,9 - 3308: -26,-27 + 687: 25,10 + 688: 27,10 + 689: 29,10 + 694: 25,6 + 695: 24,7 + 696: 24,9 + 3284: -26,-27 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale @@ -5702,18 +5544,18 @@ entities: color: '#D4D4D433' id: QuarterTileOverlayGreyscale decals: - 780: -11,-28 - 787: -6,-25 - 837: 27,-3 - 903: 19,-58 + 768: -11,-28 + 775: -6,-25 + 825: 27,-3 + 891: 19,-58 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale decals: - 404: 35,-7 - 532: -32,25 - 535: -28,26 - 1477: 38,51 + 392: 35,-7 + 520: -32,25 + 523: -28,26 + 1465: 38,51 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale @@ -5742,56 +5584,56 @@ entities: 44: 27,0 45: 27,-1 46: 27,-2 - 540: -33,31 - 541: -32,31 - 542: -31,31 - 543: -30,31 - 544: -29,31 - 545: -28,31 - 546: -27,31 - 547: -26,31 - 548: -25,31 - 549: -24,31 - 550: -23,31 - 551: -22,31 - 552: -21,31 - 553: -21,32 - 637: -19,54 - 654: -28,39 - 655: -27,39 - 656: -26,39 - 657: -25,39 - 658: -24,39 - 659: -23,39 - 660: -28,38 - 661: -28,37 - 664: -11,41 - 665: -12,41 - 666: -13,41 - 667: -14,41 - 668: -15,41 - 669: -16,41 - 670: -17,41 - 671: -17,40 - 672: -17,39 - 673: -17,38 - 674: -17,37 - 675: -17,36 - 676: -17,35 - 689: 24,10 - 690: 26,10 - 691: 28,10 - 698: 24,8 - 1416: -6,37 - 1417: -6,36 - 1418: -6,35 - 1419: -6,34 - 1420: -6,33 - 1443: -6,38 - 1444: -6,39 - 1445: -6,40 - 1446: -6,41 - 1447: -6,42 + 528: -33,31 + 529: -32,31 + 530: -31,31 + 531: -30,31 + 532: -29,31 + 533: -28,31 + 534: -27,31 + 535: -26,31 + 536: -25,31 + 537: -24,31 + 538: -23,31 + 539: -22,31 + 540: -21,31 + 541: -21,32 + 625: -19,54 + 642: -28,39 + 643: -27,39 + 644: -26,39 + 645: -25,39 + 646: -24,39 + 647: -23,39 + 648: -28,38 + 649: -28,37 + 652: -11,41 + 653: -12,41 + 654: -13,41 + 655: -14,41 + 656: -15,41 + 657: -16,41 + 658: -17,41 + 659: -17,40 + 660: -17,39 + 661: -17,38 + 662: -17,37 + 663: -17,36 + 664: -17,35 + 677: 24,10 + 678: 26,10 + 679: 28,10 + 686: 24,8 + 1404: -6,37 + 1405: -6,36 + 1406: -6,35 + 1407: -6,34 + 1408: -6,33 + 1431: -6,38 + 1432: -6,39 + 1433: -6,40 + 1434: -6,41 + 1435: -6,42 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale180 @@ -5816,77 +5658,77 @@ entities: 226: -22,-27 228: -26,-26 229: -27,-26 - 702: 29,9 - 703: 29,7 - 704: 28,6 - 705: 26,6 - 3309: -25,-27 + 690: 29,9 + 691: 29,7 + 692: 28,6 + 693: 26,6 + 3285: -25,-27 - node: color: '#A4610696' id: QuarterTileOverlayGreyscale180 decals: - 1639: 45,26 - 1640: 43,16 + 1627: 45,26 + 1628: 43,16 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale180 decals: - 973: 20,66 - 992: 24,71 + 961: 20,66 + 980: 24,71 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale180 decals: - 1181: -22,29 - 1359: -4,49 + 1169: -22,29 + 1347: -4,49 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale180 decals: - 770: -5,-26 - 818: -41,-5 - 849: 20,-5 - 881: 21,-36 + 758: -5,-26 + 806: -41,-5 + 837: 20,-5 + 869: 21,-36 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale180 decals: 238: -27,-40 - 348: 43,-1 - 383: 34,-13 - 384: 35,-15 - 385: 36,-17 - 386: 33,-8 - 405: 46,-6 - 536: -26,27 - 537: -30,27 - 1223: -61,51 - 1622: 46,-12 + 336: 43,-1 + 371: 34,-13 + 372: 35,-15 + 373: 36,-17 + 374: 33,-8 + 393: 46,-6 + 524: -26,27 + 525: -30,27 + 1211: -61,51 + 1610: 46,-12 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale180 decals: - 634: -19,43 - 662: -24,36 - 663: -23,36 - 677: -17,35 - 678: -16,35 - 679: -15,35 - 680: -14,35 - 681: -13,35 - 682: -13,36 - 683: -13,37 - 684: -13,38 - 685: -12,38 - 686: -11,38 - 692: 29,10 - 693: 29,8 - 694: 29,6 - 695: 27,6 - 696: 25,6 - 697: 24,7 - 1448: -7,43 - 1449: -8,43 + 622: -19,43 + 650: -24,36 + 651: -23,36 + 665: -17,35 + 666: -16,35 + 667: -15,35 + 668: -14,35 + 669: -13,35 + 670: -13,36 + 671: -13,37 + 672: -13,38 + 673: -12,38 + 674: -11,38 + 680: 29,10 + 681: 29,8 + 682: 29,6 + 683: 27,6 + 684: 25,6 + 685: 24,7 + 1436: -7,43 + 1437: -8,43 - node: color: '#52B4E996' id: QuarterTileOverlayGreyscale270 @@ -5901,51 +5743,51 @@ entities: 186: -13,-27 230: -26,-33 232: -26,-34 - 437: 51,-13 - 438: 51,-12 - 1611: 53,-14 - 1612: 52,-14 - 1613: 51,-14 + 425: 51,-13 + 426: 51,-12 + 1599: 53,-14 + 1600: 52,-14 + 1601: 51,-14 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale270 decals: - 336: -47,-24 - 337: -47,-25 - 338: -47,-26 + 324: -47,-24 + 325: -47,-25 + 326: -47,-26 - node: color: '#A4610696' id: QuarterTileOverlayGreyscale270 decals: - 1641: 44,16 + 1629: 44,16 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale270 decals: - 970: 18,67 - 1025: 11,58 - 1026: 11,57 - 1027: 11,56 - 1028: 11,55 - 1029: 11,54 - 1030: 11,53 - 1031: 12,53 + 958: 18,67 + 1013: 11,58 + 1014: 11,57 + 1015: 11,56 + 1016: 11,55 + 1017: 11,54 + 1018: 11,53 + 1019: 12,53 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale270 decals: - 1180: -24,29 - 1324: 18,30 + 1168: -24,29 + 1312: 18,30 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale270 decals: - 779: -7,-28 - 781: -11,-27 - 803: -6,-5 - 827: 17,-5 - 828: 18,-6 - 840: 29,-5 + 767: -7,-28 + 769: -11,-27 + 791: -6,-5 + 815: 17,-5 + 816: 18,-6 + 828: 29,-5 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale270 @@ -5981,55 +5823,55 @@ entities: 88: 63,2 89: 64,2 237: -25,-40 - 349: 47,-1 - 387: 47,-6 - 399: 35,-13 - 400: 36,-15 - 401: 34,-8 - 412: 37,-6 - 413: 38,-6 - 414: 39,-6 - 415: 40,-6 - 416: 41,-6 - 417: 42,-6 - 418: 43,-6 - 419: 44,-6 - 420: 44,-7 - 421: 44,-8 - 422: 44,-9 - 423: 44,-10 - 424: 44,-11 - 439: 49,-3 - 440: 50,-3 - 441: 51,-3 - 442: 52,-3 - 443: 53,-3 - 444: 54,-3 - 445: 55,-3 - 446: 56,-3 - 456: 49,-1 - 457: 49,-2 - 458: 58,0 - 459: 58,-1 - 460: 58,-2 - 461: 58,-3 - 462: 59,-3 - 463: 60,-3 - 464: 61,-3 - 465: 62,-3 - 538: -28,27 - 539: -32,27 - 1230: -64,51 + 337: 47,-1 + 375: 47,-6 + 387: 35,-13 + 388: 36,-15 + 389: 34,-8 + 400: 37,-6 + 401: 38,-6 + 402: 39,-6 + 403: 40,-6 + 404: 41,-6 + 405: 42,-6 + 406: 43,-6 + 407: 44,-6 + 408: 44,-7 + 409: 44,-8 + 410: 44,-9 + 411: 44,-10 + 412: 44,-11 + 427: 49,-3 + 428: 50,-3 + 429: 51,-3 + 430: 52,-3 + 431: 53,-3 + 432: 54,-3 + 433: 55,-3 + 434: 56,-3 + 444: 49,-1 + 445: 49,-2 + 446: 58,0 + 447: 58,-1 + 448: 58,-2 + 449: 58,-3 + 450: 59,-3 + 451: 60,-3 + 452: 61,-3 + 453: 62,-3 + 526: -28,27 + 527: -32,27 + 1218: -64,51 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale270 decals: - 1437: -6,51 - 1438: -6,50 - 1439: -6,49 - 1440: -6,48 - 1441: -6,47 - 1442: -6,46 + 1425: -6,51 + 1426: -6,50 + 1427: -6,49 + 1428: -6,48 + 1429: -6,47 + 1430: -6,46 - node: color: '#334E6DC8' id: QuarterTileOverlayGreyscale90 @@ -6053,11 +5895,11 @@ entities: decals: 233: -26,-34 234: -27,-34 - 432: 53,-12 - 433: 52,-12 - 434: 51,-12 - 435: 53,-13 - 436: 53,-14 + 420: 53,-12 + 421: 52,-12 + 422: 51,-12 + 423: 53,-13 + 424: 53,-14 - node: color: '#9FED5896' id: QuarterTileOverlayGreyscale90 @@ -6082,13 +5924,13 @@ entities: 138: -5,-47 139: -5,-48 140: -5,-49 - 329: -43,-26 - 330: -43,-25 - 331: -44,-25 - 332: -45,-25 - 333: -45,-24 - 334: -46,-24 - 335: -47,-24 + 317: -43,-26 + 318: -43,-25 + 319: -44,-25 + 320: -45,-25 + 321: -45,-24 + 322: -46,-24 + 323: -47,-24 - node: color: '#A4610696' id: QuarterTileOverlayGreyscale90 @@ -6117,1164 +5959,1166 @@ entities: 21: 33,20 22: 33,19 90: 33,7 - 1452: 33,23 - 1453: 33,24 - 1454: 33,25 - 1455: 33,26 - 1456: 33,27 - 1457: 33,28 - 1458: 33,29 - 1459: 33,30 - 4091: 33,35 + 1440: 33,23 + 1441: 33,24 + 1442: 33,25 + 1443: 33,26 + 1444: 33,27 + 1445: 33,28 + 1446: 33,29 + 1447: 33,30 + 3984: 33,35 - node: color: '#D381C996' id: QuarterTileOverlayGreyscale90 decals: - 573: 25,51 - 574: 24,51 - 575: 23,51 - 576: 22,51 - 577: 21,51 - 988: 24,66 - 1018: 16,57 - 1019: 16,58 - 1020: 15,58 - 1021: 14,58 - 1022: 13,58 - 1023: 12,58 - 1024: 11,58 - 1394: 20,51 - 1395: 19,51 - 1396: 18,51 - 1397: 17,51 - 1398: 16,51 - 1399: 12,51 - 1400: 11,51 - 1401: 10,51 - 1402: 9,51 - 1403: 8,51 - 1404: 7,51 - 1405: 6,51 - 1406: 5,51 - 1407: 4,51 + 561: 25,51 + 562: 24,51 + 563: 23,51 + 564: 22,51 + 565: 21,51 + 976: 24,66 + 1006: 16,57 + 1007: 16,58 + 1008: 15,58 + 1009: 14,58 + 1010: 13,58 + 1011: 12,58 + 1012: 11,58 + 1382: 20,51 + 1383: 19,51 + 1384: 18,51 + 1385: 17,51 + 1386: 16,51 + 1387: 12,51 + 1388: 11,51 + 1389: 10,51 + 1390: 9,51 + 1391: 8,51 + 1392: 7,51 + 1393: 6,51 + 1394: 5,51 + 1395: 4,51 - node: color: '#D4D4D419' id: QuarterTileOverlayGreyscale90 decals: - 1213: -56,31 + 1201: -56,31 - node: color: '#D4D4D433' id: QuarterTileOverlayGreyscale90 decals: - 860: 20,-17 - 874: 21,-31 - 902: 21,-58 + 848: 20,-17 + 862: 21,-31 + 890: 21,-58 - node: color: '#DE3A3A96' id: QuarterTileOverlayGreyscale90 decals: - 359: 37,-3 - 388: 46,-12 - 402: 33,-7 - 406: 36,-12 - 407: 36,-11 - 408: 36,-10 - 409: 36,-9 - 410: 36,-8 - 411: 36,-7 - 425: 43,-12 - 426: 42,-12 - 427: 41,-12 - 428: 40,-12 - 429: 39,-12 - 430: 38,-12 - 431: 37,-12 - 447: 56,-3 - 448: 56,-2 - 449: 56,-1 - 450: 54,-1 - 451: 53,-1 - 452: 52,-1 - 453: 51,-1 - 454: 50,-1 - 455: 49,-1 - 466: 62,-3 - 467: 62,-2 - 468: 62,-1 - 469: 62,0 - 470: 61,0 - 471: 60,0 - 472: 59,0 - 473: 58,0 - 533: -26,25 - 534: -30,26 - 1623: 46,-17 + 347: 37,-3 + 376: 46,-12 + 390: 33,-7 + 394: 36,-12 + 395: 36,-11 + 396: 36,-10 + 397: 36,-9 + 398: 36,-8 + 399: 36,-7 + 413: 43,-12 + 414: 42,-12 + 415: 41,-12 + 416: 40,-12 + 417: 39,-12 + 418: 38,-12 + 419: 37,-12 + 435: 56,-3 + 436: 56,-2 + 437: 56,-1 + 438: 54,-1 + 439: 53,-1 + 440: 52,-1 + 441: 51,-1 + 442: 50,-1 + 443: 49,-1 + 454: 62,-3 + 455: 62,-2 + 456: 62,-1 + 457: 62,0 + 458: 61,0 + 459: 60,0 + 460: 59,0 + 461: 58,0 + 521: -26,25 + 522: -30,26 + 1611: 46,-17 - node: color: '#EFB34196' id: QuarterTileOverlayGreyscale90 decals: - 554: -19,32 - 555: -19,31 - 556: -18,31 - 557: -17,31 - 558: -16,31 - 559: -15,31 - 560: -14,31 - 561: -13,31 - 562: -12,31 - 563: -11,31 - 564: -10,31 - 565: -9,31 - 566: -8,31 - 633: -19,45 - 638: -20,54 - 1408: 2,51 - 1409: 1,51 - 1410: -1,51 - 1411: -2,51 - 1412: -3,51 - 1413: -4,51 - 1414: -5,51 - 1415: -6,51 - 1450: -7,45 - 1451: -8,45 + 542: -19,32 + 543: -19,31 + 544: -18,31 + 545: -17,31 + 546: -16,31 + 547: -15,31 + 548: -14,31 + 549: -13,31 + 550: -12,31 + 551: -11,31 + 552: -10,31 + 553: -9,31 + 554: -8,31 + 621: -19,45 + 626: -20,54 + 1396: 2,51 + 1397: 1,51 + 1398: -1,51 + 1399: -2,51 + 1400: -3,51 + 1401: -4,51 + 1402: -5,51 + 1403: -6,51 + 1438: -7,45 + 1439: -8,45 - node: color: '#FFFFFFFF' id: Remains decals: - 3342: -29.994413,-49.927315 + 3318: -29.994413,-49.927315 - node: color: '#60E25873' id: Rock01 decals: - 3401: -59.92391,38.210167 - 3402: -59.99335,38.974056 - 3403: -59.99335,39.946278 - 3404: -59.965576,41.015724 - 3405: -59.965576,42.321278 + 3377: -59.92391,38.210167 + 3378: -59.99335,38.974056 + 3379: -59.99335,39.946278 + 3380: -59.965576,41.015724 + 3381: -59.965576,42.321278 - node: color: '#9FED5896' id: Rock01 decals: - 3569: 24.034931,-33.3361 - 3570: 23.951597,-33.863876 + 3462: 24.034931,-33.3361 + 3463: 23.951597,-33.863876 - node: color: '#9FED5873' id: Rock02 decals: - 3335: 78.26405,7.9695406 - 3336: 79.31961,7.983429 - 3337: 79.93072,7.941762 - 3338: 78.26405,7.9556513 + 3311: 78.26405,7.9695406 + 3312: 79.31961,7.983429 + 3313: 79.93072,7.941762 + 3314: 78.26405,7.9556513 - node: color: '#9FED5896' id: Rock02 decals: - 3221: -40.422146,-22.63485 - 3222: -41.797146,-22.468182 - 3223: -42.797146,-21.815403 - 3224: -42.297146,-22.87096 - 3225: -43.158257,-18.593182 - 3226: -43.047146,-19.73207 - 3227: -40.61659,-18.329292 - 3228: -39.922146,-18.940403 - 3229: -39.797146,-22.565403 - 3230: -39.86659,-23.50985 - 3231: -41.283257,-21.787628 - 3232: -42.797146,-20.87096 - 3233: -42.7277,-17.940403 - 3234: -41.061035,-18.12096 - 3235: -41.21381,-19.176516 + 3197: -40.422146,-22.63485 + 3198: -41.797146,-22.468182 + 3199: -42.797146,-21.815403 + 3200: -42.297146,-22.87096 + 3201: -43.158257,-18.593182 + 3202: -43.047146,-19.73207 + 3203: -40.61659,-18.329292 + 3204: -39.922146,-18.940403 + 3205: -39.797146,-22.565403 + 3206: -39.86659,-23.50985 + 3207: -41.283257,-21.787628 + 3208: -42.797146,-20.87096 + 3209: -42.7277,-17.940403 + 3210: -41.061035,-18.12096 + 3211: -41.21381,-19.176516 - node: color: '#9FED5896' id: Rock05 decals: - 3565: 23.909931,-33.22499 - 3566: 24.007153,-33.9611 + 3458: 23.909931,-33.22499 + 3459: 24.007153,-33.9611 - node: color: '#FFFFFFFF' id: Rock05 decals: - 4993: -1.8656068,46.688976 + 4774: -1.8656068,46.688976 - node: color: '#FFFFFFFF' id: Rock07 decals: - 3341: -16.459831,-40.314075 + 3317: -16.459831,-40.314075 - node: cleanable: True color: '#FFFFFFFF' id: Rust decals: - 3316: -64,-33 - 3317: -65,-33 - 3318: -63,-33 + 3292: -64,-33 + 3293: -65,-33 + 3294: -63,-33 - node: color: '#B78FB4FF' id: SpaceStationSign1 decals: - 1555: 4,-4 + 1543: 4,-4 - node: color: '#B78FB4FF' id: SpaceStationSign2 decals: - 1556: 5,-4 + 1544: 5,-4 - node: color: '#B78FB4FF' id: SpaceStationSign3 decals: - 1557: 6,-4 + 1545: 6,-4 - node: color: '#B78FB4FF' id: SpaceStationSign4 decals: - 1558: 7,-4 + 1546: 7,-4 - node: color: '#B78FB4FF' id: SpaceStationSign5 decals: - 1559: 8,-4 + 1547: 8,-4 - node: color: '#B78FB4FF' id: SpaceStationSign6 decals: - 1560: 9,-4 + 1548: 9,-4 - node: color: '#B78FB4FF' id: SpaceStationSign7 decals: - 1561: 10,-4 + 1549: 10,-4 - node: color: '#A4610696' id: StandClear decals: - 4083: 34,20 - 4084: 34,19 - 4085: 34,20 - 4086: 34,19 - 4087: 39,20 - 4088: 39,19 - 4089: 39,20 - 4090: 39,19 + 3976: 34,20 + 3977: 34,19 + 3978: 34,20 + 3979: 34,19 + 3980: 39,20 + 3981: 39,19 + 3982: 39,20 + 3983: 39,19 - node: color: '#EFB34196' id: StandClear decals: - 474: 35,-2 - 475: 36,-2 - 476: 37,-2 - 731: 23,14 - 732: 23,13 - 733: 23,12 - 1055: 37,26 - 1563: 34,14 - 1564: 34,13 - 1565: 34,12 - 1566: 53,-26 - 1567: 53,-27 - 1568: 53,-28 - 1569: 53,-29 - 1570: 53,-30 - 1571: 53,-31 - 1572: 56,-31 - 1573: 56,-30 - 1574: 56,-29 - 1575: 56,-28 - 1576: 56,-27 - 1577: 56,-26 - 1642: -22,50 - 1643: -22,49 - 1644: -22,48 - 1645: -22,47 + 462: 35,-2 + 463: 36,-2 + 464: 37,-2 + 719: 23,14 + 720: 23,13 + 721: 23,12 + 1043: 37,26 + 1551: 34,14 + 1552: 34,13 + 1553: 34,12 + 1554: 53,-26 + 1555: 53,-27 + 1556: 53,-28 + 1557: 53,-29 + 1558: 53,-30 + 1559: 53,-31 + 1560: 56,-31 + 1561: 56,-30 + 1562: 56,-29 + 1563: 56,-28 + 1564: 56,-27 + 1565: 56,-26 + 1630: -22,50 + 1631: -22,49 + 1632: -22,48 + 1633: -22,47 - node: angle: 1.5707963267948966 rad color: '#EFB34196' id: StandClear decals: - 1247: -56,39 - 1248: -56,37 - 1249: -56,46 - 1250: -56,48 + 1235: -56,39 + 1236: -56,37 + 1237: -56,46 + 1238: -56,48 - node: color: '#52B4E996' id: StandClearGreyscale decals: - 4250: -3,-11 - 4251: -3,-12 - 4252: -1,-11 - 4253: -1,-12 - 4254: 15,-11 - 4255: 15,-12 - 4256: 17,-11 - 4257: 17,-12 - 4961: -27,17 - 4962: -27,18 - 4963: -25,18 - 4964: -25,17 + 4071: -3,-11 + 4072: -3,-12 + 4073: -1,-11 + 4074: -1,-12 + 4075: 15,-11 + 4076: 15,-12 + 4077: 17,-11 + 4078: 17,-12 + 4742: -27,17 + 4743: -27,18 + 4744: -25,18 + 4745: -25,17 - node: color: '#D381C996' id: StandClearGreyscale decals: - 3997: 25,54 - 3998: 25,55 - 3999: 21,55 - 4000: 21,54 - 4092: 16,64 - 4093: 18,68 - 4094: 19,68 - 4095: 23,72 - 4096: 24,72 - 4553: 25,79 - 4554: 25,78 - 4555: 28,79 - 4556: 28,78 - 4557: 32,79 - 4558: 32,78 - 4559: 32,77 + 3890: 25,54 + 3891: 25,55 + 3892: 21,55 + 3893: 21,54 + 3985: 16,64 + 3986: 18,68 + 3987: 19,68 + 3988: 23,72 + 3989: 24,72 + 4374: 25,79 + 4375: 25,78 + 4376: 28,79 + 4377: 28,78 + 4378: 32,79 + 4379: 32,78 + 4380: 32,77 - node: color: '#DE3A3A96' id: StandClearGreyscale decals: - 1630: 47,-14 - 1631: 47,-15 - 1632: 50,-18 - 1688: 41,1 - 1689: 39,1 - 1690: 39,-2 - 1691: 41,-2 + 1618: 47,-14 + 1619: 47,-15 + 1620: 50,-18 + 1676: 41,1 + 1677: 39,1 + 1678: 39,-2 + 1679: 41,-2 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale decals: - 820: -43,-3 + 808: -43,-3 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale decals: 243: -28,-38 - 1472: 35,51 + 1460: 35,51 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale180 decals: - 825: -3,-6 + 813: -3,-6 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale180 decals: 235: -27,-41 241: -22,-41 - 1226: -61,48 - 1470: 38,48 + 1214: -61,48 + 1458: 38,48 - node: color: '#D4D4D419' id: ThreeQuarterTileOverlayGreyscale270 decals: - 1209: -58,29 + 1197: -58,29 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale270 decals: - 826: 17,-6 + 814: 17,-6 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale270 decals: 236: -25,-41 242: -28,-41 - 1471: 35,48 + 1459: 35,48 - node: color: '#D4D4D419' id: ThreeQuarterTileOverlayGreyscale90 decals: - 1325: 18,31 + 1313: 18,31 - node: color: '#D4D4D433' id: ThreeQuarterTileOverlayGreyscale90 decals: - 859: 21,-17 + 847: 21,-17 - node: color: '#DE3A3A96' id: ThreeQuarterTileOverlayGreyscale90 decals: 244: -22,-38 - 3592: 47,-3 + 3485: 47,-3 - node: color: '#FFFFFFFF' id: VentSmall decals: - 3678: -5,-1 + 3571: -5,-1 - node: color: '#79150096' id: WarnBox decals: - 1506: -52,-24 - 1507: -52,-25 - 3285: -6,13 - 3286: -6,13 - 3287: -6,14 - 3288: -6,14 - 3289: -6,15 - 3290: -6,15 - 3294: 30,13 - 3295: 30,12 - 3296: 30,13 - 3297: 30,12 + 1494: -52,-24 + 1495: -52,-25 + 3261: -6,13 + 3262: -6,13 + 3263: -6,14 + 3264: -6,14 + 3265: -6,15 + 3266: -6,15 + 3270: 30,13 + 3271: 30,12 + 3272: 30,13 + 3273: 30,12 - node: color: '#52B4E996' id: WarnBoxGreyscale decals: - 1508: -49,-25 - 1509: -49,-24 - 3291: 22,17 - 3292: 22,16 - 3293: 22,15 + 1496: -49,-25 + 1497: -49,-24 + 3267: 22,17 + 3268: 22,16 + 3269: 22,15 + 4925: -51,-38 + 4926: -49,-38 - node: color: '#EFB34196' id: WarnCornerNE decals: - 1015: 16,56 - 1114: 39,14 - 1436: -7,42 + 1003: 16,56 + 1102: 39,14 + 1424: -7,42 - node: color: '#FFFFFFFF' id: WarnCornerNE decals: - 5068: 27,12 - 5072: -25,36 - 5076: 54,-15 + 4849: 27,12 + 4853: -25,36 + 4857: 54,-15 - node: color: '#EFB34196' id: WarnCornerNW decals: - 739: 24,14 - 1111: 35,14 + 727: 24,14 + 1099: 35,14 - node: color: '#FFFFFFFF' id: WarnCornerNW decals: - 4900: -29,16 - 5067: 25,12 - 5073: -28,36 - 5074: -10,41 + 4681: -29,16 + 4848: 25,12 + 4854: -28,36 + 4855: -10,41 - node: color: '#EFB34196' id: WarnCornerSE decals: - 1112: 39,12 - 1271: -22,32 - 1430: -7,46 - 3283: -2,43 + 1100: 39,12 + 1259: -22,32 + 1418: -7,46 + 3259: -2,43 - node: color: '#FFFFFFFF' id: WarnCornerSE decals: - 4885: 10,72 - 5077: 54,-17 + 4666: 10,72 + 4858: 54,-17 - node: color: '#EFB34196' id: WarnCornerSW decals: - 1113: 35,12 - 1272: -18,32 + 1101: 35,12 + 1260: -18,32 - node: color: '#FFFFFFFF' id: WarnCornerSW decals: - 4903: -29,19 - 5075: -10,40 + 4684: -29,19 + 4856: -10,40 - node: color: '#EFB34196' id: WarnCornerSmallNE decals: - 1501: -2,57 + 1489: -2,57 - node: color: '#FFFFFFFF' id: WarnCornerSmallNE decals: - 5037: 73,-5 - 5038: 73,-12 - 5098: -40,26 + 4818: 73,-5 + 4819: 73,-12 + 4879: -40,26 - node: color: '#EFB34196' id: WarnCornerSmallNW decals: - 653: -23,48 - 1500: 2,57 + 641: -23,48 + 1488: 2,57 - node: color: '#FFFFFFFF' id: WarnCornerSmallNW decals: - 5039: 85,-5 - 5040: 85,-12 - 5099: -41,26 + 4820: 85,-5 + 4821: 85,-12 + 4880: -41,26 - node: color: '#EFB34196' id: WarnCornerSmallSE decals: - 1498: -2,61 - 3270: 49,-20 - 3284: -2,44 + 1486: -2,61 + 3246: 49,-20 + 3260: -2,44 - node: color: '#FFFFFFFF' id: WarnCornerSmallSE decals: - 5035: 73,-3 - 5036: 73,-10 + 4816: 73,-3 + 4817: 73,-10 - node: color: '#EFB34196' id: WarnCornerSmallSW decals: - 1011: 16,56 - 1499: 2,61 - 3271: 51,-20 + 999: 16,56 + 1487: 2,61 + 3247: 51,-20 - node: color: '#FFFFFFFF' id: WarnCornerSmallSW decals: - 5041: 85,-10 - 5042: 85,-3 + 4822: 85,-10 + 4823: 85,-3 - node: color: '#EFB34196' id: WarnEndE decals: - 1693: -19,-23 + 1681: -19,-23 - node: color: '#FFFFFFFF' id: WarnEndE decals: - 4884: 21,74 + 4665: 21,74 - node: color: '#FFFFFFFF' id: WarnEndN decals: - 5079: 40,-10 + 4860: 40,-10 - node: color: '#EFB34196' id: WarnEndS decals: - 3267: 49,-21 - 3268: 51,-21 + 3243: 49,-21 + 3244: 51,-21 - node: color: '#EFB34196' id: WarnEndW decals: - 1012: 13,56 - 1692: -20,-23 + 1000: 13,56 + 1680: -20,-23 - node: color: '#FFFFFFFF' id: WarnEndW decals: - 4883: 20,74 + 4664: 20,74 - node: color: '#334E6DC8' id: WarnFullGreyscale decals: - 4959: -26,17 - 4960: -26,18 + 4740: -26,17 + 4741: -26,18 - node: color: '#EFB34196' id: WarnLineE decals: - 486: 74,14 - 487: 74,13 - 488: 74,12 - 489: 81,15 - 490: 81,14 - 491: 81,13 - 492: 81,12 - 499: 74,15 - 649: -23,50 - 650: -23,49 - 651: -23,48 - 652: -23,47 - 687: -10,38 - 688: -10,39 - 734: 22,14 - 735: 22,13 - 736: 22,12 - 1003: 24,69 - 1004: 20,60 - 1016: 16,55 - 1032: 17,65 - 1033: 17,64 - 1034: 17,63 - 1040: 24,69 - 1043: 20,60 - 1044: 15,64 - 1122: 39,13 - 1276: -22,33 - 1421: -7,38 - 1422: -7,39 - 1423: -7,40 - 1424: -7,41 - 1425: -7,47 - 1426: -7,48 - 1427: -7,49 - 1428: -7,50 - 1429: -7,51 - 1480: 33,12 - 1481: 33,13 - 1482: 33,14 - 1483: 33,12 - 1484: 33,13 - 1485: 33,14 - 1489: -2,58 - 1490: -2,59 - 1491: -2,60 - 1545: 47,33 - 1546: 47,34 - 1610: 62,-21 - 1624: 46,-14 - 1625: 46,-15 - 1626: 46,-14 - 1627: 46,-15 - 1635: 51,-17 - 1636: 51,-16 - 3272: 51,-20 - 3273: 51,-19 - 4001: 24,54 - 4002: 24,55 - 4005: 20,54 - 4006: 20,55 - 4007: 20,54 - 4008: 20,55 - 4529: 24,79 - 4530: 24,79 - 4531: 24,78 - 4532: 24,78 - 4545: 27,79 - 4546: 27,79 - 4547: 27,78 - 4548: 27,78 + 474: 74,14 + 475: 74,13 + 476: 74,12 + 477: 81,15 + 478: 81,14 + 479: 81,13 + 480: 81,12 + 487: 74,15 + 637: -23,50 + 638: -23,49 + 639: -23,48 + 640: -23,47 + 675: -10,38 + 676: -10,39 + 722: 22,14 + 723: 22,13 + 724: 22,12 + 991: 24,69 + 992: 20,60 + 1004: 16,55 + 1020: 17,65 + 1021: 17,64 + 1022: 17,63 + 1028: 24,69 + 1031: 20,60 + 1032: 15,64 + 1110: 39,13 + 1264: -22,33 + 1409: -7,38 + 1410: -7,39 + 1411: -7,40 + 1412: -7,41 + 1413: -7,47 + 1414: -7,48 + 1415: -7,49 + 1416: -7,50 + 1417: -7,51 + 1468: 33,12 + 1469: 33,13 + 1470: 33,14 + 1471: 33,12 + 1472: 33,13 + 1473: 33,14 + 1477: -2,58 + 1478: -2,59 + 1479: -2,60 + 1533: 47,33 + 1534: 47,34 + 1598: 62,-21 + 1612: 46,-14 + 1613: 46,-15 + 1614: 46,-14 + 1615: 46,-15 + 1623: 51,-17 + 1624: 51,-16 + 3248: 51,-20 + 3249: 51,-19 + 3894: 24,54 + 3895: 24,55 + 3898: 20,54 + 3899: 20,55 + 3900: 20,54 + 3901: 20,55 + 4350: 24,79 + 4351: 24,79 + 4352: 24,78 + 4353: 24,78 + 4366: 27,79 + 4367: 27,79 + 4368: 27,78 + 4369: 27,78 - node: color: '#FFFFFFFF' id: WarnLineE decals: - 4636: 19,15 - 4637: 19,16 - 4638: 19,17 - 4887: 10,73 - 4888: 10,74 - 4889: 10,75 - 4890: 10,76 - 5033: 73,-11 - 5034: 73,-4 - 5047: -54,47 - 5048: -54,46 - 5049: -54,39 - 5050: -54,38 - 5078: 54,-16 - 5083: -40,27 + 4457: 19,15 + 4458: 19,16 + 4459: 19,17 + 4668: 10,73 + 4669: 10,74 + 4670: 10,75 + 4671: 10,76 + 4814: 73,-11 + 4815: 73,-4 + 4828: -54,47 + 4829: -54,46 + 4830: -54,39 + 4831: -54,38 + 4859: 54,-16 + 4864: -40,27 - node: color: '#DE3A3A96' id: WarnLineGreyscaleN decals: - 1582: 64,-22 - 1583: 65,-22 - 1584: 66,-22 - 1585: 67,-22 - 1586: 64,-21 - 1587: 64,-21 - 1588: 65,-21 - 1589: 65,-21 - 1590: 66,-21 - 1591: 66,-21 - 1592: 67,-21 - 1593: 67,-21 + 1570: 64,-22 + 1571: 65,-22 + 1572: 66,-22 + 1573: 67,-22 + 1574: 64,-21 + 1575: 64,-21 + 1576: 65,-21 + 1577: 65,-21 + 1578: 66,-21 + 1579: 66,-21 + 1580: 67,-21 + 1581: 67,-21 - node: color: '#D381C996' id: WarnLineGreyscaleS decals: - 324: -47,-27 - 325: -46,-27 - 326: -45,-27 - 327: -44,-27 - 328: -43,-27 + 312: -47,-27 + 313: -46,-27 + 314: -45,-27 + 315: -44,-27 + 316: -43,-27 - node: color: '#DE3A3A96' id: WarnLineGreyscaleS decals: - 1578: 64,-20 - 1579: 65,-20 - 1580: 66,-20 - 1581: 67,-20 - 1594: 64,-21 - 1595: 64,-21 - 1596: 65,-21 - 1597: 65,-21 - 1598: 66,-21 - 1599: 66,-21 - 1600: 67,-21 - 1601: 67,-21 + 1566: 64,-20 + 1567: 65,-20 + 1568: 66,-20 + 1569: 67,-20 + 1582: 64,-21 + 1583: 64,-21 + 1584: 65,-21 + 1585: 65,-21 + 1586: 66,-21 + 1587: 66,-21 + 1588: 67,-21 + 1589: 67,-21 - node: color: '#EFB34196' id: WarnLineN decals: - 323: -41,-26 - 635: -21,55 - 636: -20,55 - 997: 18,69 - 998: 19,69 - 1009: 15,56 - 1010: 14,56 - 1118: 36,12 - 1119: 37,12 - 1120: 38,12 - 1234: -62,53 - 1235: -58,53 - 1278: -27,32 - 1279: -26,32 - 1280: -25,32 - 1281: -24,32 - 1282: -23,32 - 1283: -17,32 - 1284: -16,32 - 1285: -15,32 - 1286: -14,32 - 1287: -13,32 - 1431: -8,46 - 1460: -23,55 - 1461: -24,55 - 1462: -25,55 - 1463: -26,55 - 1464: -27,55 - 1465: -28,55 - 1466: -29,55 - 1487: 0,52 - 1492: -1,61 - 1493: 0,61 - 1494: 1,61 - 1504: 23,54 - 1505: 24,54 - 1602: 64,-22 - 1603: 65,-22 - 1604: 66,-22 - 1605: 67,-22 - 1633: 50,-17 - 1676: -43,-17 - 1677: -42,-17 - 1678: -41,-17 - 3269: 50,-20 - 3278: 2,44 - 3279: 3,44 - 3280: 1,44 - 3281: 0,44 - 3282: -1,44 - 3319: 22,54 + 311: -41,-26 + 623: -21,55 + 624: -20,55 + 985: 18,69 + 986: 19,69 + 997: 15,56 + 998: 14,56 + 1106: 36,12 + 1107: 37,12 + 1108: 38,12 + 1222: -62,53 + 1223: -58,53 + 1266: -27,32 + 1267: -26,32 + 1268: -25,32 + 1269: -24,32 + 1270: -23,32 + 1271: -17,32 + 1272: -16,32 + 1273: -15,32 + 1274: -14,32 + 1275: -13,32 + 1419: -8,46 + 1448: -23,55 + 1449: -24,55 + 1450: -25,55 + 1451: -26,55 + 1452: -27,55 + 1453: -28,55 + 1454: -29,55 + 1475: 0,52 + 1480: -1,61 + 1481: 0,61 + 1482: 1,61 + 1492: 23,54 + 1493: 24,54 + 1590: 64,-22 + 1591: 65,-22 + 1592: 66,-22 + 1593: 67,-22 + 1621: 50,-17 + 1664: -43,-17 + 1665: -42,-17 + 1666: -41,-17 + 3245: 50,-20 + 3254: 2,44 + 3255: 3,44 + 3256: 1,44 + 3257: 0,44 + 3258: -1,44 + 3295: 22,54 - node: color: '#FFFFFFFF' id: WarnLineN decals: - 4886: 9,72 - 4904: -28,19 - 5043: 88,3 - 5055: -47,-50 - 5056: -48,-50 - 5057: 10,-51 - 5058: 9,-51 - 5080: 55,0 - 5081: 56,0 - 5090: -44,26 - 5091: -43,26 - 5092: -42,26 - 5093: -41,26 - 5094: -40,26 - 5095: -39,26 - 5096: -38,26 - 5097: -37,26 + 4667: 9,72 + 4685: -28,19 + 4824: 88,3 + 4836: -47,-50 + 4837: -48,-50 + 4838: 10,-51 + 4839: 9,-51 + 4861: 55,0 + 4862: 56,0 + 4871: -44,26 + 4872: -43,26 + 4873: -42,26 + 4874: -41,26 + 4875: -40,26 + 4876: -39,26 + 4877: -38,26 + 4878: -37,26 - node: color: '#EFB34196' id: WarnLineS decals: - 320: -40,-27 - 321: -40,-28 - 322: -40,-29 - 493: 77,14 - 494: 77,13 - 495: 77,12 - 496: 84,15 - 497: 84,13 - 498: 84,12 - 500: 77,15 - 570: -8,45 - 571: -8,44 - 572: -8,43 - 647: -23,49 - 648: -23,50 - 737: 24,13 - 738: 24,12 - 1005: 18,55 - 1006: 18,56 - 1007: 16,53 - 1008: 16,55 - 1017: 16,54 - 1035: 17,64 - 1041: 18,56 - 1042: 18,55 - 1045: 14,63 - 1046: 14,64 - 1047: 14,65 - 1121: 35,13 - 1277: -18,33 - 1432: -8,45 - 1433: -8,44 - 1434: -8,43 - 1495: 2,60 - 1496: 2,59 - 1497: 2,58 - 1628: 48,-15 - 1629: 48,-14 - 3274: 49,-20 - 3275: 49,-19 - 3276: 30,66 - 3277: 30,66 - 3329: 84,14 - 4003: 22,55 - 4004: 22,54 - 4533: 29,79 - 4534: 29,79 - 4535: 29,78 - 4536: 29,78 - 4549: 26,79 - 4550: 26,79 - 4551: 26,78 - 4552: 26,78 - 4594: 26,54 - 4595: 26,55 + 308: -40,-27 + 309: -40,-28 + 310: -40,-29 + 481: 77,14 + 482: 77,13 + 483: 77,12 + 484: 84,15 + 485: 84,13 + 486: 84,12 + 488: 77,15 + 558: -8,45 + 559: -8,44 + 560: -8,43 + 635: -23,49 + 636: -23,50 + 725: 24,13 + 726: 24,12 + 993: 18,55 + 994: 18,56 + 995: 16,53 + 996: 16,55 + 1005: 16,54 + 1023: 17,64 + 1029: 18,56 + 1030: 18,55 + 1033: 14,63 + 1034: 14,64 + 1035: 14,65 + 1109: 35,13 + 1265: -18,33 + 1420: -8,45 + 1421: -8,44 + 1422: -8,43 + 1483: 2,60 + 1484: 2,59 + 1485: 2,58 + 1616: 48,-15 + 1617: 48,-14 + 3250: 49,-20 + 3251: 49,-19 + 3252: 30,66 + 3253: 30,66 + 3305: 84,14 + 3896: 22,55 + 3897: 22,54 + 4354: 29,79 + 4355: 29,79 + 4356: 29,78 + 4357: 29,78 + 4370: 26,79 + 4371: 26,79 + 4372: 26,78 + 4373: 26,78 + 4415: 26,54 + 4416: 26,55 - node: color: '#FFFFFFFF' id: WarnLineS decals: - 4901: -29,15 - 4902: -29,20 - 5031: 85,-11 - 5032: 85,-4 - 5045: -54,46 - 5046: -54,47 - 5051: -54,39 - 5052: -54,38 - 5082: -41,27 + 4682: -29,15 + 4683: -29,20 + 4812: 85,-11 + 4813: 85,-4 + 4826: -54,46 + 4827: -54,47 + 4832: -54,39 + 4833: -54,38 + 4863: -41,27 - node: color: '#EFB34196' id: WarnLineW decals: - 483: 35,-2 - 484: 36,-2 - 485: 37,-2 - 567: -21,33 - 568: -20,33 - 569: -19,33 - 639: -21,56 - 640: -20,56 - 641: -29,48 - 642: -28,48 - 643: -27,48 - 644: -26,48 - 645: -25,48 - 646: -24,48 - 709: 25,14 - 710: 26,14 - 711: 27,14 - 712: 28,14 - 993: 18,69 - 994: 19,69 - 995: 20,69 - 996: 21,69 - 999: 18,67 - 1000: 19,67 - 1001: 23,71 - 1002: 24,71 - 1013: 14,56 - 1014: 15,56 - 1036: 18,67 - 1037: 19,67 - 1038: 23,71 - 1039: 24,71 - 1115: 36,14 - 1116: 37,14 - 1117: 38,14 - 1233: -62,51 - 1273: -21,33 - 1274: -20,33 - 1275: -19,33 - 1435: -8,42 - 1486: 0,53 - 1488: -1,57 - 1502: 23,55 - 1503: 24,55 - 1606: 64,-20 - 1607: 65,-20 - 1608: 66,-20 - 1609: 67,-20 - 1634: 50,-19 - 3320: 22,55 - 3943: 0,57 - 3944: 1,57 + 471: 35,-2 + 472: 36,-2 + 473: 37,-2 + 555: -21,33 + 556: -20,33 + 557: -19,33 + 627: -21,56 + 628: -20,56 + 629: -29,48 + 630: -28,48 + 631: -27,48 + 632: -26,48 + 633: -25,48 + 634: -24,48 + 697: 25,14 + 698: 26,14 + 699: 27,14 + 700: 28,14 + 981: 18,69 + 982: 19,69 + 983: 20,69 + 984: 21,69 + 987: 18,67 + 988: 19,67 + 989: 23,71 + 990: 24,71 + 1001: 14,56 + 1002: 15,56 + 1024: 18,67 + 1025: 19,67 + 1026: 23,71 + 1027: 24,71 + 1103: 36,14 + 1104: 37,14 + 1105: 38,14 + 1221: -62,51 + 1261: -21,33 + 1262: -20,33 + 1263: -19,33 + 1423: -8,42 + 1474: 0,53 + 1476: -1,57 + 1490: 23,55 + 1491: 24,55 + 1594: 64,-20 + 1595: 65,-20 + 1596: 66,-20 + 1597: 67,-20 + 1622: 50,-19 + 3296: 22,55 + 3836: 0,57 + 3837: 1,57 - node: color: '#FFFFFFFF' id: WarnLineW decals: - 4891: 18,71 - 4892: 19,71 - 4893: 20,71 - 4894: 21,71 - 4895: 18,69 - 4896: 19,69 - 4897: 20,69 - 4898: 21,69 - 4905: -28,16 - 5003: 86,-3 - 5004: 85,-3 - 5005: 73,-3 - 5006: 72,-3 - 5044: 88,3 - 5053: -47,-50 - 5054: -48,-50 - 5059: 10,-51 - 5060: 9,-51 - 5069: 26,12 - 5070: -27,36 - 5071: -26,36 - 5084: -44,26 - 5085: -43,26 - 5086: -42,26 - 5087: -39,26 - 5088: -38,26 - 5089: -37,26 + 4672: 18,71 + 4673: 19,71 + 4674: 20,71 + 4675: 21,71 + 4676: 18,69 + 4677: 19,69 + 4678: 20,69 + 4679: 21,69 + 4686: -28,16 + 4784: 86,-3 + 4785: 85,-3 + 4786: 73,-3 + 4787: 72,-3 + 4825: 88,3 + 4834: -47,-50 + 4835: -48,-50 + 4840: 10,-51 + 4841: 9,-51 + 4850: 26,12 + 4851: -27,36 + 4852: -26,36 + 4865: -44,26 + 4866: -43,26 + 4867: -42,26 + 4868: -39,26 + 4869: -38,26 + 4870: -37,26 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNe decals: - 3571: -25,-19 - 3666: 13,-18 + 3464: -25,-19 + 3559: 13,-18 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerNw decals: - 3793: 30,-18 + 3686: 30,-18 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSe decals: - 3665: 13,-19 + 3558: 13,-19 - node: color: '#FFFFFFFF' id: WoodTrimThinCornerSw decals: - 3670: 9,-19 - 3798: 30,-23 + 3563: 9,-19 + 3691: 30,-23 - node: color: '#FFFFFFFF' id: WoodTrimThinEndN decals: - 3668: 9,-17 + 3561: 9,-17 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNe decals: - 3672: 9,-18 - 3926: -11,33 + 3565: 9,-18 + 3819: -11,33 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerNw decals: - 3924: -8,33 + 3817: -8,33 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSe decals: - 3925: -11,36 - 4490: -18,-10 - 4491: -18,-9 + 3818: -11,36 + 4311: -18,-10 + 4312: -18,-9 - node: color: '#FFFFFFFF' id: WoodTrimThinInnerSw decals: - 3923: -8,36 + 3816: -8,36 - node: color: '#FFFFFFFF' id: WoodTrimThinLineE decals: - 3574: -25,-20 - 3575: -25,-21 - 3917: -11,34 - 3918: -11,35 + 3467: -25,-20 + 3468: -25,-21 + 3810: -11,34 + 3811: -11,35 - node: color: '#FFFFFFFF' id: WoodTrimThinLineN decals: - 3446: -2,-46 - 3447: -1,-46 - 3448: 0,-46 - 3449: 1,-46 - 3450: -3,-42 - 3451: -2,-42 - 3452: -1,-42 - 3453: 0,-42 - 3454: 1,-42 - 3572: -26,-19 - 3573: -27,-19 - 3589: -21,-13 - 3667: 12,-18 - 3794: 31,-18 - 3795: 32,-18 - 3796: 33,-18 - 3797: 34,-18 - 3915: -10,33 - 3916: -9,33 + 3422: -2,-46 + 3423: -1,-46 + 3424: 0,-46 + 3425: 1,-46 + 3426: -3,-42 + 3427: -2,-42 + 3428: -1,-42 + 3429: 0,-42 + 3430: 1,-42 + 3465: -26,-19 + 3466: -27,-19 + 3482: -21,-13 + 3560: 12,-18 + 3687: 31,-18 + 3688: 32,-18 + 3689: 33,-18 + 3690: 34,-18 + 3808: -10,33 + 3809: -9,33 - node: color: '#FFFFFFFF' id: WoodTrimThinLineS decals: - 3455: -3,-44 - 3456: -2,-44 - 3457: -1,-44 - 3458: 0,-44 - 3459: 1,-44 - 3460: -3,-48 - 3461: -2,-48 - 3462: -1,-48 - 3463: 0,-48 - 3464: 1,-48 - 3465: -12,-32 - 3671: 12,-19 - 3799: 31,-23 - 3800: 32,-23 - 3801: 33,-23 - 3802: 34,-23 - 3921: -10,36 - 3922: -9,36 + 3431: -3,-44 + 3432: -2,-44 + 3433: -1,-44 + 3434: 0,-44 + 3435: 1,-44 + 3436: -3,-48 + 3437: -2,-48 + 3438: -1,-48 + 3439: 0,-48 + 3440: 1,-48 + 3441: -12,-32 + 3564: 12,-19 + 3692: 31,-23 + 3693: 32,-23 + 3694: 33,-23 + 3695: 34,-23 + 3814: -10,36 + 3815: -9,36 - node: color: '#FFFFFFFF' id: WoodTrimThinLineW decals: - 3440: -3,-42 - 3441: -3,-43 - 3442: -3,-44 - 3443: -3,-46 - 3444: -3,-47 - 3445: -3,-48 - 3583: -21,-13 - 3584: -21,-14 - 3585: -21,-15 - 3586: -21,-16 - 3587: -21,-17 - 3588: -21,-18 - 3669: 9,-18 - 3788: 30,-22 - 3789: 30,-21 - 3790: 30,-20 - 3791: 30,-19 - 3792: 23,-21 - 3919: -8,34 - 3920: -8,35 + 3416: -3,-42 + 3417: -3,-43 + 3418: -3,-44 + 3419: -3,-46 + 3420: -3,-47 + 3421: -3,-48 + 3476: -21,-13 + 3477: -21,-14 + 3478: -21,-15 + 3479: -21,-16 + 3480: -21,-17 + 3481: -21,-18 + 3562: 9,-18 + 3681: 30,-22 + 3682: 30,-21 + 3683: 30,-20 + 3684: 30,-19 + 3685: 23,-21 + 3812: -8,34 + 3813: -8,35 - node: color: '#9FED5896' id: bushsnowa1 decals: - 3207: -41.436035,-22.25985 - 3208: -41.283257,-23.079292 - 3209: -40.255478,-23.398739 - 3210: -40.019367,-18.10707 - 3211: -41.005478,-18.926516 - 3212: -43.061035,-18.00985 - 3213: -43.130478,-18.718182 - 3214: -43.07492,-19.940405 - 3215: -43.1027,-21.551517 - 3216: -41.880478,-23.204292 - 3217: -40.172146,-23.787628 - 3218: -41.11659,-23.75985 - 3219: -39.880478,-22.273739 - 3220: -40.130478,-19.079292 + 3183: -41.436035,-22.25985 + 3184: -41.283257,-23.079292 + 3185: -40.255478,-23.398739 + 3186: -40.019367,-18.10707 + 3187: -41.005478,-18.926516 + 3188: -43.061035,-18.00985 + 3189: -43.130478,-18.718182 + 3190: -43.07492,-19.940405 + 3191: -43.1027,-21.551517 + 3192: -41.880478,-23.204292 + 3193: -40.172146,-23.787628 + 3194: -41.11659,-23.75985 + 3195: -39.880478,-22.273739 + 3196: -40.130478,-19.079292 - node: color: '#9FED5896' id: bushsnowb3 decals: - 3567: 24.076597,-33.183323 - 3568: 23.937708,-34.09999 + 3460: 24.076597,-33.183323 + 3461: 23.937708,-34.09999 - node: color: '#A4DF8296' id: bushsnowb3 decals: - 1706: -7.3679967,-22.387566 - 1707: -9.20133,-22.69312 - 1708: -9.062441,-23.859787 - 1709: -7.2291064,-23.637566 - 1710: -8.423552,-23.276455 + 1694: -7.3679967,-22.387566 + 1695: -9.20133,-22.69312 + 1696: -9.062441,-23.859787 + 1697: -7.2291064,-23.637566 + 1698: -8.423552,-23.276455 - node: color: '#9FED5896' id: grasssnow07 decals: - 3333: 78.19461,7.941762 - 3334: 79.52794,7.9139843 + 3309: 78.19461,7.941762 + 3310: 79.52794,7.9139843 - node: color: '#60AC5863' id: grasssnow09 decals: - 3352: -12.979685,-40.336945 - 3353: -11.368574,-40.225834 - 3354: -11.4657955,-39.059166 - 3355: -13.701906,-39.198055 - 3356: -12.507462,-39.503613 - 3357: -12.799128,-40.614723 + 3328: -12.979685,-40.336945 + 3329: -11.368574,-40.225834 + 3330: -11.4657955,-39.059166 + 3331: -13.701906,-39.198055 + 3332: -12.507462,-39.503613 + 3333: -12.799128,-40.614723 - node: color: '#9FED587C' id: grasssnow09 decals: - 3351: -13.604685,-40.086945 + 3327: -13.604685,-40.086945 - node: color: '#60FF5D92' id: grasssnow10 decals: - 4690: -19.105085,3.5241327 - 4691: -19.957012,2.1050215 - 4692: -19.829224,0.3878975 + 4511: -19.105085,3.5241327 + 4512: -19.957012,2.1050215 + 4513: -19.829224,0.3878975 - node: color: '#9FED587C' id: grasssnow10 decals: - 3343: -13.5907955,-40.670277 - 3344: -12.229685,-40.475834 - 3345: -11.354685,-39.475834 - 3346: -13.813017,-39.350834 - 3347: -12.826906,-39.614723 - 3348: -11.271351,-40.698055 - 3349: -11.41024,-38.989723 - 3350: -12.979685,-38.961945 + 3319: -13.5907955,-40.670277 + 3320: -12.229685,-40.475834 + 3321: -11.354685,-39.475834 + 3322: -13.813017,-39.350834 + 3323: -12.826906,-39.614723 + 3324: -11.271351,-40.698055 + 3325: -11.41024,-38.989723 + 3326: -12.979685,-38.961945 - node: color: '#A4DF8296' id: grasssnow10 decals: - 1696: -7.4220443,-1.9321766 + 1684: -7.4220443,-1.9321766 - node: color: '#A4DF8296' id: grasssnowc1 decals: - 1697: -6.4220433,-1.9599552 + 1685: -6.4220433,-1.9599552 - node: color: '#60E2588B' id: grasssnowc3 decals: - 3372: -15.396351,-36.573055 - 3373: -17.549128,-36.656387 - 3374: -17.604685,-37.795277 - 3375: -16.007462,-37.8925 - 3376: -16.354685,-36.698055 - 3377: -15.299128,-37.6425 - 3378: -16.118574,-37.031387 + 3348: -15.396351,-36.573055 + 3349: -17.549128,-36.656387 + 3350: -17.604685,-37.795277 + 3351: -16.007462,-37.8925 + 3352: -16.354685,-36.698055 + 3353: -15.299128,-37.6425 + 3354: -16.118574,-37.031387 - node: cleanable: True color: '#800080FF' id: prolizard decals: - 4899: 27.413673,-33.665314 + 4680: 27.413673,-33.665314 - node: color: '#9FED5896' id: shop decals: - 3310: -4,-42 - 3311: -4,-48 + 3286: -4,-42 + 3287: -4,-48 type: DecalGrid - version: 2 data: @@ -8103,7 +7947,8 @@ entities: -9,-8: 0: 65535 -11,-10: - 0: 65535 + 6: 1 + 0: 65534 -11,-9: 0: 65535 -10,-10: @@ -8383,7 +8228,10 @@ entities: -9,-12: 0: 65535 -9,-11: - 0: 65535 + 0: 64751 + 8: 16 + 6: 256 + 9: 512 -8,-12: 0: 65535 -8,-11: @@ -10202,6 +10050,36 @@ entities: - 0 - 0 - 0 + - volume: 2500 + temperature: 293.15 + moles: + - 21.640223 + - 81.40846 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - volume: 2500 + temperature: 293.14993 + moles: + - 20.078888 + - 75.53487 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 chunkSize: 4 type: GridAtmosphere - type: OccluderTree @@ -10237,6 +10115,16 @@ entities: - pos: -9.519083,35.601566 parent: 82 type: Transform +- proto: ActionStethoscope + entities: + - uid: 18562 + components: + - flags: InContainer + type: MetaData + - parent: 17788 + type: Transform + - container: 17788 + type: EntityTargetAction - proto: AdvancedCapacitorStockPart entities: - uid: 15008 @@ -11350,13 +11238,29 @@ entities: pos: -40.5,-35.5 parent: 82 type: Transform - - devices: - - 15544 - - 14997 + - ShutdownSubscribers: + - 14886 - 14907 + - 2852 + - 20638 + - 7883 + - 2868 + - 24442 + - 24445 + - 24444 + - 24452 + type: DeviceNetwork + - devices: + - 24452 + - 24444 + - 24445 + - 24442 + - 2868 + - 7883 - 14886 - - 14896 - - 14895 + - 14907 + - 2852 + - 20638 type: DeviceList - uid: 24526 components: @@ -11408,22 +11312,43 @@ entities: - pos: -38.5,-29.5 parent: 82 type: Transform - - devices: - - 15411 - - 15410 - - 24581 - - 15503 - - 3592 - - 3597 - - 24449 + - ShutdownSubscribers: + - 24445 - 24458 - 24448 - 24454 - - 24452 - - 24444 + - 15410 + - 15411 - 24442 + - 24444 + - 24452 + - 3278 + - 2821 + - 15273 + - 15400 + - 3607 + - 3608 + - 14880 + - 14837 + type: DeviceNetwork + - devices: + - 15411 + - 15410 + - 24454 + - 24448 + - 24458 - 24445 - - 24441 + - 24442 + - 24444 + - 24452 + - 3278 + - 2821 + - 15273 + - 15400 + - 3607 + - 3608 + - 14880 + - 14837 type: DeviceList - uid: 24577 components: @@ -13881,11 +13806,6 @@ entities: type: Transform - proto: AirlockMaintMedLocked entities: - - uid: 6906 - components: - - pos: -48.5,-38.5 - parent: 82 - type: Transform - uid: 10245 components: - pos: -55.5,-33.5 @@ -13896,6 +13816,11 @@ entities: - pos: -55.5,-23.5 parent: 82 type: Transform + - uid: 22635 + components: + - pos: -46.5,-37.5 + parent: 82 + type: Transform - uid: 25244 components: - pos: -40.5,-45.5 @@ -13953,6 +13878,18 @@ entities: type: Transform - proto: AirlockMedicalGlassLocked entities: + - uid: 2746 + components: + - rot: 1.5707963267948966 rad + pos: -40.5,-40.5 + parent: 82 + type: Transform + - uid: 2756 + components: + - rot: 3.141592653589793 rad + pos: -37.5,-41.5 + parent: 82 + type: Transform - uid: 7860 components: - pos: -53.5,-31.5 @@ -14015,11 +13952,6 @@ entities: type: Transform - proto: AirlockMedicalLocked entities: - - uid: 8127 - components: - - pos: -34.5,-37.5 - parent: 82 - type: Transform - uid: 8128 components: - pos: -55.5,-29.5 @@ -18267,6 +18199,13 @@ entities: - pos: 17.470211,-0.54444814 parent: 82 type: Transform +- proto: Beaker + entities: + - uid: 15913 + components: + - pos: -43.321316,-40.53151 + parent: 82 + type: Transform - proto: Bed entities: - uid: 2135 @@ -18559,34 +18498,32 @@ entities: pos: -42.5,-28.5 parent: 82 type: Transform - - uid: 8029 + - uid: 14998 components: - rot: 1.5707963267948966 rad - pos: -43.5,-39.5 + pos: -39.5,-36.5 parent: 82 type: Transform - - uid: 25240 + - uid: 15521 components: - - rot: 1.5707963267948966 rad - pos: -43.5,-41.5 + - rot: -1.5707963267948966 rad + pos: -31.5,-39.5 parent: 82 type: Transform - - uid: 25241 + - uid: 16958 components: - - rot: 1.5707963267948966 rad - pos: -43.5,-43.5 + - pos: -35.5,-39.5 parent: 82 type: Transform - - uid: 25242 + - uid: 18574 components: - - rot: 1.5707963267948966 rad - pos: -37.5,-43.5 + - pos: -33.5,-39.5 parent: 82 type: Transform - - uid: 25243 + - uid: 22089 components: - rot: 1.5707963267948966 rad - pos: -37.5,-41.5 + pos: -39.5,-38.5 parent: 82 type: Transform - proto: BedsheetMime @@ -18825,7 +18762,7 @@ entities: - pos: 34.5,12.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497366.78 + - SecondsUntilStateChange: -507010.16 state: Opening type: Door - links: @@ -18836,7 +18773,7 @@ entities: - pos: 34.5,14.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497366.78 + - SecondsUntilStateChange: -507010.16 state: Opening type: Door - links: @@ -18863,7 +18800,7 @@ entities: - pos: 34.5,13.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497366.78 + - SecondsUntilStateChange: -507010.16 state: Opening type: Door - links: @@ -18890,7 +18827,7 @@ entities: - pos: 53.5,-25.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18901,7 +18838,7 @@ entities: - pos: 53.5,-26.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18912,7 +18849,7 @@ entities: - pos: 53.5,-27.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18923,7 +18860,7 @@ entities: - pos: 53.5,-28.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18934,7 +18871,7 @@ entities: - pos: 53.5,-29.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18945,7 +18882,7 @@ entities: - pos: 53.5,-30.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18956,7 +18893,7 @@ entities: - pos: 56.5,-25.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18967,7 +18904,7 @@ entities: - pos: 56.5,-26.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18978,7 +18915,7 @@ entities: - pos: 56.5,-27.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -18989,7 +18926,7 @@ entities: - pos: 56.5,-28.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -19000,7 +18937,7 @@ entities: - pos: 56.5,-29.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -19011,7 +18948,7 @@ entities: - pos: 56.5,-30.5 parent: 82 type: Transform - - SecondsUntilStateChange: -495631.72 + - SecondsUntilStateChange: -505275.1 state: Opening type: Door - links: @@ -19022,7 +18959,7 @@ entities: - pos: -21.5,50.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436286.66 + - SecondsUntilStateChange: -445930.03 state: Opening type: Door - links: @@ -19033,7 +18970,7 @@ entities: - pos: -21.5,48.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436286.66 + - SecondsUntilStateChange: -445930.03 state: Opening type: Door - links: @@ -19044,7 +18981,7 @@ entities: - pos: -21.5,49.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436286.66 + - SecondsUntilStateChange: -445930.03 state: Opening type: Door - links: @@ -19055,7 +18992,7 @@ entities: - pos: -21.5,47.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436286.66 + - SecondsUntilStateChange: -445930.03 state: Opening type: Door - links: @@ -19120,7 +19057,7 @@ entities: - pos: 23.5,14.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497428.03 + - SecondsUntilStateChange: -507071.4 state: Closing type: Door - links: @@ -19131,7 +19068,7 @@ entities: - pos: 23.5,13.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497428.03 + - SecondsUntilStateChange: -507071.4 state: Closing type: Door - links: @@ -19142,7 +19079,7 @@ entities: - pos: 23.5,12.5 parent: 82 type: Transform - - SecondsUntilStateChange: -497428.03 + - SecondsUntilStateChange: -507071.4 state: Closing type: Door - links: @@ -19157,11 +19094,6 @@ entities: type: Transform - proto: Bloodpack entities: - - uid: 1890 - components: - - pos: -31.416758,-37.230022 - parent: 82 - type: Transform - uid: 8348 components: - pos: -23.740927,-27.426304 @@ -19172,16 +19104,11 @@ entities: - pos: -23.55774,-27.309635 parent: 82 type: Transform - - uid: 16958 - components: - - pos: -31.219885,-37.426895 - parent: 82 - type: Transform - proto: BodyBag_Folded entities: - uid: 2918 components: - - pos: -35.591175,-43.576096 + - pos: -32.606377,-44.38219 parent: 82 type: Transform - air: @@ -19204,7 +19131,7 @@ entities: type: EntityStorage - uid: 2919 components: - - pos: -35.368954,-43.728874 + - pos: -32.32277,-44.43378 parent: 82 type: Transform - air: @@ -19850,7 +19777,7 @@ entities: type: Transform - uid: 3280 components: - - pos: -35.022633,-34.322704 + - pos: -35.018135,-34.250908 parent: 82 type: Transform - proto: BoxSyringe @@ -20052,11 +19979,56 @@ entities: - pos: -40.5,-45.5 parent: 82 type: Transform + - uid: 2729 + components: + - pos: -35.5,-43.5 + parent: 82 + type: Transform + - uid: 2730 + components: + - pos: -37.5,-43.5 + parent: 82 + type: Transform + - uid: 2732 + components: + - pos: -36.5,-43.5 + parent: 82 + type: Transform + - uid: 2736 + components: + - pos: -42.5,-41.5 + parent: 82 + type: Transform + - uid: 2740 + components: + - pos: -42.5,-39.5 + parent: 82 + type: Transform + - uid: 2741 + components: + - pos: -42.5,-40.5 + parent: 82 + type: Transform + - uid: 2743 + components: + - pos: -42.5,-42.5 + parent: 82 + type: Transform + - uid: 2747 + components: + - pos: -40.5,-40.5 + parent: 82 + type: Transform - uid: 2787 components: - pos: 26.5,27.5 parent: 82 type: Transform + - uid: 2837 + components: + - pos: -37.5,-42.5 + parent: 82 + type: Transform - uid: 2994 components: - pos: 14.5,-18.5 @@ -21723,21 +21695,6 @@ entities: type: Transform - enabled: True type: AmbientSound - - uid: 13987 - components: - - pos: -38.5,-44.5 - parent: 82 - type: Transform - - uid: 13988 - components: - - pos: -37.5,-41.5 - parent: 82 - type: Transform - - uid: 13990 - components: - - pos: -37.5,-42.5 - parent: 82 - type: Transform - uid: 14024 components: - pos: 31.5,-35.5 @@ -23181,6 +23138,26 @@ entities: type: Transform - enabled: True type: AmbientSound + - uid: 14899 + components: + - pos: -41.5,-40.5 + parent: 82 + type: Transform + - uid: 14900 + components: + - pos: -41.5,-44.5 + parent: 82 + type: Transform + - uid: 14901 + components: + - pos: -42.5,-44.5 + parent: 82 + type: Transform + - uid: 14902 + components: + - pos: -42.5,-43.5 + parent: 82 + type: Transform - uid: 14980 components: - pos: 27.5,25.5 @@ -36612,11 +36589,6 @@ entities: - pos: -39.5,-40.5 parent: 82 type: Transform - - uid: 18562 - components: - - pos: -39.5,-44.5 - parent: 82 - type: Transform - uid: 18563 components: - pos: -40.5,-44.5 @@ -36627,59 +36599,9 @@ entities: - pos: -40.5,-44.5 parent: 82 type: Transform - - uid: 18565 - components: - - pos: -41.5,-44.5 - parent: 82 - type: Transform - - uid: 18566 - components: - - pos: -42.5,-44.5 - parent: 82 - type: Transform - - uid: 18567 - components: - - pos: -42.5,-43.5 - parent: 82 - type: Transform - - uid: 18568 - components: - - pos: -42.5,-42.5 - parent: 82 - type: Transform - - uid: 18569 - components: - - pos: -42.5,-41.5 - parent: 82 - type: Transform - - uid: 18570 - components: - - pos: -42.5,-40.5 - parent: 82 - type: Transform - - uid: 18571 - components: - - pos: -42.5,-39.5 - parent: 82 - type: Transform - uid: 18572 components: - - pos: -42.5,-38.5 - parent: 82 - type: Transform - - uid: 18573 - components: - - pos: -42.5,-37.5 - parent: 82 - type: Transform - - uid: 18574 - components: - - pos: -41.5,-37.5 - parent: 82 - type: Transform - - uid: 18575 - components: - - pos: -40.5,-37.5 + - pos: -37.5,-41.5 parent: 82 type: Transform - uid: 18576 @@ -36712,11 +36634,6 @@ entities: - pos: -34.5,-39.5 parent: 82 type: Transform - - uid: 18582 - components: - - pos: -34.5,-40.5 - parent: 82 - type: Transform - uid: 18583 components: - pos: -34.5,-41.5 @@ -36907,16 +36824,6 @@ entities: type: Transform - enabled: True type: AmbientSound - - uid: 18616 - components: - - pos: -37.5,-44.5 - parent: 82 - type: Transform - - uid: 18617 - components: - - pos: -37.5,-43.5 - parent: 82 - type: Transform - uid: 18619 components: - pos: -38.5,-46.5 @@ -62205,12 +62112,6 @@ entities: pos: 31.5,56.5 parent: 82 type: Transform - - uid: 14989 - components: - - rot: 3.141592653589793 rad - pos: -50.5,-37.5 - parent: 82 - type: Transform - uid: 15274 components: - pos: 36.5,68.5 @@ -62394,11 +62295,6 @@ entities: - pos: 40.5,48.5 parent: 82 type: Transform - - uid: 18742 - components: - - pos: -48.5,-37.5 - parent: 82 - type: Transform - uid: 18805 components: - pos: 25.5,30.5 @@ -64927,11 +64823,6 @@ entities: pos: -1.5,-13.5 parent: 82 type: Transform - - uid: 24818 - components: - - pos: -49.5,-37.5 - parent: 82 - type: Transform - uid: 24882 components: - rot: 3.141592653589793 rad @@ -65138,9 +65029,13 @@ entities: entities: - uid: 2921 components: - - pos: -35.730064,-44.451096 - parent: 82 + - flags: InContainer + type: MetaData + - parent: 18569 type: Transform + - canCollide: False + type: Physics + - type: InsideEntityStorage - proto: Chair entities: - uid: 2660 @@ -66094,6 +65989,12 @@ entities: pos: -21.5,-39.5 parent: 82 type: Transform + - uid: 2842 + components: + - rot: -1.5707963267948966 rad + pos: -38.5,-38.5 + parent: 82 + type: Transform - uid: 3358 components: - rot: 1.5707963267948966 rad @@ -66222,6 +66123,11 @@ entities: pos: -60.5,48.5 parent: 82 type: Transform + - uid: 8813 + components: + - pos: -33.5,-38.5 + parent: 82 + type: Transform - uid: 8816 components: - rot: 3.141592653589793 rad @@ -66411,18 +66317,6 @@ entities: pos: -32.5,-28.5 parent: 82 type: Transform - - uid: 2846 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-44.5 - parent: 82 - type: Transform - - uid: 2847 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-42.5 - parent: 82 - type: Transform - uid: 3299 components: - rot: 1.5707963267948966 rad @@ -66504,24 +66398,6 @@ entities: pos: 43.5,-13.5 parent: 82 type: Transform - - uid: 25304 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-40.5 - parent: 82 - type: Transform - - uid: 25305 - components: - - rot: -1.5707963267948966 rad - pos: -37.5,-44.5 - parent: 82 - type: Transform - - uid: 25306 - components: - - rot: -1.5707963267948966 rad - pos: -37.5,-42.5 - parent: 82 - type: Transform - proto: ChairWood entities: - uid: 91 @@ -66845,16 +66721,6 @@ entities: type: Transform - proto: CheapRollerBed entities: - - uid: 2859 - components: - - pos: -39.493538,-40.522873 - parent: 82 - type: Transform - - uid: 2861 - components: - - pos: -38.48993,-40.508984 - parent: 82 - type: Transform - uid: 16946 components: - pos: -47.5,-32.5 @@ -70291,7 +70157,7 @@ entities: entities: - uid: 2870 components: - - pos: -35.49941,-43.281456 + - pos: -32.620266,-44.253162 parent: 82 type: Transform - proto: ClothingBackpackDuffelSyndicateCostumeClown @@ -70376,7 +70242,7 @@ entities: type: Transform - uid: 11227 components: - - pos: -33.885056,-34.490807 + - pos: -35.57847,-38.19613 parent: 82 type: Transform - uid: 19126 @@ -70489,7 +70355,7 @@ entities: entities: - uid: 11228 components: - - pos: -33.593388,-34.379696 + - pos: -35.475338,-38.505672 parent: 82 type: Transform - proto: ClothingHandsGlovesMercFingerless @@ -70501,9 +70367,9 @@ entities: type: Transform - proto: ClothingHandsGlovesNitrile entities: - - uid: 11205 + - uid: 2831 components: - - pos: -35.628624,-39.721123 + - pos: -36.487114,-42.538757 parent: 82 type: Transform - uid: 11214 @@ -70649,13 +70515,6 @@ entities: - pos: -9.8989315,-53.441345 parent: 82 type: Transform -- proto: ClothingHeadHatParamedicsoftFlipped - entities: - - uid: 1889 - components: - - pos: -31.613634,-37.426895 - parent: 82 - type: Transform - proto: ClothingHeadHatPwig entities: - uid: 25136 @@ -70698,9 +70557,9 @@ entities: type: Transform - proto: ClothingHeadHatSurgcapPurple entities: - - uid: 2869 + - uid: 15499 components: - - pos: -35.69385,-39.40979 + - pos: -36.64181,-42.24211 parent: 82 type: Transform - proto: ClothingHeadHatUshanka @@ -70790,12 +70649,12 @@ entities: entities: - uid: 11209 components: - - pos: -34.49878,-34.416466 + - pos: -18.541143,-30.567162 parent: 82 type: Transform - uid: 11210 components: - - pos: -34.290443,-34.20813 + - pos: -18.747404,-30.425285 parent: 82 type: Transform - proto: ClothingHeadSafari @@ -71016,6 +70875,13 @@ entities: - pos: 22.490013,27.553314 parent: 82 type: Transform +- proto: ClothingNeckScarfStripedLightBlue + entities: + - uid: 18740 + components: + - pos: -43.695164,-41.07321 + parent: 82 + type: Transform - proto: ClothingNeckScarfStripedZebra entities: - uid: 21528 @@ -71025,21 +70891,24 @@ entities: type: Transform - proto: ClothingNeckStethoscope entities: - - uid: 2707 - components: - - pos: -42.43948,-39.42413 - parent: 82 - type: Transform - uid: 11012 components: - pos: -26.4877,-35.33183 parent: 82 type: Transform - - uid: 11212 + - uid: 17788 components: - - pos: -42.49492,-43.470898 + - pos: -38.522915,-36.380253 parent: 82 type: Transform + - actionEntity: 18562 + type: Stethoscope + - type: ActionsContainer + - containers: + actions: !type:Container + ents: + - 18562 + type: ContainerContainer - uid: 25224 components: - pos: -42.38529,-34.390274 @@ -71758,9 +71627,10 @@ entities: type: DeviceLinkSource - proto: computerBodyScanner entities: - - uid: 2917 + - uid: 20641 components: - - pos: -33.5,-43.5 + - rot: 3.141592653589793 rad + pos: -33.5,-44.5 parent: 82 type: Transform - proto: ComputerBroken @@ -72988,9 +72858,9 @@ entities: type: EntityStorage - proto: CrateMedicalSupplies entities: - - uid: 2981 + - uid: 1890 components: - - pos: -37.5,-37.5 + - pos: -43.5,-39.5 parent: 82 type: Transform - air: @@ -72998,8 +72868,8 @@ entities: immutable: False temperature: 293.1496 moles: - - 1.6971024 - - 6.3843384 + - 1.7459903 + - 6.568249 - 0 - 0 - 0 @@ -73013,18 +72883,18 @@ entities: type: EntityStorage - proto: CrateMedicalSurgery entities: - - uid: 2866 + - uid: 18569 components: - - pos: -35.5,-42.5 + - pos: -34.5,-41.5 parent: 82 type: Transform - air: volume: 200 immutable: False - temperature: 293.1496 + temperature: 293.14957 moles: - - 1.6971024 - - 6.3843384 + - 1.7459903 + - 6.568249 - 0 - 0 - 0 @@ -73036,6 +72906,20 @@ entities: - 0 - 0 type: EntityStorage + - containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 2922 + - 2920 + - 2923 + - 2921 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null + type: ContainerContainer - proto: CrateNPCBee entities: - uid: 22551 @@ -73297,9 +73181,14 @@ entities: type: Transform - proto: CryoPod entities: - - uid: 15502 + - uid: 14999 components: - - pos: -47.5,-36.5 + - pos: -39.5,-43.5 + parent: 82 + type: Transform + - uid: 15421 + components: + - pos: -43.5,-43.5 parent: 82 type: Transform - proto: CryostasisBeaker @@ -73319,6 +73208,13 @@ entities: - pos: -46.362053,-24.766727 parent: 82 type: Transform +- proto: CryoxadoneBeakerSmall + entities: + - uid: 15001 + components: + - pos: -43.6436,-40.338047 + parent: 82 + type: Transform - proto: CultAltarSpawner entities: - uid: 10264 @@ -73368,6 +73264,12 @@ entities: type: Transform - proto: DefibrillatorCabinetFilled entities: + - uid: 2849 + components: + - rot: 1.5707963267948966 rad + pos: -40.5,-37.5 + parent: 82 + type: Transform - uid: 4217 components: - rot: -1.5707963267948966 rad @@ -73472,11 +73374,6 @@ entities: - pos: 46.5,38.5 parent: 82 type: Transform - - uid: 19812 - components: - - pos: -40.5,-38.5 - parent: 82 - type: Transform - uid: 19816 components: - rot: 3.141592653589793 rad @@ -73505,6 +73402,12 @@ entities: - pos: -11.5,-1.5 parent: 82 type: Transform + - uid: 22362 + components: + - rot: 3.141592653589793 rad + pos: -35.5,-40.5 + parent: 82 + type: Transform - proto: DeployableBarrier entities: - uid: 11502 @@ -81191,9 +81094,13 @@ entities: entities: - uid: 2923 components: - - pos: -35.452286,-44.437206 - parent: 82 + - flags: InContainer + type: MetaData + - parent: 18569 type: Transform + - canCollide: False + type: Physics + - type: InsideEntityStorage - proto: DrinkBottleCognac entities: - uid: 11916 @@ -81280,6 +81187,13 @@ entities: - pos: -13.670343,-6.8330545 parent: 82 type: Transform +- proto: DrinkHotCoco + entities: + - uid: 22678 + components: + - pos: -43.243965,-41.047417 + parent: 82 + type: Transform - proto: DrinkLean entities: - uid: 1278 @@ -84186,12 +84100,18 @@ entities: - pos: -40.5,-28.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - uid: 3608 components: - rot: 1.5707963267948966 rad pos: -42.5,-26.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - uid: 6939 components: - rot: 1.5707963267948966 rad @@ -84518,18 +84438,27 @@ entities: pos: -29.5,-31.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - uid: 24454 components: - rot: 1.5707963267948966 rad pos: -29.5,-32.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - uid: 24458 components: - rot: 1.5707963267948966 rad pos: -29.5,-30.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - uid: 25437 components: - rot: 1.5707963267948966 rad @@ -85922,16 +85851,28 @@ entities: - pos: -32.5,-33.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24525 + - 24530 + type: DeviceNetwork - uid: 24444 components: - pos: -36.5,-33.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24525 + - 24530 + type: DeviceNetwork - uid: 24445 components: - pos: -31.5,-33.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24525 + - 24530 + type: DeviceNetwork - uid: 24449 components: - pos: -36.5,-29.5 @@ -85942,6 +85883,10 @@ entities: - pos: -37.5,-33.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24525 + - 24530 + type: DeviceNetwork - uid: 24501 components: - rot: 3.141592653589793 rad @@ -86523,6 +86468,13 @@ entities: - pos: -26.65648,-14.25965 parent: 82 type: Transform +- proto: FoodSnackChocolate + entities: + - uid: 22748 + components: + - pos: -43.308422,-41.460144 + parent: 82 + type: Transform - proto: FoodSnackSus entities: - uid: 25114 @@ -86616,6 +86568,16 @@ entities: - pos: -39.5,54.5 parent: 82 type: Transform +- proto: GasFilter + entities: + - uid: 8814 + components: + - rot: 3.141592653589793 rad + pos: -41.5,-42.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - proto: GasFilterFlipped entities: - uid: 729 @@ -87179,14 +87141,37 @@ entities: type: AtmosPipeColor - enabled: True type: AmbientSound - - uid: 3138 + - uid: 2734 + components: + - rot: -1.5707963267948966 rad + pos: -39.5,-42.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2735 + components: + - pos: -41.5,-41.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor + - uid: 2853 components: - rot: 3.141592653589793 rad - pos: -50.5,-37.5 + pos: -37.5,-43.5 parent: 82 type: Transform - - enabled: True - type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 2995 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-36.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 5608 components: - pos: 13.5,31.5 @@ -87202,6 +87187,14 @@ entities: type: Transform - enabled: True type: AmbientSound + - uid: 8127 + components: + - rot: 3.141592653589793 rad + pos: -36.5,-42.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 8321 components: - rot: 1.5707963267948966 rad @@ -87376,12 +87369,24 @@ entities: - pos: -9.5,-34.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 10249 + components: + - rot: 3.141592653589793 rad + pos: -43.5,-44.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - uid: 11154 components: - rot: 3.141592653589793 rad pos: -10.5,-34.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 11921 components: - pos: 47.5,18.5 @@ -87598,6 +87603,8 @@ entities: pos: -60.5,37.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 13418 components: - pos: -15.5,18.5 @@ -87817,20 +87824,13 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 14893 - components: - - rot: 3.141592653589793 rad - pos: -33.5,-41.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - uid: 14894 components: - - pos: -32.5,-41.5 + - rot: -1.5707963267948966 rad + pos: -39.5,-44.5 parent: 82 type: Transform - - color: '#990000FF' + - color: '#03FCD3FF' type: AtmosPipeColor - uid: 14939 components: @@ -87857,14 +87857,6 @@ entities: type: AtmosPipeColor - enabled: True type: AmbientSound - - uid: 14999 - components: - - rot: -1.5707963267948966 rad - pos: -37.5,-39.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 15270 components: - pos: -40.5,-26.5 @@ -87950,14 +87942,6 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 15520 - components: - - rot: 1.5707963267948966 rad - pos: -39.5,-36.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - uid: 18494 components: - pos: 31.5,51.5 @@ -88103,10 +88087,10 @@ entities: pos: 53.5,-42.5 parent: 82 type: Transform - - uid: 25132 + - uid: 22761 components: - - rot: -1.5707963267948966 rad - pos: -47.5,-37.5 + - rot: 1.5707963267948966 rad + pos: -42.5,-39.5 parent: 82 type: Transform - color: '#03FCD3FF' @@ -88117,12 +88101,16 @@ entities: pos: -29.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26211 components: - rot: 3.141592653589793 rad pos: -29.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - proto: GasPipeFourway entities: - uid: 904 @@ -88163,6 +88151,8 @@ entities: - pos: -21.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 10401 components: - pos: 33.5,25.5 @@ -90154,6 +90144,14 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor + - uid: 2297 + components: + - rot: 1.5707963267948966 rad + pos: -38.5,-40.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 2786 components: - rot: 3.141592653589793 rad @@ -90162,32 +90160,130 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 3249 + - uid: 2820 + components: + - pos: -48.5,-33.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2833 components: - rot: 1.5707963267948966 rad - pos: 34.5,19.5 + pos: -39.5,-40.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 2838 + components: + - rot: 1.5707963267948966 rad + pos: -38.5,-38.5 parent: 82 type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 3254 + - uid: 2843 components: - rot: 1.5707963267948966 rad - pos: 35.5,19.5 + pos: -34.5,-42.5 parent: 82 type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 3278 + - uid: 2851 components: - pos: -50.5,-33.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 2861 + components: + - pos: -36.5,-39.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2997 + components: + - rot: 3.141592653589793 rad + pos: -36.5,-41.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - enabled: True + type: AmbientSound + - uid: 3032 + components: + - pos: -36.5,-37.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 3062 + components: + - rot: 3.141592653589793 rad + pos: -37.5,-39.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 3074 + components: + - rot: 1.5707963267948966 rad + pos: -37.5,-38.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 3138 + components: + - pos: -50.5,-32.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 3192 + components: + - rot: -1.5707963267948966 rad + pos: -34.5,-35.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 3193 + components: + - rot: -1.5707963267948966 rad + pos: -33.5,-36.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 3249 + components: + - rot: 1.5707963267948966 rad + pos: 34.5,19.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 3254 + components: + - rot: 1.5707963267948966 rad + pos: 35.5,19.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 3282 components: - - pos: -50.5,-34.5 + - pos: -50.5,-31.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 3389 components: - rot: -1.5707963267948966 rad @@ -90217,11 +90313,15 @@ entities: - pos: 85.5,-1.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 5725 components: - pos: 85.5,-2.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 6523 components: - rot: -1.5707963267948966 rad @@ -90258,22 +90358,30 @@ entities: pos: 18.5,70.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7293 components: - rot: 3.141592653589793 rad pos: 18.5,71.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7335 components: - pos: 19.5,70.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7336 components: - pos: 19.5,71.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7401 components: - pos: 12.5,65.5 @@ -90284,157 +90392,227 @@ entities: - pos: -9.5,-37.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7695 components: - pos: -9.5,-40.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7756 components: - pos: 73.5,-1.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7757 components: - pos: 73.5,-2.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7758 components: - pos: 73.5,0.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7759 components: - pos: 73.5,-0.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7760 components: - pos: 73.5,-5.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7761 components: - pos: 73.5,-6.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7762 components: - pos: 73.5,-3.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7763 components: - pos: 73.5,-4.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7764 components: - pos: 72.5,0.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7765 components: - pos: 72.5,-0.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7769 components: - pos: 72.5,-1.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7770 components: - pos: 72.5,-3.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7771 components: - pos: 72.5,-4.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7792 components: - pos: 85.5,-5.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7811 components: - pos: 86.5,0.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7812 components: - pos: 86.5,-0.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7813 components: - pos: 86.5,-1.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7814 components: - pos: 86.5,-2.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7815 components: - pos: 85.5,-0.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7816 components: - pos: 86.5,-3.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7817 components: - pos: 86.5,-4.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7818 components: - pos: 86.5,-5.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7819 components: - pos: 86.5,-6.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 7825 components: - pos: 85.5,-4.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7829 components: - pos: 72.5,-5.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7841 components: - pos: 72.5,-2.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7843 components: - pos: 85.5,-3.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7847 components: - pos: 85.5,0.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 8001 components: - rot: 3.141592653589793 rad pos: -57.5,36.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 8029 + components: + - rot: 3.141592653589793 rad + pos: -36.5,-40.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 8036 components: - rot: 1.5707963267948966 rad @@ -90443,6 +90621,14 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor + - uid: 8249 + components: + - rot: 3.141592653589793 rad + pos: -37.5,-41.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 8798 components: - pos: 28.5,11.5 @@ -91961,16 +92147,22 @@ entities: - pos: -9.5,-39.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 10160 components: - pos: -9.5,-38.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 10161 components: - pos: -9.5,-36.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 10272 components: - pos: 31.5,13.5 @@ -92048,6 +92240,8 @@ entities: - pos: -9.5,-35.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 10632 components: - pos: 0.5,20.5 @@ -92077,17 +92271,62 @@ entities: pos: -60.5,36.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 11002 + components: + - rot: 3.141592653589793 rad + pos: -42.5,-42.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - uid: 11183 components: - pos: -9.5,-41.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 11184 components: - rot: 1.5707963267948966 rad pos: -10.5,-42.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 11208 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-43.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 11217 + components: + - pos: -39.5,-40.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 11219 + components: + - pos: -39.5,-39.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 11223 + components: + - pos: -39.5,-41.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - enabled: True + type: AmbientSound - uid: 11539 components: - rot: 1.5707963267948966 rad @@ -92109,6 +92348,8 @@ entities: pos: -59.5,36.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 11919 components: - pos: 47.5,16.5 @@ -96265,6 +96506,8 @@ entities: pos: -58.5,37.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 13308 components: - rot: 3.141592653589793 rad @@ -96448,6 +96691,8 @@ entities: pos: -59.5,37.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 13339 components: - pos: -57.5,38.5 @@ -100133,6 +100378,14 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor + - uid: 13986 + components: + - rot: 3.141592653589793 rad + pos: -37.5,-42.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 14145 components: - pos: 21.5,-37.5 @@ -102653,85 +102906,29 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 14889 - components: - - pos: -33.5,-37.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - - enabled: True - type: AmbientSound - uid: 14890 components: - - pos: -33.5,-38.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - - uid: 14891 - components: - - pos: -33.5,-39.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - - uid: 14892 - components: - - pos: -33.5,-40.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - - enabled: True - type: AmbientSound - - uid: 14897 - components: - - rot: 3.141592653589793 rad - pos: -34.5,-41.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - - uid: 14898 - components: - - rot: 3.141592653589793 rad - pos: -34.5,-40.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - - uid: 14899 - components: - - rot: 3.141592653589793 rad - pos: -34.5,-39.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - - uid: 14900 - components: - - rot: 3.141592653589793 rad - pos: -34.5,-38.5 + - rot: 1.5707963267948966 rad + pos: -40.5,-40.5 parent: 82 type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 14901 + - uid: 14892 components: - rot: 3.141592653589793 rad - pos: -34.5,-37.5 + pos: -42.5,-43.5 parent: 82 type: Transform - - color: '#0055CCFF' + - color: '#03FCD3FF' type: AtmosPipeColor - - uid: 14902 + - uid: 14893 components: - - rot: 3.141592653589793 rad - pos: -34.5,-36.5 + - rot: 1.5707963267948966 rad + pos: -40.5,-44.5 parent: 82 type: Transform - - color: '#0055CCFF' + - color: '#03FCD3FF' type: AtmosPipeColor - uid: 14904 components: @@ -103075,14 +103272,6 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 14994 - components: - - rot: -1.5707963267948966 rad - pos: -36.5,-36.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - uid: 14995 components: - rot: -1.5707963267948966 rad @@ -103099,14 +103288,6 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 14998 - components: - - rot: -1.5707963267948966 rad - pos: -38.5,-39.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 15000 components: - rot: 3.141592653589793 rad @@ -103115,14 +103296,6 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 15001 - components: - - rot: 3.141592653589793 rad - pos: -37.5,-37.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 15271 components: - rot: -1.5707963267948966 rad @@ -103578,59 +103751,62 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 15499 + - uid: 15911 components: - - rot: 3.141592653589793 rad - pos: -48.5,-33.5 + - rot: 1.5707963267948966 rad + pos: -34.5,-43.5 parent: 82 type: Transform - - color: '#990000FF' + - color: '#0055CCFF' type: AtmosPipeColor - - uid: 15518 + - uid: 16878 components: - - rot: -1.5707963267948966 rad - pos: -37.5,-36.5 + - pos: -26.5,28.5 parent: 82 type: Transform - - color: '#990000FF' + - color: '#0055CCFF' type: AtmosPipeColor - - uid: 15519 + - uid: 16914 components: - rot: -1.5707963267948966 rad - pos: -38.5,-36.5 + pos: 22.5,60.5 parent: 82 type: Transform - - color: '#990000FF' + - color: '#0055CCFF' type: AtmosPipeColor - - uid: 15521 + - uid: 16917 components: - - pos: -39.5,-37.5 + - rot: -1.5707963267948966 rad + pos: 24.5,60.5 parent: 82 type: Transform - - color: '#990000FF' + - color: '#0055CCFF' type: AtmosPipeColor - - uid: 16878 + - uid: 18567 components: - - pos: -26.5,28.5 + - rot: 1.5707963267948966 rad + pos: -35.5,-42.5 parent: 82 type: Transform - - color: '#0055CCFF' + - color: '#990000FF' type: AtmosPipeColor - - uid: 16914 + - enabled: True + type: AmbientSound + - uid: 18571 components: - - rot: -1.5707963267948966 rad - pos: 22.5,60.5 + - rot: 1.5707963267948966 rad + pos: -35.5,-43.5 parent: 82 type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 16917 + - uid: 18742 components: - - rot: -1.5707963267948966 rad - pos: 24.5,60.5 + - rot: 3.141592653589793 rad + pos: -41.5,-43.5 parent: 82 type: Transform - - color: '#0055CCFF' + - color: '#03FCD3FF' type: AtmosPipeColor - uid: 18827 components: @@ -105827,20 +106003,6 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 20640 - components: - - pos: -50.5,-36.5 - parent: 82 - type: Transform - - color: '#03FCD3FF' - type: AtmosPipeColor - - uid: 20641 - components: - - pos: -48.5,-36.5 - parent: 82 - type: Transform - - color: '#03FCD3FF' - type: AtmosPipeColor - uid: 22443 components: - rot: 3.141592653589793 rad @@ -106057,16 +106219,6 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 25656 - components: - - pos: -50.5,-31.5 - parent: 82 - type: Transform - - uid: 25657 - components: - - pos: -50.5,-32.5 - parent: 82 - type: Transform - uid: 25800 components: - pos: 29.5,77.5 @@ -106107,72 +106259,96 @@ entities: pos: -24.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26201 components: - rot: -1.5707963267948966 rad pos: -25.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26202 components: - rot: -1.5707963267948966 rad pos: -26.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26203 components: - rot: -1.5707963267948966 rad pos: -27.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26204 components: - rot: -1.5707963267948966 rad pos: -22.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26205 components: - rot: -1.5707963267948966 rad pos: -23.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26206 components: - rot: -1.5707963267948966 rad pos: -24.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26207 components: - rot: -1.5707963267948966 rad pos: -25.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26208 components: - rot: -1.5707963267948966 rad pos: -26.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26209 components: - rot: -1.5707963267948966 rad pos: -27.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26238 components: - rot: 1.5707963267948966 rad pos: -28.5,18.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 26239 components: - rot: 1.5707963267948966 rad pos: -28.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - proto: GasPipeTJunction entities: - uid: 344 @@ -106582,16 +106758,52 @@ entities: type: AtmosPipeColor - enabled: True type: AmbientSound - - uid: 3062 + - uid: 2540 components: - - rot: 3.141592653589793 rad - pos: -49.5,-37.5 + - rot: 1.5707963267948966 rad + pos: -42.5,-40.5 parent: 82 type: Transform - color: '#03FCD3FF' type: AtmosPipeColor - - enabled: True - type: AmbientSound + - uid: 2848 + components: + - pos: -48.5,-32.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2850 + components: + - rot: 1.5707963267948966 rad + pos: -39.5,-38.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2859 + components: + - rot: -1.5707963267948966 rad + pos: -36.5,-38.5 + parent: 82 + type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2863 + components: + - pos: -50.5,-30.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 3030 + components: + - rot: -1.5707963267948966 rad + pos: -37.5,-37.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 3245 components: - rot: -1.5707963267948966 rad @@ -106797,12 +107009,24 @@ entities: pos: -23.5,17.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 10983 components: - rot: -1.5707963267948966 rad pos: -57.5,37.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 11001 + components: + - rot: 3.141592653589793 rad + pos: -42.5,-44.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - uid: 11181 components: - rot: 1.5707963267948966 rad @@ -106817,6 +107041,16 @@ entities: pos: -9.5,-42.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor + - uid: 11212 + components: + - rot: 3.141592653589793 rad + pos: -41.5,-44.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - uid: 12415 components: - rot: 1.5707963267948966 rad @@ -108026,20 +108260,6 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 14888 - components: - - pos: -33.5,-36.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - - uid: 14903 - components: - - pos: -34.5,-35.5 - parent: 82 - type: Transform - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 14910 components: - rot: 1.5707963267948966 rad @@ -108125,13 +108345,6 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 15421 - components: - - pos: -48.5,-32.5 - parent: 82 - type: Transform - - color: '#990000FF' - type: AtmosPipeColor - uid: 15428 components: - rot: -1.5707963267948966 rad @@ -108146,6 +108359,8 @@ entities: pos: -54.5,-27.5 parent: 82 type: Transform + - color: '#990000FF' + type: AtmosPipeColor - uid: 15442 components: - rot: -1.5707963267948966 rad @@ -108164,9 +108379,12 @@ entities: type: AtmosPipeColor - uid: 15473 components: - - pos: -50.5,-30.5 + - rot: -1.5707963267948966 rad + pos: -37.5,-40.5 parent: 82 type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 15556 components: - pos: -11.5,45.5 @@ -108202,12 +108420,6 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor - - uid: 18740 - components: - - rot: -1.5707963267948966 rad - pos: -48.5,-34.5 - parent: 82 - type: Transform - uid: 19164 components: - rot: 3.141592653589793 rad @@ -108488,6 +108700,14 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor + - uid: 22763 + components: + - rot: 1.5707963267948966 rad + pos: -42.5,-41.5 + parent: 82 + type: Transform + - color: '#03FCD3FF' + type: AtmosPipeColor - uid: 22782 components: - rot: 3.141592653589793 rad @@ -108504,16 +108724,6 @@ entities: type: Transform - color: '#990000FF' type: AtmosPipeColor - - uid: 25131 - components: - - rot: 3.141592653589793 rad - pos: -48.5,-37.5 - parent: 82 - type: Transform - - color: '#03FCD3FF' - type: AtmosPipeColor - - enabled: True - type: AmbientSound - proto: GasPort entities: - uid: 905 @@ -108838,13 +109048,6 @@ entities: pos: 21.5,-79.5 parent: 82 type: Transform - - uid: 3032 - components: - - pos: -50.5,-35.5 - parent: 82 - type: Transform - - color: '#03FCD3FF' - type: AtmosPipeColor - uid: 9509 components: - rot: 1.5707963267948966 rad @@ -108880,13 +109083,21 @@ entities: type: Transform - color: '#0055CCFF' type: AtmosPipeColor + - uid: 15518 + components: + - rot: -1.5707963267948966 rad + pos: -41.5,-40.5 + parent: 82 + type: Transform + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 18739 components: - - rot: 3.141592653589793 rad - pos: -48.5,-35.5 + - rot: 1.5707963267948966 rad + pos: -40.5,-42.5 parent: 82 type: Transform - - color: '#03FCD3FF' + - color: '#990000FF' type: AtmosPipeColor - uid: 19009 components: @@ -108937,9 +109148,10 @@ entities: - pos: 12.5,66.5 parent: 82 type: Transform - - uid: 15500 + - uid: 18566 components: - - pos: -49.5,-36.5 + - rot: -1.5707963267948966 rad + pos: -41.5,-39.5 parent: 82 type: Transform - color: '#03FCD3FF' @@ -109127,6 +109339,19 @@ entities: type: AmbientSound - color: '#0055CCFF' type: AtmosPipeColor + - uid: 2821 + components: + - rot: 3.141592653589793 rad + pos: -50.5,-34.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 5525 components: - rot: 3.141592653589793 rad @@ -109144,6 +109369,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7735 components: - rot: 3.141592653589793 rad @@ -109152,6 +109379,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 7736 components: - rot: 3.141592653589793 rad @@ -109160,6 +109389,21 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor + - uid: 7883 + components: + - rot: 1.5707963267948966 rad + pos: -38.5,-37.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 9709 components: - rot: 3.141592653589793 rad @@ -109623,6 +109867,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 13405 components: - rot: -1.5707963267948966 rad @@ -109661,6 +109907,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 13526 components: - pos: -36.5,-10.5 @@ -110022,6 +110270,9 @@ entities: pos: -30.5,-25.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#0055CCFF' @@ -110035,22 +110286,15 @@ entities: type: AmbientSound - color: '#0055CCFF' type: AtmosPipeColor - - uid: 14896 - components: - - rot: 3.141592653589793 rad - pos: -34.5,-42.5 - parent: 82 - type: Transform - - enabled: False - type: AmbientSound - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 14907 components: - rot: -1.5707963267948966 rad pos: -30.5,-35.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#0055CCFF' @@ -110075,22 +110319,15 @@ entities: type: AmbientSound - color: '#0055CCFF' type: AtmosPipeColor - - uid: 14997 - components: - - rot: 1.5707963267948966 rad - pos: -39.5,-39.5 - parent: 82 - type: Transform - - enabled: False - type: AmbientSound - - color: '#0055CCFF' - type: AtmosPipeColor - uid: 15273 components: - rot: 1.5707963267948966 rad pos: -44.5,-26.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#0055CCFF' @@ -110101,6 +110338,9 @@ entities: pos: -35.5,-31.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#0055CCFF' @@ -110319,6 +110559,19 @@ entities: type: AmbientSound - color: '#0055CCFF' type: AtmosPipeColor + - uid: 20638 + components: + - rot: -1.5707963267948966 rad + pos: -33.5,-43.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 22404 components: - rot: 3.141592653589793 rad @@ -110356,6 +110609,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - uid: 26241 components: - rot: 3.141592653589793 rad @@ -110364,6 +110619,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#0055CCFF' + type: AtmosPipeColor - proto: GasVentScrubber entities: - uid: 395 @@ -110416,6 +110673,44 @@ entities: type: AmbientSound - color: '#990000FF' type: AtmosPipeColor + - uid: 2852 + components: + - rot: -1.5707963267948966 rad + pos: -33.5,-42.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor + - uid: 2868 + components: + - pos: -39.5,-37.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor + - uid: 3278 + components: + - rot: 3.141592653589793 rad + pos: -48.5,-34.5 + parent: 82 + type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork + - enabled: False + type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 4455 components: - rot: 1.5707963267948966 rad @@ -110433,6 +110728,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 7738 components: - rot: 3.141592653589793 rad @@ -110441,6 +110738,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 7739 components: - rot: 3.141592653589793 rad @@ -110449,6 +110748,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 9896 components: - rot: 1.5707963267948966 rad @@ -110529,6 +110830,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 10985 components: - pos: 26.5,59.5 @@ -111392,6 +111695,9 @@ entities: - pos: -31.5,-27.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#990000FF' @@ -111402,16 +111708,9 @@ entities: pos: -30.5,-37.5 parent: 82 type: Transform - - enabled: False - type: AmbientSound - - color: '#990000FF' - type: AtmosPipeColor - - uid: 14895 - components: - - rot: 3.141592653589793 rad - pos: -32.5,-42.5 - parent: 82 - type: Transform + - ShutdownSubscribers: + - 24525 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#990000FF' @@ -111431,6 +111730,9 @@ entities: - pos: -44.5,-24.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#990000FF' @@ -111450,6 +111752,9 @@ entities: - pos: -33.5,-31.5 parent: 82 type: Transform + - ShutdownSubscribers: + - 24530 + type: DeviceNetwork - enabled: False type: AmbientSound - color: '#990000FF' @@ -111484,16 +111789,6 @@ entities: type: AmbientSound - color: '#990000FF' type: AtmosPipeColor - - uid: 15544 - components: - - rot: 3.141592653589793 rad - pos: -39.5,-38.5 - parent: 82 - type: Transform - - enabled: False - type: AmbientSound - - color: '#990000FF' - type: AtmosPipeColor - uid: 18842 components: - rot: 3.141592653589793 rad @@ -111726,14 +112021,6 @@ entities: type: AmbientSound - color: '#990000FF' type: AtmosPipeColor - - uid: 25130 - components: - - rot: 1.5707963267948966 rad - pos: -49.5,-34.5 - parent: 82 - type: Transform - - enabled: False - type: AmbientSound - uid: 25724 components: - pos: 24.5,74.5 @@ -111741,6 +112028,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - uid: 26240 components: - pos: -29.5,19.5 @@ -111748,6 +112037,8 @@ entities: type: Transform - enabled: False type: AmbientSound + - color: '#990000FF' + type: AtmosPipeColor - proto: GasVolumePump entities: - uid: 901 @@ -111759,11 +112050,6 @@ entities: type: AtmosPipeColor - proto: Gauze entities: - - uid: 8813 - components: - - pos: -38.48513,-41.45896 - parent: 82 - type: Transform - uid: 11235 components: - pos: -22.596481,-35.42784 @@ -113406,11 +113692,6 @@ entities: - pos: -23.5,-36.5 parent: 82 type: Transform - - uid: 2641 - components: - - pos: -38.5,-33.5 - parent: 82 - type: Transform - uid: 2644 components: - pos: -35.5,-33.5 @@ -113426,11 +113707,6 @@ entities: - pos: -33.5,-33.5 parent: 82 type: Transform - - uid: 2668 - components: - - pos: -30.5,-33.5 - parent: 82 - type: Transform - uid: 2673 components: - pos: -42.5,-29.5 @@ -113461,15 +113737,16 @@ entities: - pos: -28.5,-39.5 parent: 82 type: Transform - - uid: 2715 + - uid: 2708 components: - - rot: 1.5707963267948966 rad - pos: -7.5,32.5 + - rot: 3.141592653589793 rad + pos: -35.5,-42.5 parent: 82 type: Transform - - uid: 2757 + - uid: 2715 components: - - pos: -41.5,-39.5 + - rot: 1.5707963267948966 rad + pos: -7.5,32.5 parent: 82 type: Transform - uid: 2845 @@ -119373,36 +119650,6 @@ entities: pos: -61.5,22.5 parent: 82 type: Transform - - uid: 11217 - components: - - pos: -41.5,-41.5 - parent: 82 - type: Transform - - uid: 11219 - components: - - pos: -41.5,-43.5 - parent: 82 - type: Transform - - uid: 11221 - components: - - pos: -35.5,-37.5 - parent: 82 - type: Transform - - uid: 11222 - components: - - pos: -33.5,-37.5 - parent: 82 - type: Transform - - uid: 11223 - components: - - pos: -33.5,-40.5 - parent: 82 - type: Transform - - uid: 11224 - components: - - pos: -35.5,-40.5 - parent: 82 - type: Transform - uid: 11230 components: - pos: -49.5,57.5 @@ -119833,10 +120080,10 @@ entities: pos: -65.5,56.5 parent: 82 type: Transform - - uid: 15912 + - uid: 14989 components: - rot: 3.141592653589793 rad - pos: -39.5,-41.5 + pos: -35.5,-44.5 parent: 82 type: Transform - uid: 16716 @@ -120851,12 +121098,6 @@ entities: - pos: 45.5,-41.5 parent: 82 type: Transform - - uid: 25218 - components: - - rot: 3.141592653589793 rad - pos: -39.5,-43.5 - parent: 82 - type: Transform - uid: 25335 components: - pos: -63.5,-31.5 @@ -122274,11 +122515,6 @@ entities: - pos: 17.561699,74.71864 parent: 82 type: Transform - - uid: 11216 - components: - - pos: -42.525234,-41.524086 - parent: 82 - type: Transform - uid: 26252 components: - pos: -23.599802,-28.810429 @@ -122463,40 +122699,6 @@ entities: type: Transform - proto: HospitalCurtains entities: - - uid: 2821 - components: - - pos: -41.5,-42.5 - parent: 82 - type: Transform - - SecondsUntilStateChange: -384395.47 - state: Opening - type: Door - - uid: 2822 - components: - - pos: -41.5,-44.5 - parent: 82 - type: Transform - - SecondsUntilStateChange: -384393.25 - state: Opening - type: Door - - uid: 8896 - components: - - rot: 3.141592653589793 rad - pos: -39.5,-42.5 - parent: 82 - type: Transform - - SecondsUntilStateChange: -384567.5 - state: Opening - type: Door - - uid: 15911 - components: - - rot: 3.141592653589793 rad - pos: -39.5,-44.5 - parent: 82 - type: Transform - - SecondsUntilStateChange: -384392.53 - state: Opening - type: Door - uid: 16963 components: - pos: 53.5,-49.5 @@ -122517,14 +122719,6 @@ entities: - pos: 29.5,63.5 parent: 82 type: Transform - - uid: 25219 - components: - - pos: -41.5,-40.5 - parent: 82 - type: Transform - - SecondsUntilStateChange: -384394.44 - state: Opening - type: Door - proto: HospitalCurtainsOpen entities: - uid: 1036 @@ -122547,11 +122741,6 @@ entities: - pos: -7.5,33.5 parent: 82 type: Transform - - uid: 10249 - components: - - pos: -34.5,-40.5 - parent: 82 - type: Transform - uid: 11912 components: - pos: 62.5,-16.5 @@ -122567,6 +122756,12 @@ entities: - pos: 47.5,12.5 parent: 82 type: Transform + - uid: 22650 + components: + - rot: 3.141592653589793 rad + pos: -35.5,-43.5 + parent: 82 + type: Transform - uid: 25215 components: - pos: -13.5,10.5 @@ -123163,12 +123358,6 @@ entities: - pos: -56.5,-23.5 parent: 82 type: Transform - - uid: 25951 - components: - - rot: 3.141592653589793 rad - pos: -36.5,-37.5 - parent: 82 - type: Transform - proto: IntercomScience entities: - uid: 25928 @@ -124358,52 +124547,16 @@ entities: - 0 - 0 type: EntityStorage - - uid: 11207 + - uid: 18568 components: - - pos: -33.5,-38.5 + - pos: -36.5,-44.5 parent: 82 type: Transform - - air: - volume: 200 - immutable: False - temperature: 293.1496 - moles: - - 1.6971024 - - 6.3843384 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - type: EntityStorage - - uid: 11208 + - uid: 22088 components: - - pos: -33.5,-39.5 + - pos: -37.5,-44.5 parent: 82 type: Transform - - air: - volume: 200 - immutable: False - temperature: 293.1496 - moles: - - 1.6971024 - - 6.3843384 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - type: EntityStorage - proto: LockerMedicineFilled entities: - uid: 10923 @@ -124413,14 +124566,14 @@ entities: type: Transform - proto: LockerParamedicFilled entities: - - uid: 7883 + - uid: 15500 components: - - pos: -31.5,-39.5 + - pos: -29.5,-34.5 parent: 82 type: Transform - - uid: 8249 + - uid: 18573 components: - - pos: -31.5,-38.5 + - pos: -29.5,-35.5 parent: 82 type: Transform - proto: LockerQuarterMasterFilled @@ -124772,6 +124925,21 @@ entities: - 0 - 0 type: EntityStorage +- proto: LockerWallMedical + entities: + - uid: 2916 + components: + - rot: 3.141592653589793 rad + pos: -32.5,-40.5 + parent: 82 + type: Transform +- proto: LockerWallMedicalDoctorFilled + entities: + - uid: 22768 + components: + - pos: -42.5,-38.5 + parent: 82 + type: Transform - proto: LockerWallMedicalFilled entities: - uid: 3001 @@ -124822,6 +124990,12 @@ entities: - 0 - 0 type: EntityStorage + - uid: 22925 + components: + - rot: 1.5707963267948966 rad + pos: -38.5,-42.5 + parent: 82 + type: Transform - proto: LockerWardenFilled entities: - uid: 11423 @@ -124988,19 +125162,19 @@ entities: - pos: 30.5,-86.5 parent: 82 type: Transform - - uid: 10021 + - uid: 13990 components: - - pos: -51.5,-36.5 + - pos: -50.5,-37.5 parent: 82 type: Transform - - uid: 14958 + - uid: 14888 components: - - pos: -64.5,-41.5 + - pos: -48.5,-37.5 parent: 82 type: Transform - - uid: 19120 + - uid: 14958 components: - - pos: -51.5,-37.5 + - pos: -64.5,-41.5 parent: 82 type: Transform - proto: MagazineBoxMagnumPractice @@ -125345,6 +125519,11 @@ entities: - pos: 27.5,-6.5 parent: 82 type: Transform + - uid: 14997 + components: + - pos: -48.5,-39.5 + parent: 82 + type: Transform - uid: 15522 components: - pos: -62.5,-45.5 @@ -125415,11 +125594,6 @@ entities: - pos: -20.5,-45.5 parent: 82 type: Transform - - uid: 20638 - components: - - pos: -45.5,-37.5 - parent: 82 - type: Transform - uid: 21559 components: - pos: -1.5,-51.5 @@ -125600,70 +125774,70 @@ entities: type: Transform - proto: MedicalBed entities: - - uid: 2708 + - uid: 2840 components: - - pos: -37.5,-41.5 + - pos: -41.5,-37.5 parent: 82 type: Transform - - uid: 2756 + - uid: 2967 components: - - pos: -37.5,-43.5 + - pos: -46.5,-28.5 parent: 82 type: Transform - - uid: 2840 + - uid: 2968 components: - - pos: -41.5,-37.5 + - pos: -44.5,-28.5 parent: 82 type: Transform - - uid: 2842 + - uid: 2969 components: - - pos: -43.5,-43.5 + - pos: -42.5,-28.5 parent: 82 type: Transform - - uid: 2843 + - uid: 11229 components: - - pos: -43.5,-41.5 + - pos: -39.5,-36.5 parent: 82 type: Transform - - uid: 2967 + - uid: 13987 components: - - pos: -46.5,-28.5 + - pos: -35.5,-39.5 parent: 82 type: Transform - - uid: 2968 + - uid: 22090 components: - - pos: -44.5,-28.5 + - pos: -39.5,-38.5 parent: 82 type: Transform - - uid: 2969 + - uid: 22091 components: - - pos: -42.5,-28.5 + - pos: -33.5,-39.5 parent: 82 type: Transform - - uid: 8814 + - uid: 22767 components: - - pos: -43.5,-39.5 + - pos: -31.5,-39.5 parent: 82 type: Transform - proto: MedicalTechFab entities: - - uid: 2995 + - uid: 2917 components: - - pos: -29.5,-34.5 + - pos: -47.5,-35.5 parent: 82 type: Transform - proto: MedkitAdvancedFilled entities: - uid: 3182 components: - - pos: -37.363197,-38.382984 + - pos: -33.980503,-34.432804 parent: 82 type: Transform - proto: MedkitBruteFilled entities: - uid: 3183 components: - - pos: -37.377087,-38.702427 + - pos: -34.534157,-34.43217 parent: 82 type: Transform - uid: 3268 @@ -125680,7 +125854,7 @@ entities: entities: - uid: 3184 components: - - pos: -37.363197,-39.035763 + - pos: -33.42429,-34.390564 parent: 82 type: Transform - uid: 11514 @@ -125699,7 +125873,7 @@ entities: entities: - uid: 3188 components: - - pos: -37.363197,-40.313538 + - pos: -31.440344,-38.477425 parent: 82 type: Transform - uid: 8244 @@ -125716,7 +125890,7 @@ entities: entities: - uid: 3185 components: - - pos: -37.363197,-39.369095 + - pos: -33.980503,-34.161953 parent: 82 type: Transform - uid: 11517 @@ -125728,7 +125902,7 @@ entities: entities: - uid: 3186 components: - - pos: -37.363197,-39.688538 + - pos: -34.534157,-34.187115 parent: 82 type: Transform - uid: 7098 @@ -125745,7 +125919,7 @@ entities: entities: - uid: 3187 components: - - pos: -37.363197,-40.007984 + - pos: -33.450073,-34.209995 parent: 82 type: Transform - proto: MicroManipulatorStockPart @@ -126434,9 +126608,9 @@ entities: type: Transform - proto: OperatingTable entities: - - uid: 2916 + - uid: 2832 components: - - pos: -33.5,-42.5 + - pos: -33.5,-41.5 parent: 82 type: Transform - proto: OreBag @@ -128053,6 +128227,13 @@ entities: - pos: 22.5,69.5 parent: 82 type: Transform +- proto: PosterLegitAnatomyPoster + entities: + - uid: 2865 + components: + - pos: -39.5,-41.5 + parent: 82 + type: Transform - proto: PosterLegitBlessThisSpess entities: - uid: 15903 @@ -128787,6 +128968,14 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver + - uid: 2822 + components: + - rot: -1.5707963267948966 rad + pos: -29.5,-36.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound - uid: 3407 components: - rot: 3.141592653589793 rad @@ -128979,6 +129168,14 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver + - uid: 11438 + components: + - rot: 3.141592653589793 rad + pos: -33.5,-44.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound - uid: 11500 components: - pos: 66.5,-18.5 @@ -129009,6 +129206,30 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver + - uid: 14898 + components: + - rot: 3.141592653589793 rad + pos: -42.5,-44.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound + - uid: 15520 + components: + - rot: -1.5707963267948966 rad + pos: -36.5,-40.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound + - uid: 15912 + components: + - rot: 1.5707963267948966 rad + pos: -37.5,-43.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound - uid: 16944 components: - rot: 1.5707963267948966 rad @@ -130148,14 +130369,6 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver - - uid: 22091 - components: - - rot: 3.141592653589793 rad - pos: -36.5,-36.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - uid: 22092 components: - rot: 3.141592653589793 rad @@ -130457,22 +130670,6 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver - - uid: 22361 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-43.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - - uid: 22362 - components: - - rot: -1.5707963267948966 rad - pos: -33.5,-39.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - uid: 22556 components: - pos: 37.5,-11.5 @@ -130510,6 +130707,14 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver + - uid: 22633 + components: + - rot: 1.5707963267948966 rad + pos: -39.5,-37.5 + parent: 82 + type: Transform + - enabled: False + type: AmbientSound - uid: 22634 components: - rot: -1.5707963267948966 rad @@ -130933,13 +131138,6 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver - - uid: 25486 - components: - - pos: -40.5,-39.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - uid: 25611 components: - rot: 3.141592653589793 rad @@ -131139,6 +131337,12 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver + - uid: 2742 + components: + - rot: 1.5707963267948966 rad + pos: -43.5,-42.5 + parent: 82 + type: Transform - uid: 4258 components: - rot: -1.5707963267948966 rad @@ -132065,30 +132269,6 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver - - uid: 22088 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-40.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - - uid: 22089 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-42.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - - uid: 22090 - components: - - rot: 1.5707963267948966 rad - pos: -43.5,-44.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - uid: 22100 components: - pos: -11.5,-29.5 @@ -132360,22 +132540,6 @@ entities: type: Transform - powerLoad: 0 type: ApcPowerReceiver - - uid: 25307 - components: - - rot: -1.5707963267948966 rad - pos: -37.5,-42.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - - uid: 25308 - components: - - rot: -1.5707963267948966 rad - pos: -37.5,-44.5 - parent: 82 - type: Transform - - powerLoad: 0 - type: ApcPowerReceiver - uid: 25327 components: - pos: 22.5,27.5 @@ -132466,6 +132630,12 @@ entities: - pos: 13.5,38.5 parent: 82 type: Transform + - uid: 1889 + components: + - rot: 3.141592653589793 rad + pos: -48.5,-39.5 + parent: 82 + type: Transform - uid: 2072 components: - pos: 22.5,-6.5 @@ -132476,9 +132646,9 @@ entities: - pos: 22.5,-7.5 parent: 82 type: Transform - - uid: 2848 + - uid: 2981 components: - - pos: -31.5,-37.5 + - pos: -47.5,-34.5 parent: 82 type: Transform - uid: 3246 @@ -132901,11 +133071,6 @@ entities: - pos: -20.5,-45.5 parent: 82 type: Transform - - uid: 20637 - components: - - pos: -45.5,-37.5 - parent: 82 - type: Transform - uid: 20642 components: - pos: -55.5,-35.5 @@ -133741,26 +133906,6 @@ entities: - pos: -10.5,-50.5 parent: 82 type: Transform - - uid: 24819 - components: - - pos: -36.5,-39.5 - parent: 82 - type: Transform - - uid: 24820 - components: - - pos: -44.5,-41.5 - parent: 82 - type: Transform - - uid: 24821 - components: - - pos: -44.5,-43.5 - parent: 82 - type: Transform - - uid: 24822 - components: - - pos: -44.5,-39.5 - parent: 82 - type: Transform - uid: 24823 components: - pos: -30.5,-40.5 @@ -134513,6 +134658,11 @@ entities: type: Transform - proto: RandomPosterLegit entities: + - uid: 2866 + components: + - pos: -44.5,-41.5 + parent: 82 + type: Transform - uid: 3397 components: - pos: 73.5,10.5 @@ -140900,16 +141050,24 @@ entities: entities: - uid: 2920 components: - - pos: -35.591175,-44.228874 - parent: 82 + - flags: InContainer + type: MetaData + - parent: 18569 type: Transform + - canCollide: False + type: Physics + - type: InsideEntityStorage - proto: Scalpel entities: - uid: 2922 components: - - pos: -35.4384,-44.576096 - parent: 82 + - flags: InContainer + type: MetaData + - parent: 18569 type: Transform + - canCollide: False + type: Physics + - type: InsideEntityStorage - proto: ScalpelShiv entities: - uid: 20008 @@ -141075,6 +141233,11 @@ entities: - pos: -8.5047035,8.53811 parent: 82 type: Transform + - uid: 2864 + components: + - pos: -47.476715,-34.4093 + parent: 82 + type: Transform - uid: 4169 components: - pos: 11.31822,35.63377 @@ -141110,11 +141273,6 @@ entities: - pos: 42.746567,20.491737 parent: 82 type: Transform - - uid: 11229 - components: - - pos: -30.483015,-34.43525 - parent: 82 - type: Transform - uid: 11289 components: - pos: -27.104486,5.5675354 @@ -141178,7 +141336,7 @@ entities: - pos: 58.5,-6.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141189,7 +141347,7 @@ entities: - pos: 59.5,-6.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141201,7 +141359,7 @@ entities: pos: 3.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141213,7 +141371,7 @@ entities: pos: 2.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141224,7 +141382,7 @@ entities: - pos: 1.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141235,7 +141393,7 @@ entities: - pos: 2.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141246,7 +141404,7 @@ entities: - pos: 3.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141257,7 +141415,7 @@ entities: - pos: 5.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141268,7 +141426,7 @@ entities: - pos: 6.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141279,7 +141437,7 @@ entities: - pos: 7.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141290,7 +141448,7 @@ entities: - pos: 8.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141301,7 +141459,7 @@ entities: - pos: 9.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141312,7 +141470,7 @@ entities: - pos: 11.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141323,7 +141481,7 @@ entities: - pos: 12.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141334,7 +141492,7 @@ entities: - pos: 13.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141345,7 +141503,7 @@ entities: - pos: 14.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141357,7 +141515,7 @@ entities: pos: 16.5,-11.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141369,7 +141527,7 @@ entities: pos: 16.5,-10.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141381,7 +141539,7 @@ entities: pos: -1.5,-11.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141393,7 +141551,7 @@ entities: pos: -1.5,-10.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141405,7 +141563,7 @@ entities: pos: 25.5,64.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141440,7 +141598,7 @@ entities: - pos: 62.5,-6.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141451,7 +141609,7 @@ entities: - pos: -8.5,32.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141462,7 +141620,7 @@ entities: - pos: -9.5,32.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141473,7 +141631,7 @@ entities: - pos: -7.5,32.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141485,7 +141643,7 @@ entities: pos: -6.5,34.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141497,7 +141655,7 @@ entities: pos: -6.5,35.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141508,7 +141666,7 @@ entities: - pos: 60.5,-6.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141520,7 +141678,7 @@ entities: pos: 44.5,12.5 parent: 82 type: Transform - - SecondsUntilStateChange: -79805.35 + - SecondsUntilStateChange: -89448.695 state: Opening type: Door - links: @@ -141532,7 +141690,7 @@ entities: pos: 44.5,13.5 parent: 82 type: Transform - - SecondsUntilStateChange: -79805.35 + - SecondsUntilStateChange: -89448.695 state: Opening type: Door - links: @@ -141544,7 +141702,7 @@ entities: pos: -46.5,-34.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141556,7 +141714,7 @@ entities: pos: 12.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141568,7 +141726,7 @@ entities: pos: 11.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141580,7 +141738,7 @@ entities: pos: 10.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141592,7 +141750,7 @@ entities: pos: 4.5,-19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141603,7 +141761,7 @@ entities: - pos: 0.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -491499.4 + - SecondsUntilStateChange: -501142.78 state: Opening type: Door - links: @@ -141615,7 +141773,7 @@ entities: pos: 44.5,14.5 parent: 82 type: Transform - - SecondsUntilStateChange: -79805.35 + - SecondsUntilStateChange: -89448.695 state: Opening type: Door - links: @@ -141627,7 +141785,7 @@ entities: pos: -6.5,33.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141638,7 +141796,7 @@ entities: - pos: -10.5,32.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141650,7 +141808,7 @@ entities: pos: 25.5,65.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141661,7 +141819,7 @@ entities: - pos: 28.5,67.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141672,7 +141830,7 @@ entities: - pos: 27.5,67.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141683,7 +141841,7 @@ entities: - pos: 28.5,62.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141694,7 +141852,7 @@ entities: - pos: 26.5,62.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141705,7 +141863,7 @@ entities: - pos: 27.5,62.5 parent: 82 type: Transform - - SecondsUntilStateChange: -391616.22 + - SecondsUntilStateChange: -401259.6 state: Opening type: Door - links: @@ -141717,7 +141875,7 @@ entities: pos: -6.5,36.5 parent: 82 type: Transform - - SecondsUntilStateChange: -390308.12 + - SecondsUntilStateChange: -399951.5 state: Opening type: Door - links: @@ -141729,7 +141887,7 @@ entities: pos: -46.5,-35.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141740,7 +141898,7 @@ entities: - pos: -45.5,-33.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141751,7 +141909,7 @@ entities: - pos: -44.5,-33.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141762,7 +141920,7 @@ entities: - pos: -42.5,-33.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141773,7 +141931,7 @@ entities: - pos: -41.5,-33.5 parent: 82 type: Transform - - SecondsUntilStateChange: -383249.28 + - SecondsUntilStateChange: -392892.66 state: Opening type: Door - links: @@ -141784,7 +141942,7 @@ entities: - pos: 61.5,-6.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141796,7 +141954,7 @@ entities: pos: 57.5,-7.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141808,7 +141966,7 @@ entities: pos: 57.5,-8.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141820,7 +141978,7 @@ entities: pos: 57.5,-10.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141832,7 +141990,7 @@ entities: pos: 57.5,-11.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141844,7 +142002,7 @@ entities: pos: 57.5,-9.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141856,7 +142014,7 @@ entities: pos: 59.5,-14.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -141868,7 +142026,7 @@ entities: pos: 59.5,-15.5 parent: 82 type: Transform - - SecondsUntilStateChange: -380463.97 + - SecondsUntilStateChange: -390107.34 state: Opening type: Door - links: @@ -142047,7 +142205,7 @@ entities: - pos: -26.5,60.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436300 + - SecondsUntilStateChange: -445943.38 state: Closing type: Door - links: @@ -142058,7 +142216,7 @@ entities: - pos: -24.5,60.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436300 + - SecondsUntilStateChange: -445943.38 state: Closing type: Door - links: @@ -142069,7 +142227,7 @@ entities: - pos: -25.5,60.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436300 + - SecondsUntilStateChange: -445943.38 state: Closing type: Door - links: @@ -142080,7 +142238,7 @@ entities: - pos: -23.5,60.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436300 + - SecondsUntilStateChange: -445943.38 state: Closing type: Door - links: @@ -142091,7 +142249,7 @@ entities: - pos: -27.5,60.5 parent: 82 type: Transform - - SecondsUntilStateChange: -436300 + - SecondsUntilStateChange: -445943.38 state: Closing type: Door - links: @@ -142668,6 +142826,13 @@ entities: - pos: -37.5,-29.5 parent: 82 type: Transform +- proto: SignCloning + entities: + - uid: 2871 + components: + - pos: -49.5,-33.5 + parent: 82 + type: Transform - proto: SignConference entities: - uid: 10868 @@ -142677,9 +142842,9 @@ entities: type: Transform - proto: SignCryogenicsMed entities: - - uid: 3074 + - uid: 18570 components: - - pos: -49.5,-33.5 + - pos: -40.5,-39.5 parent: 82 type: Transform - proto: SignDirectionalBar @@ -144206,9 +144371,10 @@ entities: type: Transform - proto: SignSurgery entities: - - uid: 2871 + - uid: 2745 components: - - pos: -32.5,-37.5 + - rot: 3.141592653589793 rad + pos: -36.5,-41.5 parent: 82 type: Transform - proto: SignTelecomms @@ -144322,16 +144488,10 @@ entities: type: Transform - proto: SinkWide entities: - - uid: 2863 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-41.5 - parent: 82 - type: Transform - - uid: 2867 + - uid: 2744 components: - - rot: 1.5707963267948966 rad - pos: -35.5,-38.5 + - rot: 3.141592653589793 rad + pos: -34.5,-44.5 parent: 82 type: Transform - proto: Skub @@ -146492,14 +146652,14 @@ entities: type: Transform - proto: SpawnPointParamedic entities: - - uid: 11001 + - uid: 8896 components: - - pos: -30.5,-39.5 + - pos: -30.5,-34.5 parent: 82 type: Transform - - uid: 11002 + - uid: 22637 components: - - pos: -30.5,-38.5 + - pos: -30.5,-35.5 parent: 82 type: Transform - proto: SpawnPointQuartermaster @@ -147698,12 +147858,17 @@ entities: type: SurveillanceCamera - proto: SurveillanceCameraMedical entities: - - uid: 2820 + - uid: 6906 components: - - rot: 1.5707963267948966 rad - pos: -37.5,-39.5 + - rot: -1.5707963267948966 rad + pos: -51.5,-36.5 parent: 82 type: Transform + - setupAvailableNetworks: + - SurveillanceCameraMedical + nameSet: True + id: Cloning + type: SurveillanceCamera - uid: 10508 components: - rot: 3.141592653589793 rad @@ -147747,17 +147912,6 @@ entities: nameSet: True id: Morgue type: SurveillanceCamera - - uid: 11438 - components: - - rot: -1.5707963267948966 rad - pos: -35.5,-42.5 - parent: 82 - type: Transform - - setupAvailableNetworks: - - SurveillanceCameraMedical - nameSet: True - id: Surgery - type: SurveillanceCamera - uid: 13929 components: - rot: -1.5707963267948966 rad @@ -147780,6 +147934,28 @@ entities: nameSet: True id: Chemistry Lab type: SurveillanceCamera + - uid: 14896 + components: + - rot: 3.141592653589793 rad + pos: -33.5,-41.5 + parent: 82 + type: Transform + - setupAvailableNetworks: + - SurveillanceCameraMedical + nameSet: True + id: Operating theatre + type: SurveillanceCamera + - uid: 22760 + components: + - rot: 3.141592653589793 rad + pos: -40.5,-42.5 + parent: 82 + type: Transform + - setupAvailableNetworks: + - SurveillanceCameraMedical + nameSet: True + id: Cryogenics + type: SurveillanceCamera - proto: SurveillanceCameraRouterCommand entities: - uid: 6650 @@ -148174,11 +148350,6 @@ entities: - pos: 25.5393,76.62676 parent: 82 type: Transform - - uid: 25222 - components: - - pos: -38.45715,-43.45896 - parent: 82 - type: Transform - proto: SyringeEphedrine entities: - uid: 24187 @@ -149150,24 +149321,6 @@ entities: type: Transform - proto: TableGlass entities: - - uid: 2819 - components: - - rot: -1.5707963267948966 rad - pos: -42.5,-39.5 - parent: 82 - type: Transform - - uid: 2850 - components: - - rot: 1.5707963267948966 rad - pos: -42.5,-43.5 - parent: 82 - type: Transform - - uid: 2851 - components: - - rot: 1.5707963267948966 rad - pos: -42.5,-41.5 - parent: 82 - type: Transform - uid: 3229 components: - pos: -37.5,-24.5 @@ -149220,6 +149373,11 @@ entities: pos: 3.5,-26.5 parent: 82 type: Transform + - uid: 13988 + components: + - pos: -35.5,-38.5 + parent: 82 + type: Transform - uid: 15477 components: - rot: 3.141592653589793 rad @@ -149232,6 +149390,18 @@ entities: pos: -50.5,-24.5 parent: 82 type: Transform + - uid: 15544 + components: + - rot: 1.5707963267948966 rad + pos: -38.5,-36.5 + parent: 82 + type: Transform + - uid: 18575 + components: + - rot: -1.5707963267948966 rad + pos: -31.5,-38.5 + parent: 82 + type: Transform - uid: 20280 components: - rot: -1.5707963267948966 rad @@ -149295,16 +149465,6 @@ entities: pos: 32.5,-32.5 parent: 82 type: Transform - - uid: 25220 - components: - - pos: -38.5,-43.5 - parent: 82 - type: Transform - - uid: 25221 - components: - - pos: -38.5,-41.5 - parent: 82 - type: Transform - uid: 25524 components: - rot: -1.5707963267948966 rad @@ -149989,27 +150149,20 @@ entities: - pos: -42.5,-34.5 parent: 82 type: Transform - - uid: 2682 - components: - - pos: -10.5,-10.5 - parent: 82 - type: Transform - - uid: 2746 + - uid: 2641 components: - - rot: 1.5707963267948966 rad - pos: -37.5,-39.5 + - rot: 3.141592653589793 rad + pos: -32.5,-44.5 parent: 82 type: Transform - - uid: 2747 + - uid: 2668 components: - - rot: 1.5707963267948966 rad - pos: -37.5,-40.5 + - pos: -43.5,-41.5 parent: 82 type: Transform - - uid: 2853 + - uid: 2682 components: - - rot: 1.5707963267948966 rad - pos: -37.5,-38.5 + - pos: -10.5,-10.5 parent: 82 type: Transform - uid: 2855 @@ -150017,29 +150170,6 @@ entities: - pos: -27.5,-27.5 parent: 82 type: Transform - - uid: 2864 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-43.5 - parent: 82 - type: Transform - - uid: 2865 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-44.5 - parent: 82 - type: Transform - - uid: 2868 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-39.5 - parent: 82 - type: Transform - - uid: 2997 - components: - - pos: -30.5,-34.5 - parent: 82 - type: Transform - uid: 2998 components: - pos: -35.5,-34.5 @@ -150149,6 +150279,11 @@ entities: - pos: 60.5,-10.5 parent: 82 type: Transform + - uid: 14891 + components: + - pos: -32.5,-41.5 + parent: 82 + type: Transform - uid: 14986 components: - pos: 15.5,58.5 @@ -150159,6 +150294,16 @@ entities: - pos: 14.5,58.5 parent: 82 type: Transform + - uid: 14994 + components: + - pos: -43.5,-40.5 + parent: 82 + type: Transform + - uid: 19120 + components: + - pos: -36.5,-42.5 + parent: 82 + type: Transform - uid: 20668 components: - pos: 29.5,61.5 @@ -150848,35 +150993,12 @@ entities: type: Transform - proto: TintedWindow entities: - - uid: 2297 - components: - - pos: -41.5,-39.5 - parent: 82 - type: Transform - uid: 2513 components: - rot: 3.141592653589793 rad pos: 5.5,-41.5 parent: 82 type: Transform - - uid: 2729 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-40.5 - parent: 82 - type: Transform - - uid: 2730 - components: - - rot: 1.5707963267948966 rad - pos: -33.5,-37.5 - parent: 82 - type: Transform - - uid: 2731 - components: - - rot: 1.5707963267948966 rad - pos: -33.5,-40.5 - parent: 82 - type: Transform - uid: 2749 components: - pos: 0.5,-33.5 @@ -150912,22 +151034,6 @@ entities: - pos: 4.5,-36.5 parent: 82 type: Transform - - uid: 2831 - components: - - rot: 1.5707963267948966 rad - pos: -35.5,-37.5 - parent: 82 - type: Transform - - uid: 2832 - components: - - pos: -41.5,-43.5 - parent: 82 - type: Transform - - uid: 2833 - components: - - pos: -41.5,-41.5 - parent: 82 - type: Transform - uid: 3319 components: - pos: 23.5,-18.5 @@ -151016,16 +151122,16 @@ entities: - pos: 21.5,-58.5 parent: 82 type: Transform - - uid: 13986 + - uid: 18565 components: - rot: 3.141592653589793 rad - pos: -39.5,-41.5 + pos: -35.5,-42.5 parent: 82 type: Transform - - uid: 15913 + - uid: 20640 components: - rot: 3.141592653589793 rad - pos: -39.5,-43.5 + pos: -35.5,-44.5 parent: 82 type: Transform - proto: ToiletDirtyWater @@ -151501,9 +151607,9 @@ entities: type: Transform - proto: UniformScrubsColorPurple entities: - - uid: 11206 + - uid: 2707 components: - - pos: -35.323067,-39.42946 + - pos: -36.267963,-42.216316 parent: 82 type: Transform - proto: Vaccinator @@ -151957,15 +152063,6 @@ entities: - pos: 55.5,-40.5 parent: 82 type: Transform -- proto: VendingMachineGeneDrobe - entities: - - uid: 24869 - components: - - flags: SessionSpecific - type: MetaData - - pos: -47.5,-34.5 - parent: 82 - type: Transform - proto: VendingMachineHappyHonk entities: - uid: 2079 @@ -152057,6 +152154,11 @@ entities: - pos: -19.5,-28.5 parent: 82 type: Transform + - uid: 20637 + components: + - pos: -52.5,-32.5 + parent: 82 + type: Transform - proto: VendingMachineNutri entities: - uid: 3202 @@ -166479,32 +166581,11 @@ entities: pos: -32.5,-40.5 parent: 82 type: Transform - - uid: 2732 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-40.5 - parent: 82 - type: Transform - uid: 2733 components: - pos: -36.5,-41.5 parent: 82 type: Transform - - uid: 2734 - components: - - pos: -36.5,-42.5 - parent: 82 - type: Transform - - uid: 2735 - components: - - pos: -36.5,-43.5 - parent: 82 - type: Transform - - uid: 2736 - components: - - pos: -36.5,-44.5 - parent: 82 - type: Transform - uid: 2737 components: - pos: -36.5,-45.5 @@ -166520,42 +166601,6 @@ entities: - pos: -34.5,-45.5 parent: 82 type: Transform - - uid: 2740 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-39.5 - parent: 82 - type: Transform - - uid: 2741 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-38.5 - parent: 82 - type: Transform - - uid: 2742 - components: - - rot: 1.5707963267948966 rad - pos: -36.5,-37.5 - parent: 82 - type: Transform - - uid: 2743 - components: - - rot: 1.5707963267948966 rad - pos: -32.5,-37.5 - parent: 82 - type: Transform - - uid: 2744 - components: - - rot: 1.5707963267948966 rad - pos: -32.5,-38.5 - parent: 82 - type: Transform - - uid: 2745 - components: - - rot: 1.5707963267948966 rad - pos: -32.5,-39.5 - parent: 82 - type: Transform - uid: 2759 components: - pos: -44.5,-36.5 @@ -166751,6 +166796,12 @@ entities: - pos: -44.5,-44.5 parent: 82 type: Transform + - uid: 2836 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-41.5 + parent: 82 + type: Transform - uid: 2856 components: - rot: 1.5707963267948966 rad @@ -166798,12 +166849,6 @@ entities: - pos: -47.5,-20.5 parent: 82 type: Transform - - uid: 3030 - components: - - rot: 3.141592653589793 rad - pos: -46.5,-37.5 - parent: 82 - type: Transform - uid: 3031 components: - pos: -46.5,-38.5 @@ -168840,6 +168885,12 @@ entities: - pos: 18.5,-46.5 parent: 82 type: Transform + - uid: 10021 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-33.5 + parent: 82 + type: Transform - uid: 10049 components: - pos: 21.5,39.5 @@ -168890,6 +168941,34 @@ entities: - pos: -35.5,-5.5 parent: 82 type: Transform + - uid: 11207 + components: + - pos: -35.5,-40.5 + parent: 82 + type: Transform + - uid: 11216 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-42.5 + parent: 82 + type: Transform + - uid: 11221 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-44.5 + parent: 82 + type: Transform + - uid: 11222 + components: + - rot: 1.5707963267948966 rad + pos: -39.5,-41.5 + parent: 82 + type: Transform + - uid: 11224 + components: + - pos: -33.5,-40.5 + parent: 82 + type: Transform - uid: 11226 components: - pos: -49.5,-38.5 @@ -169065,6 +169144,17 @@ entities: pos: -37.5,-45.5 parent: 82 type: Transform + - uid: 14889 + components: + - pos: -48.5,-38.5 + parent: 82 + type: Transform + - uid: 14903 + components: + - rot: 3.141592653589793 rad + pos: -35.5,-41.5 + parent: 82 + type: Transform - uid: 15384 components: - pos: 73.5,5.5 @@ -169080,6 +169170,18 @@ entities: - pos: 73.5,6.5 parent: 82 type: Transform + - uid: 15502 + components: + - rot: 1.5707963267948966 rad + pos: -40.5,-39.5 + parent: 82 + type: Transform + - uid: 15519 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-43.5 + parent: 82 + type: Transform - uid: 15550 components: - pos: 30.5,56.5 @@ -169105,6 +169207,11 @@ entities: - pos: -41.5,-38.5 parent: 82 type: Transform + - uid: 18616 + components: + - pos: -34.5,-40.5 + parent: 82 + type: Transform - uid: 18737 components: - pos: -50.5,-38.5 @@ -169191,6 +169298,12 @@ entities: - pos: -25.5,-5.5 parent: 82 type: Transform + - uid: 22361 + components: + - rot: -1.5707963267948966 rad + pos: -40.5,-41.5 + parent: 82 + type: Transform - uid: 22524 components: - rot: 1.5707963267948966 rad @@ -169214,6 +169327,12 @@ entities: pos: -60.5,-29.5 parent: 82 type: Transform + - uid: 22645 + components: + - rot: 3.141592653589793 rad + pos: -30.5,-33.5 + parent: 82 + type: Transform - uid: 22706 components: - pos: -43.5,-38.5 @@ -170713,6 +170832,13 @@ entities: pos: -23.5,-30.5 parent: 82 type: Transform +- proto: WindoorSecureParamedicLocked + entities: + - uid: 2867 + components: + - pos: -29.5,-36.5 + parent: 82 + type: Transform - proto: WindoorSecureSalvageLocked entities: - uid: 6849 @@ -171123,16 +171249,6 @@ entities: - pos: -33.5,-33.5 parent: 82 type: Transform - - uid: 3147 - components: - - pos: -38.5,-33.5 - parent: 82 - type: Transform - - uid: 3148 - components: - - pos: -30.5,-33.5 - parent: 82 - type: Transform - uid: 3165 components: - pos: -24.5,5.5 @@ -171882,12 +171998,6 @@ entities: pos: 9.5,-41.5 parent: 82 type: Transform - - uid: 2540 - components: - - rot: 3.141592653589793 rad - pos: -38.5,-43.5 - parent: 82 - type: Transform - uid: 2603 components: - rot: -1.5707963267948966 rad @@ -171900,54 +172010,6 @@ entities: pos: -14.5,-38.5 parent: 82 type: Transform - - uid: 2836 - components: - - rot: 3.141592653589793 rad - pos: -42.5,-43.5 - parent: 82 - type: Transform - - uid: 2837 - components: - - rot: 3.141592653589793 rad - pos: -43.5,-43.5 - parent: 82 - type: Transform - - uid: 2838 - components: - - rot: 3.141592653589793 rad - pos: -42.5,-41.5 - parent: 82 - type: Transform - - uid: 2839 - components: - - rot: 3.141592653589793 rad - pos: -43.5,-41.5 - parent: 82 - type: Transform - - uid: 2849 - components: - - rot: 3.141592653589793 rad - pos: -37.5,-41.5 - parent: 82 - type: Transform - - uid: 2852 - components: - - rot: 3.141592653589793 rad - pos: -38.5,-41.5 - parent: 82 - type: Transform - - uid: 3192 - components: - - rot: -1.5707963267948966 rad - pos: -29.5,-34.5 - parent: 82 - type: Transform - - uid: 3193 - components: - - rot: 1.5707963267948966 rad - pos: -39.5,-34.5 - parent: 82 - type: Transform - uid: 3284 components: - rot: -1.5707963267948966 rad @@ -172029,12 +172091,6 @@ entities: pos: -13.5,-38.5 parent: 82 type: Transform - - uid: 17788 - components: - - rot: 3.141592653589793 rad - pos: -37.5,-43.5 - parent: 82 - type: Transform - uid: 20005 components: - pos: 59.5,-36.5 @@ -172042,6 +172098,23 @@ entities: type: Transform - proto: WindowReinforcedDirectional entities: + - uid: 2731 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-39.5 + parent: 82 + type: Transform + - uid: 2757 + components: + - pos: -33.5,-37.5 + parent: 82 + type: Transform + - uid: 2819 + components: + - rot: 1.5707963267948966 rad + pos: -34.5,-38.5 + parent: 82 + type: Transform - uid: 2828 components: - rot: 1.5707963267948966 rad @@ -172066,6 +172139,39 @@ entities: pos: -32.5,-44.5 parent: 82 type: Transform + - uid: 2839 + components: + - pos: -35.5,-37.5 + parent: 82 + type: Transform + - uid: 2846 + components: + - rot: 3.141592653589793 rad + pos: -38.5,-39.5 + parent: 82 + type: Transform + - uid: 2847 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-39.5 + parent: 82 + type: Transform + - uid: 2869 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-36.5 + parent: 82 + type: Transform + - uid: 3147 + components: + - pos: -31.5,-37.5 + parent: 82 + type: Transform + - uid: 3148 + components: + - pos: -30.5,-36.5 + parent: 82 + type: Transform - uid: 3346 components: - rot: -1.5707963267948966 rad @@ -172206,6 +172312,18 @@ entities: pos: 64.5,-10.5 parent: 82 type: Transform + - uid: 11205 + components: + - rot: 3.141592653589793 rad + pos: -39.5,-39.5 + parent: 82 + type: Transform + - uid: 11206 + components: + - rot: 1.5707963267948966 rad + pos: -34.5,-39.5 + parent: 82 + type: Transform - uid: 11450 components: - rot: 1.5707963267948966 rad @@ -172224,6 +172342,17 @@ entities: pos: 69.5,-20.5 parent: 82 type: Transform + - uid: 14895 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-34.5 + parent: 82 + type: Transform + - uid: 14897 + components: + - pos: -38.5,-35.5 + parent: 82 + type: Transform - uid: 17772 components: - pos: 64.5,-16.5 @@ -172258,6 +172387,23 @@ entities: pos: 69.5,-22.5 parent: 82 type: Transform + - uid: 18582 + components: + - rot: 1.5707963267948966 rad + pos: -36.5,-38.5 + parent: 82 + type: Transform + - uid: 18617 + components: + - pos: -39.5,-35.5 + parent: 82 + type: Transform + - uid: 19812 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-38.5 + parent: 82 + type: Transform - uid: 20488 components: - rot: 3.141592653589793 rad @@ -172282,6 +172428,12 @@ entities: pos: 64.5,-11.5 parent: 82 type: Transform + - uid: 22764 + components: + - rot: -1.5707963267948966 rad + pos: -30.5,-35.5 + parent: 82 + type: Transform - uid: 22886 components: - pos: 65.5,-16.5 @@ -172371,7 +172523,7 @@ entities: - pos: -11.5,17.5 parent: 82 type: Transform - - SecondsUntilStateChange: -561407.4 + - SecondsUntilStateChange: -571050.75 state: Opening type: Door - uid: 4246 @@ -172379,7 +172531,7 @@ entities: - pos: -11.5,19.5 parent: 82 type: Transform - - SecondsUntilStateChange: -561405.6 + - SecondsUntilStateChange: -571049 state: Opening type: Door - uid: 8013 diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml index 8a8818d91eb..36f6a9a987d 100644 --- a/Resources/Maps/saltern.yml +++ b/Resources/Maps/saltern.yml @@ -206,7 +206,7 @@ entities: version: 6 -3,-2: ind: -3,-2 - tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAGgAAAAAAGgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAbQAAAAACbQAAAAABbQAAAAACbQAAAAABbQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAbQAAAAAAbQAAAAABbQAAAAACbQAAAAACbQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAbQAAAAAAbQAAAAACbQAAAAABbQAAAAABbQAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAbQAAAAABbQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAA + tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAGgAAAAAAGgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAGgAAAAADGgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAbQAAAAACbQAAAAABbQAAAAACbQAAAAABbQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAbQAAAAAAbQAAAAABbQAAAAACbQAAAAACbQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAbQAAAAAAbQAAAAACbQAAAAABbQAAAAABbQAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAbQAAAAABbQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAOwAAAAAAOwAAAAAAOwAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAbwAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwAAAAAAcAAAAAAAcAAAAAAAcAAAAAAAcAAAAAAA version: 6 -3,-3: ind: -3,-3 @@ -884,42 +884,43 @@ entities: 7,4: 0: 65535 7,5: - 0: 65535 + 0: 65471 + 2: 64 7,6: 0: 61422 8,4: 0: 65535 8,5: 0: 48063 - 2: 17472 + 3: 17472 8,6: 0: 65535 9,4: 0: 65535 9,5: 0: 43695 - 3: 4368 - 4: 17472 + 4: 4368 + 5: 17472 9,6: 0: 8191 10,4: 0: 65535 10,5: 0: 43695 - 4: 4368 - 5: 17472 + 5: 4368 + 6: 17472 11,4: 0: 65535 11,5: 0: 43695 - 4: 21840 + 5: 21840 12,4: 0: 65535 12,5: 0: 13183 13,4: 0: 65399 - 4: 136 + 5: 136 13,5: 0: 7 -8,7: @@ -1024,7 +1025,7 @@ entities: 0: 62463 13,3: 0: 32755 - 4: 32768 + 5: 32768 14,0: 0: 65535 14,2: @@ -1378,6 +1379,21 @@ entities: - 0 - 0 - 0 + - volume: 2500 + temperature: 293.14996 + moles: + - 20.078888 + - 75.53487 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 - volume: 2500 temperature: 293.15 moles: @@ -4320,11 +4336,25 @@ entities: pos: 32.5,19.5 parent: 31 type: Transform + - links: + - 11307 + type: DeviceLinkSink + - linkedPorts: + 11306: + - DoorStatus: InputB + type: DeviceLinkSource - uid: 9068 components: - pos: 31.5,18.5 parent: 31 type: Transform + - links: + - 11306 + type: DeviceLinkSink + - linkedPorts: + 11307: + - DoorStatus: InputB + type: DeviceLinkSource - proto: AirlockExternalGlassCargoLocked entities: - uid: 6522 @@ -4332,11 +4362,25 @@ entities: - pos: 29.5,20.5 parent: 31 type: Transform + - links: + - 11306 + type: DeviceLinkSink + - linkedPorts: + 11307: + - DoorStatus: InputA + type: DeviceLinkSource - uid: 9067 components: - pos: 31.5,23.5 parent: 31 type: Transform + - links: + - 11307 + type: DeviceLinkSink + - linkedPorts: + 11306: + - DoorStatus: InputA + type: DeviceLinkSource - uid: 10094 components: - rot: 1.5707963267948966 rad @@ -4351,47 +4395,103 @@ entities: pos: 58.5,7.5 parent: 31 type: Transform + - links: + - 175 + type: DeviceLinkSink + - linkedPorts: + 175: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 145 components: - rot: 3.141592653589793 rad pos: -24.5,24.5 parent: 31 type: Transform + - links: + - 151 + type: DeviceLinkSink + - linkedPorts: + 151: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 151 components: - rot: 3.141592653589793 rad pos: -26.5,24.5 parent: 31 type: Transform + - links: + - 145 + type: DeviceLinkSink + - linkedPorts: + 145: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 172 components: - rot: 3.141592653589793 rad pos: 17.5,-31.5 parent: 31 type: Transform + - links: + - 173 + type: DeviceLinkSink + - linkedPorts: + 173: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 173 components: - rot: 3.141592653589793 rad pos: 15.5,-30.5 parent: 31 type: Transform + - links: + - 172 + type: DeviceLinkSink + - linkedPorts: + 172: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 174 components: - rot: 3.141592653589793 rad pos: 53.5,8.5 parent: 31 type: Transform + - links: + - 9974 + type: DeviceLinkSink + - linkedPorts: + 9974: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 175 components: - rot: 3.141592653589793 rad pos: 61.5,7.5 parent: 31 type: Transform + - links: + - 72 + type: DeviceLinkSink + - linkedPorts: + 72: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 9974 components: - pos: 53.5,4.5 parent: 31 type: Transform + - links: + - 174 + type: DeviceLinkSink + - linkedPorts: + 174: + - DoorStatus: DoorBolt + type: DeviceLinkSource - proto: AirlockExternalGlassLocked entities: - uid: 182 @@ -4400,22 +4500,50 @@ entities: pos: -24.5,-32.5 parent: 31 type: Transform + - links: + - 183 + type: DeviceLinkSink + - linkedPorts: + 183: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 183 components: - rot: 3.141592653589793 rad pos: -21.5,-32.5 parent: 31 type: Transform + - links: + - 182 + type: DeviceLinkSink + - linkedPorts: + 182: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 1594 components: - pos: 16.5,19.5 parent: 31 type: Transform + - links: + - 2465 + type: DeviceLinkSink + - linkedPorts: + 2465: + - DoorStatus: DoorBolt + type: DeviceLinkSource - uid: 2465 components: - pos: 16.5,22.5 parent: 31 type: Transform + - links: + - 1594 + type: DeviceLinkSink + - linkedPorts: + 1594: + - DoorStatus: DoorBolt + type: DeviceLinkSource - proto: AirlockExternalGlassShuttleArrivals entities: - uid: 1755 @@ -6385,6 +6513,8 @@ entities: - pos: -22.5,-21.5 parent: 31 type: Transform + - storageUsed: 5 + type: Storage - containers: storagebase: !type:Container showEnts: False @@ -6601,6 +6731,8 @@ entities: - pos: -35.410393,-24.380575 parent: 31 type: Transform + - storageUsed: 1 + type: Storage - containers: storagebase: !type:Container showEnts: False @@ -16104,6 +16236,13 @@ entities: - pos: 3.5,-24.5 parent: 31 type: Transform + - uid: 11270 + components: + - pos: 36.5,14.5 + parent: 31 + type: Transform + - enabled: True + type: AmbientSound - uid: 11274 components: - pos: -24.5,-15.5 @@ -30493,6 +30632,46 @@ entities: - pos: 16.5,-29.5 parent: 31 type: Transform +- proto: CrateEngineeringSecure + entities: + - uid: 11305 + components: + - desc: Stores logic gates that control the salvage-atmos airlocks. + name: logic gate crate + type: MetaData + - pos: 30.5,21.5 + parent: 31 + type: Transform + - air: + volume: 200 + immutable: False + temperature: 293.1496 + moles: + - 1.7459903 + - 6.568249 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + - 0 + type: EntityStorage + - containers: + entity_storage: !type:Container + showEnts: False + occludes: True + ents: + - 11306 + - 11307 + paper_label: !type:ContainerSlot + showEnts: False + occludes: True + ent: null + type: ContainerContainer - proto: CrateFilledSpawner entities: - uid: 1637 @@ -51578,6 +51757,46 @@ entities: - pos: 54.5,-1.5 parent: 31 type: Transform +- proto: LogicGate + entities: + - uid: 11306 + components: + - flags: InContainer + type: MetaData + - parent: 11305 + type: Transform + - links: + - 9067 + - 3052 + type: DeviceLinkSink + - linkedPorts: + 6522: + - Output: DoorBolt + 9068: + - Output: DoorBolt + type: DeviceLinkSource + - canCollide: False + type: Physics + - type: InsideEntityStorage + - uid: 11307 + components: + - flags: InContainer + type: MetaData + - parent: 11305 + type: Transform + - links: + - 6522 + - 9068 + type: DeviceLinkSink + - linkedPorts: + 3052: + - Output: DoorBolt + 9067: + - Output: DoorBolt + type: DeviceLinkSource + - canCollide: False + type: Physics + - type: InsideEntityStorage - proto: MachineAnomalyGenerator entities: - uid: 6098 @@ -72226,147 +72445,330 @@ entities: type: Transform - location: library type: WarpPoint - - uid: 1208 + - uid: 7640 components: - - pos: -36.5,5.5 + - pos: 49.5,-24.5 parent: 31 type: Transform - - location: evac + - location: observatory type: WarpPoint - - uid: 7275 +- proto: WarpPointBeaconBar + entities: + - uid: 6995 components: - - pos: -18.5,-0.5 + - pos: -7.5,12.5 parent: 31 type: Transform - - location: botany + - text: security + type: NavMapBeacon + - location: security type: WarpPoint - - uid: 7276 + - type: BombingTarget + - uid: 11267 components: - - pos: 33.5,4.5 + - pos: -12.5,19.5 parent: 31 type: Transform - - location: engineering + - text: armory + type: NavMapBeacon + - location: armory type: WarpPoint - - uid: 7640 + - type: BombingTarget + - uid: 11319 components: - - pos: 49.5,-24.5 + - pos: -17.5,9.5 parent: 31 type: Transform - - location: observatory - type: WarpPoint - - uid: 8316 + - text: permabrig + type: NavMapBeacon + - uid: 11320 components: - - pos: -36.5,15.5 + - pos: -10.5,8.5 parent: 31 type: Transform - - location: chapel - type: WarpPoint - - uid: 11268 + - text: cells + type: NavMapBeacon + - uid: 11321 components: - - pos: -47.5,-10.5 + - pos: -13.5,15.5 parent: 31 type: Transform - - location: arrivals - type: WarpPoint - - uid: 11270 + - text: locker room + type: NavMapBeacon +- proto: WarpPointBeaconCargo + entities: + - uid: 2142 components: - - pos: -25.5,-5.5 + - pos: 27.5,19.5 parent: 31 type: Transform - - location: dorms + - text: salvage + type: NavMapBeacon + - type: BombingTarget + - uid: 5767 + components: + - pos: 14.5,10.5 + parent: 31 + type: Transform + - location: cargo type: WarpPoint -- proto: WarpPointBombing + - type: BombingTarget + - uid: 11324 + components: + - pos: 21.5,17.5 + parent: 31 + type: Transform + - text: cargo bay + type: NavMapBeacon +- proto: WarpPointBeaconCommand entities: - - uid: 538 + - uid: 7262 components: - - pos: 3.5,30.5 + - pos: 9.5,19.5 parent: 31 type: Transform - - location: bridge + - text: hop's office + type: NavMapBeacon + - location: hop's office type: WarpPoint - - uid: 1136 + - type: BombingTarget + - uid: 7281 components: - - pos: 27.5,19.5 + - pos: 12.5,24.5 parent: 31 type: Transform - - location: salvage + - text: captain's room + type: NavMapBeacon + - location: captain's room type: WarpPoint - - uid: 2142 + - type: BombingTarget + - uid: 7954 components: - - pos: 14.5,10.5 + - pos: 3.5,30.5 parent: 31 type: Transform - - location: cargo + - text: bridge + type: NavMapBeacon + - location: bridge type: WarpPoint - - uid: 5767 + - type: BombingTarget + - uid: 11269 components: - - pos: -7.5,12.5 + - pos: -1.5,17.5 parent: 31 type: Transform - - location: security + - text: vault + type: NavMapBeacon + - location: vault type: WarpPoint - - uid: 6995 + - type: BombingTarget +- proto: WarpPointBeaconEngineering + entities: + - uid: 7256 + components: + - pos: 33.5,4.5 + parent: 31 + type: Transform + - text: engineering lobby + type: NavMapBeacon + - uid: 7261 components: - pos: 48.5,8.5 parent: 31 type: Transform - - location: ame - type: WarpPoint - - uid: 7256 + - text: ame + type: NavMapBeacon + - type: BombingTarget + - uid: 8316 components: - - pos: -4.5,-1.5 + - pos: 38.5,15.5 parent: 31 type: Transform - - location: bar + - text: atmospherics + type: NavMapBeacon + - location: atmospherics type: WarpPoint - - uid: 7261 + - type: BombingTarget + - uid: 11313 components: - - pos: 9.5,19.5 + - pos: 32.5,-2.5 parent: 31 type: Transform - - location: hop's office + - text: locker room + type: NavMapBeacon + - uid: 11314 + components: + - pos: 47.5,4.5 + parent: 31 + type: Transform + - text: materials + type: NavMapBeacon + - uid: 11315 + components: + - pos: 58.5,2.5 + parent: 31 + type: Transform + - text: particle accelerator + type: NavMapBeacon + - uid: 11325 + components: + - pos: 27.5,1.5 + parent: 31 + type: Transform + - text: drone closet + type: NavMapBeacon +- proto: WarpPointBeaconMedical + entities: + - uid: 9712 + components: + - pos: 16.5,-8.5 + parent: 31 + type: Transform + - type: BombingTarget + - uid: 11309 + components: + - pos: 9.5,-1.5 + parent: 31 + type: Transform + - text: medical lobby + type: NavMapBeacon + - uid: 11310 + components: + - pos: 8.5,-15.5 + parent: 31 + type: Transform + - text: cryo + type: NavMapBeacon + - uid: 11311 + components: + - pos: 13.5,-16.5 + parent: 31 + type: Transform + - text: morgue + type: NavMapBeacon + - uid: 11312 + components: + - pos: 16.5,-0.5 + parent: 31 + type: Transform + - text: chemistry + type: NavMapBeacon + - uid: 11323 + components: + - pos: 21.5,-6.5 + parent: 31 + type: Transform + - text: locker room + type: NavMapBeacon +- proto: WarpPointBeaconNeutral + entities: + - uid: 538 + components: + - pos: -36.5,5.5 + parent: 31 + type: Transform + - text: evac + type: NavMapBeacon + - location: evac type: WarpPoint - - uid: 7262 + - uid: 7276 components: - - pos: 12.5,24.5 + - pos: -47.5,-10.5 parent: 31 type: Transform - - location: captain's room + - text: arrivals + type: NavMapBeacon + - location: arrivals type: WarpPoint - uid: 7280 components: - - pos: 16.5,-8.5 + - pos: -25.5,-5.5 parent: 31 type: Transform - - location: medical + - text: dorms + type: NavMapBeacon + - location: dorms type: WarpPoint - - uid: 7281 + - uid: 11322 components: - - pos: 38.5,15.5 + - pos: 8.5,9.5 parent: 31 type: Transform - - location: atmospherics + - text: eva + type: NavMapBeacon + - location: eva type: WarpPoint - - uid: 10539 + - type: BombingTarget +- proto: WarpPointBeaconScience + entities: + - uid: 11316 components: - - pos: -9.5,-20.5 + - pos: -9.5,-29.5 parent: 31 type: Transform - - location: science - type: WarpPoint - - uid: 11267 + - text: xenoarch/anomalies + type: NavMapBeacon + - uid: 11317 components: - - pos: -12.5,19.5 + - pos: -1.5,-28.5 parent: 31 type: Transform - - location: armory + - text: robotics + type: NavMapBeacon + - uid: 11318 + components: + - pos: -15.5,-22.5 + parent: 31 + type: Transform + - text: research & development + type: NavMapBeacon +- proto: WarpPointBeaconService + entities: + - uid: 1136 + components: + - pos: -4.5,-1.5 + parent: 31 + type: Transform + - text: bar + type: NavMapBeacon + - uid: 1208 + components: + - pos: -18.5,-0.5 + parent: 31 + type: Transform + - text: botany + type: NavMapBeacon + - uid: 7275 + components: + - pos: -36.5,15.5 + parent: 31 + type: Transform + - text: chapel + type: NavMapBeacon + - location: chapel type: WarpPoint - - uid: 11269 + - uid: 11268 components: - - pos: -1.5,17.5 + - pos: -11.5,-0.5 parent: 31 type: Transform - - location: vault + - text: kitchen + type: NavMapBeacon + - uid: 11308 + components: + - pos: -18.5,-7.5 + parent: 31 + type: Transform + - text: theatre + type: NavMapBeacon +- proto: WarpPointBombing + entities: + - uid: 10539 + components: + - pos: -9.5,-20.5 + parent: 31 + type: Transform + - location: science type: WarpPoint - proto: WaterCooler entities: diff --git a/Resources/Prototypes/Accents/word_replacements.yml b/Resources/Prototypes/Accents/word_replacements.yml index d12308e4179..befcfa6e6c7 100644 --- a/Resources/Prototypes/Accents/word_replacements.yml +++ b/Resources/Prototypes/Accents/word_replacements.yml @@ -319,7 +319,6 @@ accent-archaic-replaced-50: accent-archaic-replacement-50 accent-archaic-replaced-51: accent-archaic-replacement-51 accent-archaic-replaced-52: accent-archaic-replacement-52 - accent-archaic-replaced-53: accent-archaic-replacement-53 accent-archaic-replaced-54: accent-archaic-replacement-54 accent-archaic-replaced-55: accent-archaic-replacement-55 accent-archaic-replaced-56: accent-archaic-replacement-56 diff --git a/Resources/Prototypes/Body/Organs/Animal/slimes.yml b/Resources/Prototypes/Body/Organs/Animal/slimes.yml new file mode 100644 index 00000000000..f5d94554498 --- /dev/null +++ b/Resources/Prototypes/Body/Organs/Animal/slimes.yml @@ -0,0 +1,56 @@ +- type: entity + id: SentientSlimesCore + parent: [BaseItem, OrganHumanBrain] + name: sentient slimes core + description: "The source of incredible, unending gooeyness." + components: + - type: Sprite + sprite: Mobs/Species/Slime/organs.rsi + state: brain-slime + - type: Stomach + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [ Slime ] + removeEmpty: true + groups: + - id: Food + - id: Drink + - id: Medicine + - id: Poison + - id: Narcotic + - id: Alcohol + rateModifier: 0.2 + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 30.0 + +- type: entity + id: OrganSlimesLungs + parent: BaseHumanOrgan + name: slimes gas sacs + description: "Collects nitrogen, which slime cells use for maintenance." + components: + - type: Sprite + sprite: Mobs/Species/Slime/organs.rsi + layers: + - state: lung-l-slime + - state: lung-r-slime + - type: Lung + - type: Metabolizer + removeEmpty: true + solutionOnBody: false + solution: "Lung" + metabolizerTypes: [ Slime ] + groups: + - id: Gas + rateModifier: 100.0 + - type: SolutionContainerManager + solutions: + organ: + reagents: + - ReagentId: Nutriment + Quantity: 10 + Lung: + maxVol: 100.0 + canReact: false diff --git a/Resources/Prototypes/Body/Organs/slime.yml b/Resources/Prototypes/Body/Organs/slime.yml index 4bb07da4dc2..e6ce18b335d 100644 --- a/Resources/Prototypes/Body/Organs/slime.yml +++ b/Resources/Prototypes/Body/Organs/slime.yml @@ -4,6 +4,9 @@ name: sentient slime core description: "The source of incredible, unending gooeyness." components: + - type: Sprite + sprite: Mobs/Species/Slime/organs.rsi + state: brain-slime - type: Stomach - type: Metabolizer maxReagents: 6 @@ -35,9 +38,10 @@ description: "Collects nitrogen, which slime cells use for maintenance." components: - type: Sprite + sprite: Mobs/Species/Slime/organs.rsi layers: - - state: lung-l - - state: lung-r + - state: lung-l-slime + - state: lung-r-slime - type: Lung - type: Metabolizer removeEmpty: true diff --git a/Resources/Prototypes/Body/Prototypes/Animal/slimes.yml b/Resources/Prototypes/Body/Prototypes/Animal/slimes.yml new file mode 100644 index 00000000000..8d9827e99a0 --- /dev/null +++ b/Resources/Prototypes/Body/Prototypes/Animal/slimes.yml @@ -0,0 +1,18 @@ +- type: body + id: Slimes + name: "slimes" + root: torso + slots: + torso: + part: TorsoSlime + connections: + - legs + organs: + core: SentientSlimesCore + lungs: OrganSlimesLungs + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index b904825de6f..2f246c6cd13 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -22,6 +22,7 @@ - id: ClothingHeadsetAltCargo - id: BoxEncryptionKeyCargo - id: SpaceCashLuckyBill # DeltaV - HoL steal objective, see Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml + - id: BoxPDACargo # Delta-V - type: entity id: LockerCaptainFilledHardsuit @@ -148,6 +149,7 @@ - id: ClothingHeadsetAltEngineering - id: BoxEncryptionKeyEngineering - id: AccessConfigurator + - id: BoxPDAEngineering # Delta-V - type: entity id: LockerChiefEngineerFilled @@ -170,6 +172,7 @@ - id: ClothingHeadsetAltEngineering - id: BoxEncryptionKeyEngineering - id: AccessConfigurator + - id: BoxPDAEngineering # Delta-V - type: entity id: LockerChiefMedicalOfficerFilledHardsuit @@ -194,6 +197,7 @@ - id: RubberStampCMO - id: MedicalTechFabCircuitboard - id: BoxEncryptionKeyMedical + - id: BoxPDAMedical # Delta-V - type: entity id: LockerChiefMedicalOfficerFilled @@ -217,6 +221,7 @@ - id: RubberStampCMO - id: MedicalTechFabCircuitboard - id: BoxEncryptionKeyMedical + - id: BoxPDAMedical # Delta-V - type: entity id: LockerResearchDirectorFilledHardsuit @@ -239,6 +244,7 @@ - id: RubberStampRd - id: ClothingHeadsetAltScience - id: BoxEncryptionKeyScience + - id: BoxPDAScience # Delta-V - type: entity id: LockerResearchDirectorFilled @@ -260,6 +266,7 @@ - id: RubberStampRd - id: ClothingHeadsetAltScience - id: BoxEncryptionKeyScience + - id: BoxPDAScience # Delta-V - type: entity id: LockerHeadOfSecurityFilledHardsuit @@ -293,6 +300,7 @@ - id: BoxEncryptionKeySecurity - id: HoloprojectorSecurity - id: BookSecretDocuments + - id: BoxPDASecurity # Delta-V - type: entity id: LockerHeadOfSecurityFilled @@ -323,3 +331,4 @@ - id: BoxEncryptionKeySecurity - id: HoloprojectorSecurity - id: BookSecretDocuments + - id: BoxPDASecurity # Delta-V diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index 751508a6c63..f127e3708b2 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -23,6 +23,7 @@ - id: ClothingOuterHardsuitWarden - id: HoloprojectorSecurity - id: ClothingEyesHudSecurity + - id: BoxPDAPrisoner # Delta-V - type: entity id: LockerWardenFilled @@ -48,6 +49,7 @@ - id: DoorRemoteArmory - id: HoloprojectorSecurity - id: ClothingEyesHudSecurity + - id: BoxPDAPrisoner # Delta-V - type: entity id: LockerSecurityFilled @@ -61,6 +63,8 @@ - id: ClothingUniformJumpsuitSecGrey prob: 0.3 - id: ClothingHeadHelmetBasic + - id: ClothingHeadHelmetInsulated # Nyanotrasen - Insulative headgear + prob: 0.4 - id: ClothingOuterArmorBasic - id: ClothingBeltSecurityFilled - id: Flash diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml index 3c539243c93..44ec34e1569 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml @@ -13,6 +13,10 @@ MagazineBoxMagnumPractice: 3 MagazineBoxMagnumRubber: 3 + MagazineBoxSpecial: 3 # DeltaV - .38 Special revolver + MagazineBoxSpecialPractice: 3 # DeltaV - .38 Special revolver + MagazineBoxSpecialRubber: 3 # DeltaV - .38 Special revolver + MagazineBoxPistol: 3 MagazineBoxPistolPractice: 3 MagazineBoxPistolRubber: 3 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cart.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cart.yml index cb0ef3246d3..5a96ea8cf4f 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cart.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cart.yml @@ -3,14 +3,32 @@ startingInventory: PassengerPDA: 5 ClearPDA: 5 +# Begin Delta-V additions + ServiceWorkerPDA: 2 + ChefPDA: 2 + BotanistPDA: 2 + BartenderPDA: 2 + JanitorPDA: 2 + LibrarianPDA: 1 + LawyerPDA: 1 + ReporterPDA: 1 + ZookeeperPDA: 1 + BoxerPDA: 1 + ClownPDA: 1 + MimePDA: 1 + MusicianPDA: 1 +# End Delta-V additions PassengerIDCard: 5 ClothingHeadsetGrey: 5 + ClothingHeadsetService: 5 # Delta-V RubberStampApproved: 1 RubberStampDenied: 1 Paper: 10 - EncryptionKeyCargo: 2 - EncryptionKeyEngineering: 2 - EncryptionKeyMedical: 2 - EncryptionKeyScience: 2 - EncryptionKeySecurity: 1 +# Begin Delta-V subtractions + # EncryptionKeyCargo: 2 + # EncryptionKeyEngineering: 2 + # EncryptionKeyMedical: 2 + # EncryptionKeyScience: 2 + # EncryptionKeySecurity: 1 +# End Delta-V subtractions EncryptionKeyService: 3 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chapel.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chapel.yml index c90a5bce143..bd342ba86b7 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chapel.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chapel.yml @@ -15,7 +15,7 @@ ClothingHeadHatWitch1: 1 ClothingOuterPlagueSuit: 1 ClothingMaskPlague: 1 - ClothingHeadsetService: 2 + #ClothingHeadsetService: 2 # Delta-V - Chaplain is no longer service dept emaggedInventory: ClothingOuterArmorCult: 1 ClothingHeadHelmetCult: 1 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cigs.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cigs.yml index dfbf2c1c9d4..725c1917f51 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cigs.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cigs.yml @@ -8,7 +8,7 @@ CigPackMixed: 2 CigarCase: 1 SmokingPipeFilledTobacco: 1 - Vape: 1 + # Vape: 1 # DeltaV - Disable the Vape Matchbox: 5 PackPaperRollingFilters: 3 CheapLighter: 4 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/clothesmate.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/clothesmate.yml index e263903ef50..554989b5cee 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/clothesmate.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/clothesmate.yml @@ -58,6 +58,7 @@ ClothingHeadFishCap: 2 ClothingHeadRastaHat: 2 ClothingBeltStorageWaistbag: 3 + ClothingEyesGlasses: 6 contrabandInventory: ClothingUniformJumpsuitTacticool: 1 ClothingUniformJumpskirtTacticool: 1 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/medical.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/medical.yml index 43e7cf7c941..b171da401f1 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/medical.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/medical.yml @@ -7,3 +7,5 @@ Bloodpack: 5 EpinephrineChemistryBottle: 3 Syringe: 5 + ClothingEyesGlasses: 5 # SimpleStation14 NearsightedTrait + diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml index 658a955b88a..c6ce01d127d 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml @@ -12,6 +12,8 @@ RiotShield: 2 RiotLaserShield: 2 RiotBulletShield: 2 + ClothingHeadHelmetInsulated: 2 # Nyanotrasen - Insulative headgear + ClothingHeadCage: 2 # Nyanotrasen - Insulative headgear # security officers need to follow a diet regimen! contrabandInventory: FoodDonutHomer: 12 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/winterdrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/winterdrobe.yml index 55144b606e0..11e992adfb5 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/winterdrobe.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/winterdrobe.yml @@ -10,6 +10,7 @@ ClothingNeckScarfStripedOrange: 3 ClothingNeckScarfStripedPurple: 3 ClothingOuterWinterCoat: 6 + ClothingShoesBootsWinter: 6 ClothingOuterCoatBomber: 3 ClothingHeadHatSantahat: 2 ClothingHeadHatXmasCrown: 2 diff --git a/Resources/Prototypes/Datasets/tips.yml b/Resources/Prototypes/Datasets/tips.yml index 3ccb3849a78..38e6395c233 100644 --- a/Resources/Prototypes/Datasets/tips.yml +++ b/Resources/Prototypes/Datasets/tips.yml @@ -123,3 +123,19 @@ - "Monkeys have a rare chance to be sentient. Ook!" - "You can tell if an area with firelocks up is spaced by looking to see if the firelocks have lights besides them." - "Instead of picking it up, you can alt-click food to eat it. This also works for mice and other creatures without hands." + # Nyanotrasen - Specific tips below + - "Psionic insulation prevents you from using or being targeted by psionic abilities. Look for insulative headgear or cryptobiolin pills." + - "Lotophagoi oil from the oracle will drug you up for a long time, but is one of the most reliable sources of psionics." + - "Turn off glimmer probers when glimmer approaches cautious levels." + - "Glimmer probers power themselves when glimmer gets too high." + - "Oneirophages have psionic invisiblity. Psionic insulation will allow you to see them." + - "Someone who looks just like you may be a paradox anomaly." + - "Rat kings can command their rats to attack someone by pointing at them." + - "Some rat kings are known to be friendly. As long as the rat army never goes rogue, it could be a great boon to the station." + - "The reverse engineering machine benefits greatly from machine upgrades." + - "The reverse engineering machine can reverse engineer blood red hardsuits." + # - "You can perform CPR by using an empty hand on someone in critical condition." + - "The metempsychotic machine's chance to reincarnate you into a humanoid is guaranteed for a number of times equal to its scanning module tier." + - "Glimmer wisps will only attack you if they detect you are psionic, or you aggravate them by damaging them or dragging away a body they are trying to drain." + - "Bibles, holy water, and the anti-psychic knife can deal holy damage, which has strong effects against some creatures." + - "Ectoplasm is used in the recipe for normality crystals." diff --git a/Resources/Prototypes/DeltaV/Catalog/Fills/Boxes/pda.yml b/Resources/Prototypes/DeltaV/Catalog/Fills/Boxes/pda.yml new file mode 100644 index 00000000000..4df625c71ad --- /dev/null +++ b/Resources/Prototypes/DeltaV/Catalog/Fills/Boxes/pda.yml @@ -0,0 +1,84 @@ +- type: entity + name: security PDA box + parent: BoxPDA + id: BoxPDASecurity + description: A box of spare PDA microcomputers for the security department. + components: + - type: StorageFill + contents: + - id: SecurityPDA + amount: 2 + - id: SecurityCadetPDA + - id: DetectivePDA + - id: WardenPDA + - id: SeniorOfficerPDA + +- type: entity + name: prisoner PDA box + parent: BoxPDA + id: BoxPDAPrisoner + description: A box of spare PDA microcomputers for the warden to use for prisoners. + components: + - type: StorageFill + contents: + - id: PrisonerPDA + amount: 6 + +- type: entity + name: medical PDA box + parent: BoxPDA + id: BoxPDAMedical + description: A box of spare PDA microcomputers for the medical department. + components: + - type: StorageFill + contents: + - id: MedicalPDA + amount: 2 + - id: MedicalInternPDA + - id: ChemistryPDA + - id: ParamedicPDA + - id: SeniorPhysicianPDA + +- type: entity + name: epistemics PDA box + parent: BoxPDA + id: BoxPDAScience + description: A box of spare PDA microcomputers for the epistemics department. + components: + - type: StorageFill + contents: + - id: SciencePDA + amount: 2 + - id: ResearchAssistantPDA + - id: ForensicMantisPDA + - id: ChaplainPDA + - id: SeniorResearcherPDA + +- type: entity + name: engineering PDA box + parent: BoxPDA + id: BoxPDAEngineering + description: A box of spare PDA microcomputers for the engineering department. + components: + - type: StorageFill + contents: + - id: EngineerPDA + amount: 3 + - id: TechnicalAssistantPDA + - id: AtmosPDA + - id: SeniorEngineerPDA + +- type: entity + name: logistics PDA box + parent: BoxPDA + id: BoxPDACargo + description: A box of spare PDA microcomputers for the logistics department. + components: + - type: StorageFill + contents: + - id: CargoPDA + amount: 2 + - id: SalvagePDA + amount: 2 + - id: MailCarrierPDA + amount: 2 diff --git a/Resources/Prototypes/DeltaV/Damage/modifier_sets.yml b/Resources/Prototypes/DeltaV/Damage/modifier_sets.yml new file mode 100644 index 00000000000..370ef1849d9 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Damage/modifier_sets.yml @@ -0,0 +1,4 @@ +- type: damageModifierSet + id: Vulpkanin + coefficients: + Heat: 1.15 diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml index 9b4414288cb..bb25a30471e 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml @@ -80,15 +80,19 @@ animation: WeaponArcClaw damage: types: - Blunt: 1 - Slash: 5 + Blunt: 2 + Slash: 3 - type: Perishable + - type: Damageable + damageModifierSet: Vulpkanin # - type: Carriable - type: TemperatureProtection coefficient: 0.1 - - type: Thieving - stealthy: true - stripTimeReduction: 1 + - type: Vocal + sounds: + Male: MaleVulpakin + Female: FemaleVulpakin + Unsexed: MaleVulpakin - type: entity save: false diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml new file mode 100644 index 00000000000..556707ed798 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml @@ -0,0 +1,167 @@ +- type: entity + noSpawn: true + parent: BaseMail + id: MailBooksAll # See Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/books.yml + suffix: books + components: + - type: Mail + contents: + # Author Books + - id: BookNarsieLegend + prob: 0.02 + orGroup: bookauthor + - id: BookTruth + prob: 0.02 + orGroup: bookauthor + - id: BookWorld + prob: 0.1 + orGroup: bookauthor + - id: BookIanAntarctica + prob: 0.05 + orGroup: bookauthor + - id: BookSlothClownSSS + prob: 0.04 + orGroup: bookauthor + - id: BookSlothClownPranks + prob: 0.04 + orGroup: bookauthor + - id: BookSlothClownMMD + prob: 0.04 + orGroup: bookauthor + - id: BookStruck + prob: 0.1 + orGroup: bookauthor + - id: BookSun + prob: 0.1 + orGroup: bookauthor + - id: BookPossum + prob: 0.1 + orGroup: bookauthor + - id: BookCafe + prob: 0.1 + orGroup: bookauthor + - id: BookFeather + prob: 0.1 + orGroup: bookauthor + - id: BookIanLostWolfPup + prob: 0.05 + orGroup: bookauthor + - id: BookIanRanch + prob: 0.05 + orGroup: bookauthor + - id: BookIanOcean + prob: 0.05 + orGroup: bookauthor + - id: BookIanMountain + prob: 0.05 + orGroup: bookauthor + - id: BookIanCity + prob: 0.05 + orGroup: bookauthor + - id: BookIanArctic + prob: 0.05 + orGroup: bookauthor + - id: BookIanDesert + prob: 0.05 + orGroup: bookauthor + - id: BookNames + prob: 0.08 + orGroup: bookauthor + - id: BookEarth + prob: 0.08 + orGroup: bookauthor + - id: BookTemple + prob: 0.09 + orGroup: bookauthor + - id: BookAurora + prob: 0.1 + orGroup: bookauthor + - id: BookWatched + prob: 0.04 + orGroup: bookauthor + - id: BookMedicalOfficer + prob: 0.06 + orGroup: bookauthor + - id: BookMorgue + prob: 0.06 + orGroup: bookauthor + - id: BookRufus + prob: 0.1 + orGroup: bookauthor + - id: BookMap + prob: 0.08 + orGroup: bookauthor + - id: BookJourney + prob: 0.1 + orGroup: bookauthor + - id: BookInspiration + prob: 0.09 + orGroup: bookauthor + - id: BookRandom # The "spawn nothing" in the 'orGroup' + prob: 0.3 + orGroup: bookauthor + # id: Guidebook Books + - id: BookSpaceEncyclopedia + prob: 0.2 + orGroup: bookguide + - id: BookTheBookOfControl + prob: 0.2 + orGroup: bookguide + - id: BookBartendersManual + prob: 0.2 + orGroup: bookguide + - id: BookChefGaming + prob: 0.2 + orGroup: bookguide + - id: BookLeafLoversSecret + prob: 0.2 + orGroup: bookguide + - id: BookEngineersHandbook + prob: 0.2 + orGroup: bookguide + - id: BookScientistsGuidebook + prob: 0.15 + orGroup: bookguide + - id: BookSecurity + prob: 0.2 + orGroup: bookguide + - id: BookHowToKeepStationClean + prob: 0.2 + orGroup: bookguide + - id: BookHowToRockAndStone + prob: 0.2 + orGroup: bookguide + - id: BookMedicalReferenceBook + prob: 0.2 + orGroup: bookguide + - id: BookHowToSurvive + prob: 0.3 + orGroup: bookguide + - id: BookChemicalCompendium + prob: 0.15 + orGroup: bookguide + - id: BookRandom # The "spawn nothing" in the 'orGroup' + prob: 0.5 + orGroup: bookguide + # Other Books + - id: BookEscalation + prob: 0.2 + orGroup: bookother + - id: BookEscalationSecurity + prob: 0.15 + orGroup: bookother + - id: BookAtmosDistro + prob: 0.1 + orGroup: bookother + - id: BookAtmosWaste + prob: 0.1 + orGroup: bookother + - id: BookAtmosAirAlarms + prob: 0.1 + orGroup: bookother + - id: BookAtmosVentsMore + prob: 0.1 + orGroup: bookother + - id: BookRandom # The "spawn nothing" in the 'orGroup' + prob: 0.7 + orGroup: bookother diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/special.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/special.yml new file mode 100644 index 00000000000..1ca4cc5a573 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Boxes/special.yml @@ -0,0 +1,69 @@ +- type: entity + abstract: true + parent: BaseItem + id: BaseMagazineBoxSpecial + components: + - type: BallisticAmmoProvider + mayTransfer: true + whitelist: + tags: + - CartridgeSpecial + proto: CartridgeSpecial + capacity: 60 + - type: Item + size: 5 + - type: ContainerContainer + containers: + ballistic-ammo: !type:Container + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi + - type: MagazineVisuals + magState: mag + steps: 2 + zeroVisible: false + - type: Appearance + +# Boxes +- type: entity + parent: BaseMagazineBoxSpecial + id: MagazineBoxSpecial + name: ammunition box (.38 special) + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecial + - type: Sprite + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-1 + map: ["enum.GunVisualLayers.Mag"] + +- type: entity + parent: BaseMagazineBoxSpecial + id: MagazineBoxSpecialPractice + name: ammunition box (.38 special practice) + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecialPractice + - type: Sprite + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-1 + map: ["enum.GunVisualLayers.Mag"] + - state: practice + +- type: entity + parent: BaseMagazineBoxSpecial + id: MagazineBoxSpecialRubber + name: ammunition box (.38 special rubber) + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecialRubber + - type: Sprite + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-1 + map: ["enum.GunVisualLayers.Mag"] + - state: rubber diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/special.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/special.yml new file mode 100644 index 00000000000..b2e72bcbd5c --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/special.yml @@ -0,0 +1,70 @@ +- type: entity + id: BaseCartridgeSpecial + name: cartridge (.38 special) + parent: BaseCartridge + abstract: true + components: + - type: Tag + tags: + - Cartridge + - CartridgeSpecial + - type: CartridgeAmmo + proto: BulletSpecial + - type: Sprite + sprite: Objects/Weapons/Guns/Ammunition/Casings/ammo_casing.rsi + layers: + - state: base + map: ["enum.AmmoVisualLayers.Base"] + - type: Appearance + - type: SpentAmmoVisuals + - type: StaticPrice + price: 10 + +- type: entity + id: CartridgeSpecial + name: cartridge (.38 special) + parent: BaseCartridgeSpecial + components: + - type: CartridgeAmmo + proto: BulletSpecial + +- type: entity + id: CartridgeSpecialPractice + name: cartridge (.38 special practice) + parent: BaseCartridgeSpecial + components: + - type: CartridgeAmmo + proto: BulletSpecialPractice + +- type: entity + id: CartridgeSpecialRubber + name: cartridge (.38 special rubber) + parent: BaseCartridgeSpecial + components: + - type: CartridgeAmmo + proto: BulletSpecialRubber + +- type: entity + id: CartridgeSpecialHoly + name: cartridge (.38 special holy) + parent: BaseCartridgeSpecial + components: + - type: CartridgeAmmo + proto: BulletSpecialHoly + +- type: entity + id: CartridgeSpecialMindbreaker + name: cartridge (.38 special mindbreaker) + parent: BaseCartridgeSpecial + components: + - type: CartridgeAmmo + proto: BulletSpecialMindbreaker + - type: ChemicalAmmo + - type: SolutionContainerManager + solutions: + ammo: + reagents: + - ReagentId: MindbreakerToxin + Quantity: 10 + - type: SolutionTransfer + maxTransferAmount: 10 diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/special.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/special.yml new file mode 100644 index 00000000000..b477d685dbf --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/special.yml @@ -0,0 +1,57 @@ +- type: entity + id: BulletSpecial + name: bullet (.38 special) + parent: BaseBullet + noSpawn: true + components: + - type: Projectile + damage: + types: + Piercing: 30 + +- type: entity + id: BulletSpecialPractice + name: bullet (.38 special practice) + parent: BaseBulletPractice + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 1 + +- type: entity + id: BulletSpecialRubber + name: bullet (.38 special rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + - type: StaminaDamageOnCollide + damage: 35 # 3 hits to stun cuz revolver + +- type: entity + id: BulletSpecialHoly + name: bullet (.38 special holy) + parent: BaseBullet + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + Holy: 5 + +- type: entity + id: BulletSpecialMindbreaker + name: bullet (.38 special mindbreaker) + parent: BaseBullet + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/SpeedLoaders/special.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/SpeedLoaders/special.yml new file mode 100644 index 00000000000..86f68b3c970 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Ammunition/SpeedLoaders/special.yml @@ -0,0 +1,100 @@ +- type: entity + id: BaseSpeedLoaderSpecial + name: "speed loader (.38 special)" + parent: BaseItem + abstract: true + components: + - type: Tag + tags: + - SpeedLoaderSpecial + - type: SpeedLoader + - type: BallisticAmmoProvider + whitelist: + tags: + - CartridgeSpecial + capacity: 6 + - type: Sprite + - type: ContainerContainer + containers: + ballistic-ammo: !type:Container + ents: [] + +- type: entity + id: SpeedLoaderSpecial + name: "speed loader (.38 special)" + parent: BaseSpeedLoaderSpecial + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecial + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi + layers: + - state: base + map: [ "enum.GunVisualLayers.Base" ] + - state: base-6 + map: [ "enum.GunVisualLayers.Mag" ] + - type: MagazineVisuals + magState: base + steps: 7 + zeroVisible: false + - type: Appearance + +- type: entity + id: SpeedLoaderSpecialMindbreaker + name: "speed loader (.38 special mindbreaker)" + parent: BaseSpeedLoaderSpecial + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecialMindbreaker + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi + layers: + - state: base + map: [ "enum.GunVisualLayers.Base" ] + - state: high-velocity-6 + map: [ "enum.GunVisualLayers.Mag" ] + - type: MagazineVisuals + magState: high-velocity + steps: 7 + zeroVisible: false + - type: Appearance + +- type: entity + id: SpeedLoaderSpecialPractice + name: "speed loader (.38 special practice)" + parent: BaseSpeedLoaderSpecial + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecialPractice + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi + layers: + - state: base + map: [ "enum.GunVisualLayers.Base" ] + - state: practice-6 + map: [ "enum.GunVisualLayers.Mag" ] + - type: MagazineVisuals + magState: practice + steps: 7 + zeroVisible: false + - type: Appearance + +- type: entity + id: SpeedLoaderSpecialRubber + name: "speed loader (.38 special rubber)" + parent: BaseSpeedLoaderSpecial + components: + - type: BallisticAmmoProvider + proto: CartridgeSpecialRubber + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi + layers: + - state: base + map: [ "enum.GunVisualLayers.Base" ] + - state: rubber-6 + map: [ "enum.GunVisualLayers.Mag" ] + - type: MagazineVisuals + magState: rubber + steps: 7 + zeroVisible: false + - type: Appearance diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml index d12ee1cd643..d5591de3899 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml @@ -21,3 +21,106 @@ capacity: 6 chambers: [ True, True, True, True, True, True ] ammoSlots: [ null, null, null, null, null, null ] + +- type: entity + name: K-38 Masterpiece + parent: BaseWeaponRevolver + id: WeaponRevolverK38Master + description: A classic, if not outdated, law enforcement firearm. Uses .38 Special rounds. + components: + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi + - type: Clothing + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi + - type: Gun + selectedMode: SemiAuto + fireRate: 1.5 + availableModes: + - SemiAuto + - type: RevolverAmmoProvider + whitelist: + tags: + - CartridgeSpecial + - SpeedLoaderSpecial + proto: CartridgeSpecialRubber + capacity: 6 + chambers: [ True, True, True, True, True, True ] + ammoSlots: [ null, null, null, null, null, null ] + +- type: entity + name: Fitz Special + parent: BaseWeaponRevolver + id: WeaponRevolverFitz + description: A compact and concealable self defence snub revolver. Uses .38 Special rounds. + components: + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi + - type: Clothing + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi + - type: Gun + selectedMode: SemiAuto + fireRate: 1.5 + availableModes: + - SemiAuto + - type: RevolverAmmoProvider + whitelist: + tags: + - CartridgeSpecial + - SpeedLoaderSpecial + proto: CartridgeSpecialRubber + capacity: 6 + chambers: [ True, True, True, True, True, True ] + ammoSlots: [ null, null, null, null, null, null ] + +- type: entity + name: Lucky 37 + parent: BaseWeaponRevolver + id: WeaponRevolverLucky + description: Luck always beats skill, ya weasel. Uses .38 Special rounds. + components: + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi + - type: Clothing + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi + - type: Gun + selectedMode: SemiAuto + fireRate: 1.5 + availableModes: + - SemiAuto + - type: RevolverAmmoProvider + whitelist: + tags: + - CartridgeSpecial + - SpeedLoaderSpecial + proto: CartridgeSpecial + capacity: 6 + chambers: [ True, True, True, True, True, True ] + ammoSlots: [ null, null, null, null, null, null ] + - type: StaticPrice + price: 750 + +- type: entity + name: Faith + parent: BaseWeaponRevolver + id: WeaponRevolverFaith + description: Delivers blessings in bullet form. Uses .38 Special rounds. + components: + - type: Sprite + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi + - type: Clothing + sprite: DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi + - type: Gun + selectedMode: SemiAuto + fireRate: 1 + availableModes: + - SemiAuto + - type: RevolverAmmoProvider + whitelist: + tags: + - CartridgeSpecial + proto: CartridgeSpecialHoly + capacity: 4 + chambers: [ True, True, True, True ] + ammoSlots: [ null, null, null, null ] + - type: StaticPrice + price: 1500 diff --git a/Resources/Prototypes/DeltaV/Recipes/Lathes/security.yml b/Resources/Prototypes/DeltaV/Recipes/Lathes/security.yml new file mode 100644 index 00000000000..a937a28e766 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Recipes/Lathes/security.yml @@ -0,0 +1,54 @@ +- type: latheRecipe + id: SpeedLoaderSpecial + result: SpeedLoaderSpecial + completetime: 5 + materials: + Steel: 200 + +- type: latheRecipe + id: CartridgeSpecial + result: CartridgeSpecial + completetime: 2 + materials: + Steel: 20 + +- type: latheRecipe + id: CartridgeSpecialRubber + result: CartridgeSpecialRubber + completetime: 2 + materials: + Plastic: 5 + Steel: 5 + +- type: latheRecipe + id: CartridgeSpecialHoly + result: CartridgeSpecialHoly + completetime: 2 + materials: + Plastic: 5 + Steel: 5 + Silver: 5 + +- type: latheRecipe + id: CartridgeSpecialMindbreaker + result: CartridgeSpecialMindbreaker + completetime: 2 + materials: + Plastic: 5 + Steel: 5 + Bluespace: 5 + +- type: latheRecipe + id: MagazineBoxSpecial + result: MagazineBoxSpecial + completetime: 5 + materials: + Steel: 1000 + +- type: latheRecipe + id: MagazineBoxSpecialRubber + result: MagazineBoxSpecialRubber + completetime: 5 + materials: + Steel: 350 + Plastic: 300 diff --git a/Resources/Prototypes/DeltaV/Research/arsenal.yml b/Resources/Prototypes/DeltaV/Research/arsenal.yml new file mode 100644 index 00000000000..2309360f2d8 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Research/arsenal.yml @@ -0,0 +1,15 @@ +# Tier 2 + +- type: technology + id: ExoticAmmunition + name: research-technology-exotic-ammunition + icon: + sprite: Objects/Weapons/Guns/Ammunition/Casings/shotgun_shell.rsi + state: beanbag + discipline: Arsenal + tier: 1 + cost: 7500 + recipeUnlocks: + - CartridgeSpecialHoly # DeltaV - .38 Special revolver, Holy ammo + - CartridgeSpecialMindbreaker # DeltaV - .38 Special revolver, Mindbreaker ammo + # - ShellSoulbreaker # Nyanotrasen - Soulbreaker shotgun ammo diff --git a/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml b/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml new file mode 100644 index 00000000000..df380d2aead --- /dev/null +++ b/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml @@ -0,0 +1,26 @@ +- type: soundCollection + id: VulpakinBarks + files: + - /Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg + +- type: soundCollection + id: VulpakinGrowls + files: + - /Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg + +- type: soundCollection + id: VulpakinSnarls + files: + - /Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg + - /Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg + +- type: soundCollection + id: VulpakinWhines + files: + - /Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg + diff --git a/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml b/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml new file mode 100644 index 00000000000..c75361b843b --- /dev/null +++ b/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml @@ -0,0 +1,52 @@ +# species +- type: emoteSounds + id: MaleVulpakin + params: + variation: 0.125 + sounds: + Scream: + collection: MaleScreams + Laugh: + collection: MaleLaugh + Sneeze: + collection: MaleSneezes + Cough: + collection: MaleCoughs + Crying: + collection: MaleCry + Whistle: + collection: Whistles + Growl: + collection: VulpakinGrowls + Snarl: + collection: VulpakinSnarls + Bark: + collection: VulpakinBarks + Whine: + collection: VulpakinWhines + +- type: emoteSounds + id: FemaleVulpakin + params: + variation: 0.125 + sounds: + Scream: + collection: FemaleScreams + Laugh: + collection: FemaleLaugh + Sneeze: + collection: FemaleSneezes + Cough: + collection: FemaleCoughs + Crying: + collection: FemaleCry + Whistle: + collection: Whistles + Growl: + collection: VulpakinGrowls + Snarl: + collection: VulpakinSnarls + Bark: + collection: VulpakinBarks + Whine: + collection: VulpakinWhines diff --git a/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml b/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml new file mode 100644 index 00000000000..e2b2910c329 --- /dev/null +++ b/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml @@ -0,0 +1,34 @@ +# vocal emotes +- type: emote + id: Bark + category: Vocal + chatMessages: [barks.] + chatTriggers: + - bark + - barks + - barks. + - barks! + - barking + - barked +- type: emote + id: Snarl + category: Vocal + chatMessages: [snarls.] + chatTriggers: + - snarl + - snarls + - snarls. + - snarls! + - snarling + - snarled +- type: emote + id: Whine + category: Vocal + chatMessages: [whines.] + chatTriggers: + - whine + - whines + - whines. + - whines! + - whining + - whined diff --git a/Resources/Prototypes/DeltaV/shaders.yml b/Resources/Prototypes/DeltaV/shaders.yml new file mode 100644 index 00000000000..a7501a53725 --- /dev/null +++ b/Resources/Prototypes/DeltaV/shaders.yml @@ -0,0 +1,8 @@ +# hologram +- type: shader + id: Hologram + kind: source + path: "/Textures/DeltaV/Shaders/hologram.swsl" + params: + textureHeight: 32 + hue: 0.64 diff --git a/Resources/Prototypes/DeltaV/tags.yml b/Resources/Prototypes/DeltaV/tags.yml index c8f27bbfcc5..fe57f716093 100644 --- a/Resources/Prototypes/DeltaV/tags.yml +++ b/Resources/Prototypes/DeltaV/tags.yml @@ -7,4 +7,10 @@ id: ForensicBeltEquip - type: Tag - id: HandLabeler \ No newline at end of file + id: HandLabeler + +- type: Tag + id: CartridgeSpecial # For the .38 special ammo and revolver + +- type: Tag + id: SpeedLoaderSpecial diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml index c97290fdaaa..ad71b3b2f41 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml @@ -79,6 +79,7 @@ tags: - HamsterWearable - WhitelistChameleon + - GlassesNearsight # SimpleStation14 NearsightedTrait - type: entity parent: ClothingEyesBase diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml index 80317fbaec0..9fba00a35ee 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml @@ -8,6 +8,15 @@ sprite: Clothing/Eyes/Hud/diag.rsi - type: Clothing sprite: Clothing/Eyes/Hud/diag.rsi +# - type: ClothingGrantComponent +# component: +# - type: ShowHealthBars +# damageContainers: +# - Inorganic + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - ClothingEyesHudDiagnostic - type: entity parent: ClothingEyesBase @@ -19,6 +28,16 @@ sprite: Clothing/Eyes/Hud/med.rsi - type: Clothing sprite: Clothing/Eyes/Hud/med.rsi +# - type: ClothingGrantComponent +# component: +# - type: ShowHealthBars +# damageContainers: +# - Biological +# - HalfSpirit + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - ClothingEyesHudMedical - type: entity parent: ClothingEyesBase diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index 30addb2f544..27e9f45c2e1 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -1,4 +1,5 @@ #When adding new hardsuits, please try to keep the organization consistent with hardsuit.yml (if possible.) + #For now, since locational damage is not a thing, all "combat" hardsuits (with the exception of the deathsquad hardsuit) have the equvilent of a helmet in terms of armor. This is so people don't need to wear both regular, on-station helmets and hardsuits to get full protection. #Generally, unless you're adding something like caustic damage, you should probably avoid messing with armor outside of the above scenario. @@ -326,7 +327,7 @@ id: ClothingHeadHelmetHardsuitSyndie noSpawn: true name: blood-red hardsuit helmet - description: An advanced red hardsuit helmet designed for work in special operations. + description: A heavily armored helmet designed for work in special operations. Property of Gorlex Marauders. components: - type: Sprite sprite: Clothing/Head/Hardsuits/syndicate.rsi @@ -345,20 +346,22 @@ Piercing: 0.9 Heat: 0.9 -#Cybersun Juggernaut Hardsuit +#Blood-red Medic Hardsuit - type: entity - parent: ClothingHeadHardsuitBase - id: ClothingHeadHelmetHardsuitCybersun + parent: ClothingHeadHardsuitWithLightBase + id: ClothingHeadHelmetHardsuitSyndieMedic noSpawn: true - name: cybersun juggernaut helmet - description: Made of compressed red matter, this helmet was designed in the Tau chromosphere facility. + name: blood-red medic hardsuit helmet + description: An advanced red hardsuit helmet specifically designed for field medic operations. components: - type: Sprite - sprite: Clothing/Head/Hardsuits/cybersun.rsi + sprite: Clothing/Head/Hardsuits/syndiemedic.rsi - type: Clothing - sprite: Clothing/Head/Hardsuits/cybersun.rsi + sprite: Clothing/Head/Hardsuits/syndiemedic.rsi + - type: PointLight + color: green - type: PressureProtection - highPressureMultiplier: 0.3 + highPressureMultiplier: 0.08 lowPressureMultiplier: 1000 - type: Armor modifiers: @@ -374,7 +377,7 @@ id: ClothingHeadHelmetHardsuitSyndieElite noSpawn: true name: syndicate elite helmet - description: A variant of the blood red helmet designed by the Gorlex Marauders to be exceptionally fireproof and pressure proof. + description: An elite version of the blood-red hardsuit's helmet, with improved armor and fireproofing. Property of Gorlex Marauders. components: - type: Sprite sprite: Clothing/Head/Hardsuits/syndieelite.rsi @@ -401,7 +404,7 @@ id: ClothingHeadHelmetHardsuitSyndieCommander noSpawn: true name: syndicate commander helmet - description: A syndicate hardsuit helmet custom designed for commanders of syndicate operative squads. + description: A bulked up version of the blood-red hardsuit's helmet, purpose-built for the commander of a syndicate operative squad. Has significantly improved armor for those deadly front-lines firefights. components: - type: Sprite sprite: Clothing/Head/Hardsuits/syndiecommander.rsi @@ -420,6 +423,29 @@ Piercing: 0.9 Heat: 0.9 +#Cybersun Juggernaut Hardsuit +- type: entity + parent: ClothingHeadHardsuitBase + id: ClothingHeadHelmetHardsuitCybersun + noSpawn: true + name: cybersun juggernaut helmet + description: Made of compressed red matter, this helmet was designed in the Tau chromosphere facility. + components: + - type: Sprite + sprite: Clothing/Head/Hardsuits/cybersun.rsi + - type: Clothing + sprite: Clothing/Head/Hardsuits/cybersun.rsi + - type: PressureProtection + highPressureMultiplier: 0.3 + lowPressureMultiplier: 1000 + - type: Armor + modifiers: + coefficients: + Blunt: 0.9 + Slash: 0.9 + Piercing: 0.9 + Heat: 0.9 + #Wizard Hardsuit - type: entity parent: ClothingHeadHardsuitWithLightBase diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index 70e6902e667..b29bc5104f6 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -373,6 +373,8 @@ sprite: Clothing/Head/Hats/sombrero.rsi - type: Clothing sprite: Clothing/Head/Hats/sombrero.rsi + - type: AddAccentClothing + accent: SpanishAccent - type: entity parent: ClothingHeadBase diff --git a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml index 83ba6603f8b..97fa8f59447 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml @@ -63,3 +63,14 @@ sprite: Clothing/Neck/mantles/rdmantle.rsi - type: Clothing sprite: Clothing/Neck/mantles/rdmantle.rsi + +- type: entity + parent: ClothingNeckBase + id: ClothingNeckMantleQM + name: head of logistics' mantle # DeltaV - Logistics Department replacing Cargo + description: For the master of goods and materials to rule over the department, a befitting mantle to show off superiority! + components: + - type: Sprite + sprite: Clothing/Neck/mantles/qmmantle.rsi + - type: Clothing + sprite: Clothing/Neck/mantles/qmmantle.rsi diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index c295bf88762..7ac6d0ba808 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -59,6 +59,11 @@ sprintModifier: 0.7 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitAtmos + - type: ReverseEngineering # Nyano + difficulty: 5 + newItem: ClothingOuterHardsuitJuggernautReverseEngineered + recipes: + - ClothingOuterHardsuitJuggernautReverseEngineered #Engineering Hardsuit - type: entity @@ -395,7 +400,7 @@ parent: ClothingOuterHardsuitBase id: ClothingOuterHardsuitLuxury #DO NOT MAP - https://github.com/space-wizards/space-station-14/pull/19738#issuecomment-1703486738 name: luxury mining hardsuit - description: A refurbished mining hardsuit, fashioned after the Quartermaster's colors. Graphene lining provides less protection, but is much easier to move. + description: A refurbished mining hardsuit, fashioned after the Head of Logistics' colors. Graphene lining provides less protection, but is much easier to move. # DeltaV - Logistics Department replacing Cargo components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/luxury.rsi @@ -426,7 +431,7 @@ parent: ClothingOuterHardsuitBase id: ClothingOuterHardsuitSyndie name: blood-red hardsuit - description: A heavily armored and agile advanced hardsuit designed for work in special operations. + description: A heavily armored hardsuit designed for work in special operations. Property of Gorlex Marauders. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/syndicate.rsi @@ -451,44 +456,32 @@ sprintModifier: 0.9 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndie + - type: ReverseEngineering # Nyano + difficulty: 5 + newItem: ClothingOuterHardsuitSyndieReverseEngineered + recipes: + - ClothingOuterHardsuitSyndieReverseEngineered -#Cybersun Juggernaut Hardsuit +# Syndicate Medic Hardsuit - type: entity - parent: ClothingOuterHardsuitBase - id: ClothingOuterHardsuitJuggernaut - name: cybersun juggernaut suit - description: A suit made by the cutting edge R&D department at cybersun to be hyper resilient. + parent: ClothingOuterHardsuitSyndie + id: ClothingOuterHardsuitMedic + name: blood-red medic hardsuit + description: A heavily armored and agile advanced hardsuit specifically designed for field medic operations. components: - type: Sprite - sprite: Clothing/OuterClothing/Hardsuits/cybersun.rsi + sprite: Clothing/OuterClothing/Hardsuits/syndiemedic.rsi - type: Clothing - sprite: Clothing/OuterClothing/Hardsuits/cybersun.rsi - - type: PressureProtection - highPressureMultiplier: 0.2 - lowPressureMultiplier: 1000 - - type: ExplosionResistance - damageCoefficient: 0.3 - - type: Armor - modifiers: - coefficients: - Blunt: 0.2 - Slash: 0.2 - Piercing: 0.2 - Heat: 0.2 - Radiation: 0.2 - Caustic: 0.2 - - type: ClothingSpeedModifier - walkModifier: 0.9 - sprintModifier: 0.65 + sprite: Clothing/OuterClothing/Hardsuits/syndiemedic.rsi - type: ToggleableClothing - clothingPrototype: ClothingHeadHelmetHardsuitCybersun + clothingPrototype: ClothingHeadHelmetHardsuitSyndieMedic #Syndicate Elite Hardsuit - type: entity parent: ClothingOuterHardsuitBase id: ClothingOuterHardsuitSyndieElite name: syndicate elite hardsuit - description: An upgraded version of the blood red hardsuit that features enhanced fireproofing, pressure resist, and superior armor. + description: An elite version of the blood-red hardsuit, with improved armor and fireproofing. Property of Gorlex Marauders. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/syndieelite.rsi @@ -521,7 +514,7 @@ parent: ClothingOuterHardsuitBase id: ClothingOuterHardsuitSyndieCommander name: syndicate commander hardsuit - description: A blood red hardsuit heavily modified for use by the commander of operative squads. + description: A bulked up version of the blood-red hardsuit, purpose-built for the commander of a syndicate operative squad. Has significantly improved armor for those deadly front-lines firefights. components: - type: Sprite sprite: Clothing/OuterClothing/Hardsuits/syndiecommander.rsi @@ -547,6 +540,37 @@ - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieCommander +#Cybersun Juggernaut Hardsuit +- type: entity + parent: ClothingOuterHardsuitBase + id: ClothingOuterHardsuitJuggernaut + name: cybersun juggernaut suit + description: A suit made by the cutting edge R&D department at cybersun to be hyper resilient. + components: + - type: Sprite + sprite: Clothing/OuterClothing/Hardsuits/cybersun.rsi + - type: Clothing + sprite: Clothing/OuterClothing/Hardsuits/cybersun.rsi + - type: PressureProtection + highPressureMultiplier: 0.2 + lowPressureMultiplier: 1000 + - type: ExplosionResistance + damageCoefficient: 0.3 + - type: Armor + modifiers: + coefficients: + Blunt: 0.2 + Slash: 0.2 + Piercing: 0.2 + Heat: 0.2 + Radiation: 0.2 + Caustic: 0.2 + - type: ClothingSpeedModifier + walkModifier: 0.9 + sprintModifier: 0.65 + - type: ToggleableClothing + clothingPrototype: ClothingHeadHelmetHardsuitCybersun + #Wizard Hardsuit - type: entity parent: ClothingOuterHardsuitBase diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml index c19560ab1e4..e0de6c7d83e 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml @@ -114,6 +114,8 @@ sprite: Clothing/OuterClothing/Misc/classicponcho.rsi - type: Clothing sprite: Clothing/OuterClothing/Misc/classicponcho.rsi + - type: AddAccentClothing + accent: SpanishAccent - type: entity parent: ClothingOuterBase @@ -147,6 +149,8 @@ sprite: Clothing/OuterClothing/Misc/poncho.rsi - type: Clothing sprite: Clothing/OuterClothing/Misc/poncho.rsi + - type: AddAccentClothing + accent: SpanishAccent - type: entity parent: ClothingOuterBase diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml index fcd21def8af..b75a2a712ec 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/boots.yml @@ -91,3 +91,16 @@ sprite: Clothing/Shoes/Boots/laceups.rsi - type: Clothing sprite: Clothing/Shoes/Boots/laceups.rsi + +- type: entity + parent: ClothingShoesBaseButcherable + id: ClothingShoesBootsWinter + name: winter boots + description: Fluffy boots to help survive even the coldest of winters. + components: + - type: Sprite + sprite: Clothing/Shoes/Boots/winterboots.rsi + - type: Clothing + sprite: Clothing/Shoes/Boots/winterboots.rsi + - type: TemperatureProtection + coefficient: 0.05 diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index 0a603bc509b..da08036fb05 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -48,6 +48,10 @@ sprite: Clothing/Uniforms/Jumpsuit/punpun.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/punpun.rsi + - type: SuitSensor + controlsLocked: false + randomMode: false + mode: SensorCords - type: entity parent: ClothingUniformBase diff --git a/Resources/Prototypes/Entities/Debugging/spanisharmyknife.yml b/Resources/Prototypes/Entities/Debugging/spanisharmyknife.yml index 66e2b35ad81..94464f2535d 100644 --- a/Resources/Prototypes/Entities/Debugging/spanisharmyknife.yml +++ b/Resources/Prototypes/Entities/Debugging/spanisharmyknife.yml @@ -24,6 +24,7 @@ - type: Tool qualities: - Prying + - type: Prying - type: MultipleTool statusShowBehavior: true entries: diff --git a/Resources/Prototypes/Entities/Mobs/Corpses/corpses.yml b/Resources/Prototypes/Entities/Mobs/Corpses/corpses.yml index 39815bcdbb9..498f1892bc3 100644 --- a/Resources/Prototypes/Entities/Mobs/Corpses/corpses.yml +++ b/Resources/Prototypes/Entities/Mobs/Corpses/corpses.yml @@ -61,6 +61,7 @@ - ResearchAssistantGear - ScientistGear - ChaplainGear # DeltaV - Move Chaplain into Epistemics + - ForensicMantisGear # Nyanotrasen - Forensic Mantis - type: entity parent: SalvageHumanCorpse diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml index 60e7f346493..72da7b1d2a5 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml @@ -255,7 +255,7 @@ state: horns_myrsore - type: marking - id: LizardBighorn + id: LizardHornsBighorn bodyPart: HeadTop markingCategory: HeadTop speciesRestriction: [Reptilian] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 170d5e242ba..a76b68aced3 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -2108,6 +2108,8 @@ interactFailureString: petting-failure-generic interactSuccessSound: path: /Audio/Animals/cat_meow.ogg + - type: Respirator #It just works? + minSaturation: 5.0 - type: entity name: caracal cat diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index bb46955dcb6..1efa767af1b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -97,6 +97,7 @@ task: SimpleHostileCompound - type: Grammar attributes: + proper: true gender: female - type: Tag tags: @@ -114,6 +115,7 @@ - PetsNT - type: Grammar attributes: + proper: true gender: male - type: Tag tags: @@ -153,6 +155,7 @@ components: - type: Grammar attributes: + proper: true gender: male - type: Tag tags: @@ -160,7 +163,7 @@ - VimPilot - type: entity - name: bingus + name: Bingus parent: SimpleMobBase id: MobBingus description: Bingus my beloved... @@ -206,12 +209,13 @@ amount: 2 - type: InteractionPopup successChance: 0.9 - interactSuccessString: petting-success-cat + interactSuccessString: petting-success-bingus interactFailureString: petting-failure-generic interactSuccessSound: path: /Audio/Animals/cat_meow.ogg - type: Grammar attributes: + proper: true gender: epicene - type: Tag tags: @@ -219,7 +223,7 @@ - VimPilot - type: entity - name: mcgriff + name: McGriff parent: SimpleMobBase id: MobMcGriff description: This dog can tell something smells around here, and that something is CRIME! @@ -431,6 +435,7 @@ path: /Audio/Animals/pig_oink.ogg - type: Grammar attributes: + proper: true gender: male - type: Tag tags: @@ -614,8 +619,6 @@ description: This masterpiece has gone through thousands of experiments. But it is the sweetest creature in the world. Smile Slime! components: - type: Sprite - drawdepth: Mobs - sprite: Mobs/Aliens/slimes.rsi layers: - map: [ "enum.DamageStateVisualLayers.Base" ] state: rainbow_baby_slime @@ -645,22 +648,14 @@ Dead: Base: rainbow_baby_slime_dead - type: Butcherable - butcheringType: Knife spawned: - id: FoodMeatSlime amount: 1 - id: MaterialSmileExtract amount: 1 - type: Damageable - damageContainer: Biological damageModifierSet: SlimePet - type: Bloodstream - bloodMaxVolume: 150 - bloodReagent: Slime - bloodlossDamage: - types: - Bloodloss: - 1 bloodlossHealDamage: types: Bloodloss: @@ -669,11 +664,6 @@ heatDamageThreshold: 800 coldDamageThreshold: 0 - type: MeleeWeapon - hidden: true - soundHit: - path: /Audio/Weapons/punch3.ogg - angle: 0 - animation: WeaponArcPunch damage: types: Blunt: 1 @@ -683,9 +673,12 @@ - type: MobPrice price: 3000 # it is a truly valuable creature - type: GhostRole - makeSentient: true name: ghost-role-information-smile-name description: ghost-role-information-smile-description + - type: Grammar + attributes: + proper: true + gender: female - type: entity name: Pun Pun @@ -715,3 +708,7 @@ - VimPilot - type: Loadout prototypes: [ MobMonkeyGear ] + - type: Grammar + attributes: + proper: true + gender: male diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 120389304b4..69e20a51da9 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -112,6 +112,9 @@ - type: GuideHelp guides: - MinorAntagonists + - type: Grammar + attributes: + gender: male - type: entity id: MobRatKingBuff diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index 85a0b2afa44..4d56face9d1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -94,6 +94,9 @@ type: Local messages: [ "slime-hurt-by-water-popup" ] probability: 0.25 + - type: Body + prototype: Slimes + requiredLegs: 1 - type: CombatMode - type: MeleeWeapon hidden: true diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 1c81d57e69e..9831d20e27a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -25,6 +25,11 @@ speed: 1.5 qualities: - Prying + - type: Prying + pryPowered: !type:Bool + true + force: !type:Bool + true useSound: path: /Audio/Items/crowbar.ogg - type: Reactive @@ -305,6 +310,11 @@ drawdepth: Mobs sprite: Mobs/Aliens/Xenos/rouny.rsi offset: 0,0.6 + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatRouny + amount: 3 - type: entity name: Spitter diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index 398d1010217..368d1846925 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -133,6 +133,8 @@ spawnsLeft: 2 spawnsProto: MobCarpDragon spawnRiftAction: ActionSpawnRift + - type: GenericAntag + rule: Dragon - type: GuideHelp guides: - MinorAntagonists diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 985be544e5f..59990a3f7b4 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -61,6 +61,8 @@ parent: MobHuman id: MobHumanSpaceNinja components: + - type: RandomHumanoidAppearance + randomizeName: false - type: Loadout prototypes: [SpaceNinjaGear] - type: NpcFactionMember diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 9e362c88395..d00f93fb764 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -200,6 +200,7 @@ - type: Puller - type: Speech speechSounds: Alto + - type: DamageForceSay - type: Vocal sounds: Male: MaleHuman diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml index 4384542bb0d..eb05133a38e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/bowl.yml @@ -21,18 +21,12 @@ damage: types: Blunt: 5 - - type: Drink - solution: food - - type: DrawableSolution - solution: food - - type: Damageable - damageContainer: Inorganic - type: SolutionTransfer canChangeTransferAmount: true - type: UserInterface interfaces: - - key: enum.TransferAmountUiKey.Key - type: TransferAmountBoundUserInterface + - key: enum.TransferAmountUiKey.Key + type: TransferAmountBoundUserInterface - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index 05cae79b166..e2ce3dfaa86 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -1,7 +1,7 @@ # Base - type: entity - parent: FoodInjectableBase + parent: [FoodInjectableBase, ItemHeftyBase] id: FoodEggBase description: An egg! abstract: true @@ -28,15 +28,7 @@ ignoreEmpty: true popup: spike-solution-egg - type: DeleteOnTrigger - - type: DamageOnLand - damage: - types: - Blunt: 1 - - type: DamageOtherOnHit - damage: - types: - Blunt: 1 - #Dignity: 25 + # egg fragile - type: DamageOnHighSpeedImpact minimumSpeed: 0.1 damage: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml index 9c9890084cf..c3b3bba35ba 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/ingredients.yml @@ -5,9 +5,9 @@ # Reagent Containers - type: entity + abstract: true parent: BaseItem id: ReagentContainerBase - abstract: true components: - type: Sprite sprite: Objects/Consumable/Food/ingredients.rsi @@ -18,6 +18,8 @@ - type: SolutionTransfer # This is potentially badly-handled due to 'drink opening', # but it lets the flour be tampered with, refilled, etc. + - type: DrawableSolution + solution: food - type: RefillableSolution solution: food - type: DrainableSolution @@ -26,22 +28,58 @@ solution: food useSound: path: /Audio/Items/eating_1.ogg + - type: Damageable + damageContainer: Inorganic + - type: Spillable + solution: food + - type: TrashOnEmpty + solution: food + +- type: entity + abstract: true + parent: ReagentContainerBase + id: ReagentPacketBase + components: - type: Openable sound: collection: packetOpenSounds - - type: Spillable - solution: food + # packet can be broken open + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 2 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: desecration + - !type:SpillBehavior + solution: food + - !type:DoActsBehavior + acts: [ "Destruction" ] + # packet contents can be splashed when open - type: MeleeWeapon soundNoDamage: path: "/Audio/Effects/Fluids/splat.ogg" damage: types: Blunt: 0 - - type: TrashOnEmpty - solution: food - type: entity - parent: ReagentContainerBase + abstract: true + id: ItemHeftyBase + components: + - type: DamageOnLand + damage: + types: + Blunt: 1 + - type: DamageOtherOnHit + damage: + types: + Blunt: 1 + +- type: entity + parent: [ReagentPacketBase, ItemHeftyBase] id: ReagentContainerFlour name: flour bag description: A big bag of flour. Good for baking! @@ -55,34 +93,9 @@ reagents: - ReagentId: Flour Quantity: 50 - - type: DamageOnLand - damage: - types: - Blunt: 1 - - type: DamageOtherOnHit - damage: - types: - Blunt: 1 - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 2 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: desecration - - !type:SpillBehavior - solution: food - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: TrashOnEmpty - solution: food - type: entity - parent: ReagentContainerBase + parent: [ReagentPacketBase, ItemHeftyBase] id: ReagentContainerFlourSmall name: flour pack description: A pack of flour. Good for baking! @@ -96,32 +109,9 @@ reagents: - ReagentId: Flour Quantity: 20 - - type: DamageOnLand - damage: - types: - Blunt: 1 - - type: DamageOtherOnHit - damage: - types: - Blunt: 1 - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 2 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: desecration - - !type:SpillBehavior - solution: food - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerCornmeal name: cornmeal bag description: A big bag of cornmeal. Good for cooking! @@ -136,7 +126,7 @@ Quantity: 50 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerCornmealSmall name: cornmeal pack description: A pack of cornmeal. Good for cooking! @@ -152,7 +142,7 @@ Quantity: 20 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerRice name: rice bag description: A big bag of rice. Good for cooking! @@ -167,7 +157,7 @@ Quantity: 50 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerRiceSmall name: rice pack description: A pack of rice. Good for cooking! @@ -183,7 +173,7 @@ Quantity: 20 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerSugar name: sugar bag description: A big bag of tasty spacey sugar. @@ -198,7 +188,7 @@ Quantity: 50 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerSugarSmall name: sugar pack description: A pack of tasty spacey sugar. @@ -216,7 +206,7 @@ # Milk - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerMilk name: milk description: It's milk. White and nutritious goodness! @@ -232,7 +222,7 @@ Quantity: 50 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerMilkSoy name: soy milk description: It's soy milk. White and nutritious goodness! @@ -248,7 +238,7 @@ Quantity: 50 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerMilkOat name: oat milk description: It's oat milk. Tan and nutritious goodness! @@ -266,7 +256,7 @@ # Misc - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerOliveoil name: olive oil description: Olive oil. From space olives presumably. @@ -282,7 +272,7 @@ Quantity: 20 - type: entity - parent: ReagentContainerBase + parent: ReagentPacketBase id: ReagentContainerMayo name: mayonnaise description: Bottle of mayonnaise. @@ -298,7 +288,7 @@ Quantity: 20 # - type: entity -# parent: ReagentContainerBase +# parent: ReagentPacketBase # id: ReagentContainerAllspice # name: all-spice # description: @@ -316,13 +306,12 @@ - type: entity abstract: true - parent: BaseItem + parent: FoodBase id: FoodBakingBase description: Used in various recipes. components: - type: Sprite sprite: Objects/Consumable/Food/ingredients.rsi - - type: Food - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml index 44f2b668e4d..1c003df38e6 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml @@ -494,6 +494,34 @@ count: 3 slice: FoodMeatXenoCutlet +- type: entity + name: raw rouny meat + # not raw since rouny best + parent: FoodMeatBase + id: FoodMeatRouny + description: A slab of meat from an innocent red friend. + components: + - type: FlavorProfile + flavors: + - meaty + - acid + - lostfriendship + - type: Tag + tags: + - Raw + - type: Sprite + state: rouny + - type: SolutionContainerManager + solutions: + food: + reagents: + - ReagentId: SulfuricAcid + Quantity: 20 + - type: Construction + graph: RounySteak + node: start + defaultTarget: rouny steak + - type: entity name: killer tomato meat parent: FoodMeatBase @@ -848,6 +876,34 @@ graph: GoliathSteak node: goliath steak +- type: entity + name: rouny steak + parent: FoodMeatBase + id: FoodMeatRounyCooked + description: Some kill to survive. You on the other hand, kill for fun. + components: + - type: FlavorProfile + flavors: + - meaty + - lostfriendship + - type: Tag + tags: + - Cooked + - type: Sprite + layers: + - state: rouny-cooked + - type: SolutionContainerManager + solutions: + food: + reagents: + - ReagentId: Nutriment + Quantity: 10 + - ReagentId: Protein + Quantity: 10 + - type: Construction + graph: RounySteak + node: rouny steak + - type: entity name: lizard steak parent: FoodMeatBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 4a5aa42130d..1e3d42b26b7 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -548,7 +548,7 @@ - type: entity name: tomato - parent: FoodProduceBase + parent: [FoodProduceBase, ItemHeftyBase] id: FoodTomato description: I say to-mah-to, you say tom-mae-to. components: @@ -576,15 +576,6 @@ reagents: - ReagentId: JuiceTomato Quantity: 10 - - type: DamageOnLand - damage: - types: - Blunt: 1 - - type: DamageOtherOnHit - damage: - types: - Blunt: 1 - #Dignity: 25 - type: Damageable damageContainer: Biological - type: DamageOnHighSpeedImpact @@ -1329,7 +1320,7 @@ - type: entity name: watermelon - parent: FoodProduceBase + parent: [FoodProduceBase, ItemHeftyBase] id: FoodWatermelon description: Round green object that you can slice and eat. components: @@ -1358,14 +1349,6 @@ reagents: - ReagentId: JuiceWatermelon Quantity: 20 - - type: DamageOnLand - damage: - types: - Blunt: 1 - - type: DamageOtherOnHit - damage: - types: - Blunt: 1 - type: Damageable damageContainer: Biological - type: DamageOnHighSpeedImpact @@ -1531,4 +1514,4 @@ - type: Seed seedId: bungo - type: SpaceGarbage - - type: BadFood \ No newline at end of file + - type: BadFood diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Vapes/vape.yml b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Vapes/vape.yml index 06009b4d2fe..374a396a5a6 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Vapes/vape.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Smokeables/Vapes/vape.yml @@ -1,9 +1,10 @@ - type: entity id: Vape + noSpawn: true # DeltaV - Disable the Vape parent: BaseVape name: vape description: "Like a cigar, but for tough teens. (WARNING:Pour only water into the vape)" components: - type: Sprite sprite: Objects/Consumable/Smokeables/Vapes/vape-standart.rsi - state: icon \ No newline at end of file + state: icon diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 9ecd8c36f12..d06469c6c89 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -98,6 +98,10 @@ Amount: 2 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - CircuitImprinterMachineCircuitboard - type: entity id: ExosuitFabricatorMachineCircuitboard @@ -113,6 +117,10 @@ Manipulator: 3 materialRequirements: Glass: 5 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - ExosuitFabricatorMachineCircuitboard - type: GuideHelp guides: - Robotics @@ -141,6 +149,10 @@ requirements: MatterBin: 1 Manipulator: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - UniformPrinterMachineCircuitboard - type: entity id: VaccinatorMachineCircuitboard @@ -161,6 +173,10 @@ Amount: 1 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - VaccinatorMachineCircuitboard - type: entity id: DiagnoserMachineCircuitboard @@ -183,6 +199,10 @@ Amount: 1 DefaultPrototype: DiseaseSwab ExamineName: Swab + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - DiagnoserMachineCircuitboard - type: entity id: ArtifactAnalyzerMachineCircuitboard @@ -199,6 +219,10 @@ Capacitor: 1 materialRequirements: Glass: 5 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - ArtifactAnalyzerMachineCircuitboard - type: entity id: TraversalDistorterMachineCircuitboard @@ -216,6 +240,10 @@ materialRequirements: Steel: 5 Cable: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - TraversalDistorterMachineCircuitboard - type: entity parent: BaseMachineCircuitboard @@ -232,6 +260,10 @@ materialRequirements: Cable: 1 PlasmaGlass: 10 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - AnomalyVesselCircuitboard - type: entity parent: BaseMachineCircuitboard @@ -248,6 +280,10 @@ materialRequirements: Cable: 1 Glass: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - APECircuitboard - type: entity id: ThermomachineFreezerMachineCircuitBoard @@ -268,6 +304,10 @@ deconstructionTarget: null graph: ThermomachineBoard node: freezer + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - ThermomachineFreezerMachineCircuitBoard - type: entity id: ThermomachineHeaterMachineCircuitBoard @@ -305,6 +345,9 @@ materialRequirements: Cable: 5 Glass: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: - type: entity id: CloningPodMachineCircuitboard @@ -322,6 +365,10 @@ materialRequirements: Glass: 1 Cable: 1 + - type: ReverseEngineering # Nyano + difficulty: 4 + recipes: + - CloningPodMachineCircuitboard - type: entity id: MedicalScannerMachineCircuitboard @@ -338,6 +385,10 @@ materialRequirements: Glass: 5 Cable: 1 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - MedicalScannerMachineCircuitboard - type: entity id: CrewMonitoringServerMachineCircuitboard @@ -364,6 +415,10 @@ materialRequirements: Glass: 5 Cable: 1 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - CryoPodMachineCircuitboard - type: entity id: ChemMasterMachineCircuitboard @@ -385,6 +440,10 @@ Amount: 2 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - ChemMasterMachineCircuitboard - type: entity id: ChemDispenserMachineCircuitboard @@ -406,6 +465,10 @@ Amount: 2 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - ChemDispenserMachineCircuitboard - type: entity id: BiomassReclaimerMachineCircuitboard @@ -425,6 +488,10 @@ ExamineName: Knife materialRequirements: Steel: 5 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - BiomassReclaimerMachineCircuitboard - type: entity id: HydroponicsTrayMachineCircuitboard @@ -445,6 +512,10 @@ Amount: 2 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - HydroponicsTrayMachineCircuitboard - type: entity id: SeedExtractorMachineCircuitboard @@ -463,6 +534,10 @@ # replacing the console screen Glass: 1 Cable: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SeedExtractorMachineCircuitboard - type: entity id: SMESMachineCircuitboard @@ -477,6 +552,9 @@ prototype: SMESBasicEmpty requirements: Capacitor: 5 + - type: ReverseEngineering # Nyano + recipes: + - SMESMachineCircuitboard - type: entity id: CellRechargerCircuitboard @@ -557,6 +635,9 @@ materialRequirements: CableMV: 5 CableHV: 5 + - type: ReverseEngineering # Nyano + recipes: + - SubstationMachineCircuitboard - type: PhysicalComposition materialComposition: Glass: 200 @@ -597,6 +678,10 @@ Amount: 1 DefaultPrototype: SaxophoneInstrument ExamineName: Woodwind Instrument + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - DawInstrumentMachineCircuitboard - type: entity id: PortableGeneratorPacmanMachineCircuitboard @@ -611,6 +696,10 @@ Capacitor: 1 materialRequirements: CableHV: 5 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - GeneratorPlasmaMachineCircuitboard - type: PhysicalComposition materialComposition: Glass: 200 @@ -660,6 +749,10 @@ Glass: 200 chemicalComposition: Silicon: 20 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - PortableGeneratorSuperPacmanMachineCircuitboard - type: entity id: PortableGeneratorJrPacmanMachineCircuitboard @@ -696,6 +789,10 @@ Amount: 1 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - ReagentGrinderMachineCircuitboard - type: entity id: HotplateMachineCircuitboard @@ -709,6 +806,10 @@ Capacitor: 2 materialRequirements: Glass: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - HotplateMachineCircuitboard - type: entity id: StasisBedMachineCircuitboard @@ -732,6 +833,10 @@ Amount: 2 DefaultPrototype: CryostasisBeaker ExamineName: Cryostasis Beaker + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - StasisBedMachineCircuitboard - type: entity id: MaterialReclaimerMachineCircuitboard @@ -762,6 +867,9 @@ Manipulator: 3 materialRequirements: Glass: 1 + - type: ReverseEngineering # Nyano + recipes: + - OreProcessorMachineCircuitboard - type: entity id: SheetifierMachineCircuitboard @@ -788,6 +896,9 @@ materialRequirements: Glass: 2 Cable: 2 + - type: ReverseEngineering # Nyano + recipes: + - MicrowaveMachineCircuitboard - type: entity id: FatExtractorMachineCircuitboard @@ -820,6 +931,10 @@ materialRequirements: CableHV: 5 Glass: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - EmitterCircuitboard - type: entity id: SurveillanceCameraRouterCircuitboard @@ -831,6 +946,10 @@ prototype: SurveillanceCameraRouterConstructed materialRequirements: Cable: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SurveillanceCameraRouterCircuitboard - type: entity id: SurveillanceCameraWirelessRouterCircuitboard @@ -843,6 +962,10 @@ materialRequirements: Cable: 2 Glass: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SurveillanceCameraWirelessRouterCircuitboard - type: entity id: SurveillanceWirelessCameraMovableCircuitboard @@ -855,6 +978,10 @@ materialRequirements: Glass: 2 Cable: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SurveillanceWirelessCameraMovableCircuitboard - type: entity id: SurveillanceWirelessCameraAnchoredCircuitboard @@ -867,6 +994,10 @@ materialRequirements: Cable: 2 Glass: 1 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SurveillanceWirelessCameraAnchoredCircuitboard - type: entity id: GasRecyclerMachineCircuitboard @@ -882,6 +1013,10 @@ materialRequirements: Steel: 10 Plasma: 5 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - GasRecyclerMachineCircuitboard - type: entity id: BoozeDispenserMachineCircuitboard @@ -900,6 +1035,9 @@ Amount: 1 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + recipes: + - BoozeDispenserMachineCircuitboard - type: entity id: CargoTelepadMachineCircuitboard @@ -933,6 +1071,9 @@ Amount: 1 DefaultPrototype: Beaker ExamineName: Glass Beaker + - type: ReverseEngineering # Nyano + recipes: + - SodaDispenserMachineCircuitboard - type: entity id: TelecomServerCircuitboard @@ -945,6 +1086,9 @@ materialRequirements: Steel: 1 Cable: 2 + - type: ReverseEngineering # Nyano + recipes: + - TelecomServerCircuitboard - type: entity parent: BaseMachineCircuitboard @@ -960,6 +1104,9 @@ Steel: 5 CableHV: 5 Cable: 2 + - type: ReverseEngineering # Nyano + recipes: + - SalvageMagnetMachineCircuitboard - type: entity parent: BaseMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml index 13967b9df59..247e503eb47 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml @@ -38,6 +38,9 @@ state: cpu_engineering - type: ComputerBoard prototype: ComputerPowerMonitoring + - type: ReverseEngineering # Nyano + recipes: + - PowerComputerCircuitboard - type: entity parent: BaseComputerCircuitboard @@ -199,6 +202,10 @@ state: cpu_science - type: ComputerBoard prototype: ComputerAnalysisConsole + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - AnalysisComputerCircuitboard - type: entity parent: BaseComputerCircuitboard @@ -210,6 +217,10 @@ state: cpu_science - type: ComputerBoard prototype: ComputerTechnologyDiskTerminal + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - TechDiskComputerCircuitboard - type: entity parent: BaseComputerCircuitboard @@ -219,6 +230,10 @@ components: - type: ComputerBoard prototype: ComputerCrewMonitoring + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - CrewMonitoringComputerCircuitboard - type: entity parent: BaseComputerCircuitboard @@ -286,6 +301,10 @@ state: cpu_engineering - type: ComputerBoard prototype: ComputerSolarControl + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - SolarControlComputerCircuitboard - type: entity parent: BaseComputerCircuitboard @@ -344,6 +363,10 @@ state: cpu_medical - type: ComputerBoard prototype: ComputerCloningConsole + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - CloningConsoleComputerCircuitboard - type: entity parent: BaseComputerCircuitboard diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/atmos_alarms.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/atmos_alarms.yml index b42ee2499c6..37f56f4ca3c 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/atmos_alarms.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/atmos_alarms.yml @@ -11,6 +11,9 @@ tags: - DroneUsable - AirAlarmElectronics + - type: ReverseEngineering # Nyano + recipes: + - AirAlarmElectronics - type: StaticPrice price: 61 @@ -27,5 +30,8 @@ tags: - DroneUsable - FireAlarmElectronics + - type: ReverseEngineering # Nyano + recipes: + - FireAlarmElectronics - type: StaticPrice price: 61 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/disposal.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/disposal.yml index 9278e347066..bfc00dcbf8d 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/disposal.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/disposal.yml @@ -11,5 +11,8 @@ tags: - DroneUsable - MailingUnitElectronics + - type: ReverseEngineering # Nyano + recipes: + - MailingUnitElectronics - type: StaticPrice price: 55 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml index 627fe5fb0a0..a444afe3a48 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml @@ -12,5 +12,8 @@ tags: - DoorElectronics - DroneUsable + - type: ReverseEngineering # Nyano + recipes: + - DoorElectronics - type: StaticPrice price: 55 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/firelock.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/firelock.yml index 3dee4037b34..3a8c6f3e025 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/firelock.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/firelock.yml @@ -11,5 +11,8 @@ tags: - DroneUsable - FirelockElectronics + - type: ReverseEngineering # Nyano + recipes: + - FirelockElectronics - type: StaticPrice price: 61 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/intercom.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/intercom.yml index b59654cf02d..2a77d228a8f 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/intercom.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/intercom.yml @@ -11,5 +11,8 @@ tags: - DroneUsable - IntercomElectronics + - type: ReverseEngineering # Nyano + recipes: + - IntercomElectronics - type: StaticPrice price: 55 diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/power_electronics.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/power_electronics.yml index 80c728aca73..46d36a6fb1f 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/power_electronics.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/power_electronics.yml @@ -9,6 +9,9 @@ - type: Sprite sprite: Objects/Misc/module.rsi state: charger_APC + - type: ReverseEngineering # Nyano + recipes: + - APCElectronics - type: PhysicalComposition materialComposition: Glass: 50 diff --git a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml index 984753edcb3..e960c8316e8 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml @@ -213,6 +213,10 @@ layers: - state: crypt_red - state: synd_label + - type: ReverseEngineering # Nyano + difficulty: 5 + recipes: + - EncryptionKeySyndie - type: entity parent: EncryptionKey diff --git a/Resources/Prototypes/Entities/Objects/Devices/hand_teleporter.yml b/Resources/Prototypes/Entities/Objects/Devices/hand_teleporter.yml index 0acd4fbf19f..53779173553 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/hand_teleporter.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/hand_teleporter.yml @@ -9,6 +9,10 @@ layers: - state: icon - type: HandTeleporter + - type: ReverseEngineering # Nyano + difficulty: 4 + recipes: + - HandTeleporter - type: Tag tags: - HighRiskItem diff --git a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml index e1137d7b8ce..ee04ac6a062 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml @@ -42,6 +42,9 @@ - HolofanProjector - type: StaticPrice price: 80 + - type: ReverseEngineering # Nyano + recipes: + - HolofanProjector - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index df2cb002982..ee34ce87163 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -294,6 +294,19 @@ - type: PresetIdCard job: Bartender +- type: entity + parent: IDCardStandard + id: PunPunIDCard + name: pun pun ID card + components: + - type: Sprite + layers: + - state: default + - state: idbartender + - type: PresetIdCard + job: Bartender + name: Pun Pun + - type: entity parent: IDCardStandard id: ChefIDCard @@ -567,6 +580,7 @@ - JobIconMailCarrier # Nyanotrasen - MailCarrier, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Cargo/mail-carrier.yml - JobIconMartialArtist # Nyanotrasen - MartialArtist, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/martialartist.yml - JobIconGladiator # Nyanotrasen - Gladiator, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/gladiator.yml + - JobIconForensicMantis # Nyanotrasen - ForensicMantis, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml - type: ActivatableUI key: enum.AgentIDCardUiKey.Key inHandsOnly: true diff --git a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml index be1f4f65eea..cd065770213 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/machine_parts.yml @@ -27,6 +27,9 @@ - type: MachinePart part: Capacitor rating: 1 + - type: ReverseEngineering # Nyano + recipes: + - CapacitorStockPart - type: Tag tags: - CapacitorStockPart @@ -43,6 +46,9 @@ - type: MachinePart part: Manipulator rating: 1 + - type: ReverseEngineering # Nyano + recipes: + - MicroManipulatorStockPart - type: entity id: MatterBinStockPart @@ -56,6 +62,9 @@ - type: MachinePart part: MatterBin rating: 1 + - type: ReverseEngineering # Nyano + recipes: + - MatterBinStockPart # Rating 2 @@ -70,6 +79,10 @@ state: adv_capacitor - type: MachinePart rating: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - AdvancedCapacitorStockPart - type: entity id: NanoManipulatorStockPart @@ -82,6 +95,10 @@ state: nano_mani - type: MachinePart rating: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - NanoManipulatorStockPart - type: entity id: AdvancedMatterBinStockPart @@ -94,6 +111,10 @@ state: advanced_matter_bin - type: MachinePart rating: 2 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - AdvancedMatterBinStockPart # Rating 3 @@ -108,6 +129,10 @@ state: super_capacitor - type: MachinePart rating: 3 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - SuperCapacitorStockPart - type: entity id: PicoManipulatorStockPart @@ -120,6 +145,10 @@ state: pico_mani - type: MachinePart rating: 3 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - PicoManipulatorStockPart - type: entity id: SuperMatterBinStockPart @@ -132,6 +161,10 @@ state: super_matter_bin - type: MachinePart rating: 3 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - SuperMatterBinStockPart # Rating 4 @@ -146,6 +179,10 @@ state: quadratic_capacitor - type: MachinePart rating: 4 + - type: ReverseEngineering # Nyano + difficulty: 4 + recipes: + - QuadraticCapacitorStockPart - type: entity id: FemtoManipulatorStockPart @@ -158,6 +195,10 @@ state: femto_mani - type: MachinePart rating: 4 + - type: ReverseEngineering # Nyano + difficulty: 4 + recipes: + - FemtoManipulatorStockPart - type: entity id: BluespaceMatterBinStockPart @@ -170,6 +211,10 @@ state: bluespace_matter_bin - type: MachinePart rating: 4 + - type: ReverseEngineering # Nyano + difficulty: 4 + recipes: + - BluespaceMatterBinStockPart # Subspace stock parts (REMOVE THESE) diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index ea5935957df..8afe40bfe72 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -424,7 +424,6 @@ - state: teleriot-icon - state: teleriot-on visible: false - shader: unshaded map: [ "shield" ] - type: Item size: 10 @@ -437,10 +436,8 @@ inhandVisuals: left: - state: inhand-left-shield - shader: unshaded right: - state: inhand-right-shield - shader: unshaded - type: Appearance - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index 13bd6d16650..3ae89e0d1c0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -196,33 +196,30 @@ - type: entity name: wet floor sign id: WetFloorSign - parent: BaseItem + parent: ClothingOuterBase description: Caution! Wet Floor! components: - type: Sprite sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - state: caution - type: Item sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi size: 15 + - type: Armor + modifiers: + coefficients: + Blunt: 0.95 + Slash: 0.95 - type: Tag tags: - WetFloorSign + - WhitelistChameleon - type: entity - name: wet floor sign suffix: Explosive - description: Caution! Wet Floor! - parent: BaseItem + parent: WetFloorSign id: WetFloorSignMineExplosive components: - - type: Sprite - sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - state: caution - - type: Item - sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi - size: 15 - type: StepTrigger intersectRatio: 0.2 requiredTriggeredSpeed: 0 @@ -254,6 +251,16 @@ totalIntensity: 60 # about a ~3 tile radius canCreateVacuum: false - type: DeleteOnTrigger + - type: OnUseTimerTrigger + useVerbInstead: true + beepInterval: .25 + beepSound: /Audio/Items/Janitor/floor_sign_beep.ogg + params: + volume: 1 + examinable: false + - type: Tag + tags: # ignore "WhitelistChameleon" tag + - WetFloorSign - type: entity name: janitorial trolley diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml index 6fdb04cb3a2..6eaea1ee0e6 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/handheld_crew_monitor.yml @@ -27,6 +27,10 @@ - type: WirelessNetworkConnection range: 500 - type: StationLimitedNetwork + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - HandheldCrewMonitor - type: StaticPrice price: 500 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml b/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml index b2c1f6cdcc7..9c580ede66a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml @@ -19,6 +19,10 @@ - type: GuideHelp guides: - ScannersAndVessels + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - AnomalyScanner - type: entity id: AnomalyLocatorUnpowered @@ -71,3 +75,36 @@ slots: cell_slot: name: power-cell-slot-component-slot-name-default + +- type: entity + id: AnomalyLocatorWideUnpowered + parent: AnomalyLocatorUnpowered + name: wide-spectrum anomaly locator + description: A device that looks for anomalies from an extended distance, but has no way to determine the distance to them. + suffix: Unpowered + components: + - type: Sprite + sprite: Objects/Specific/Research/anomalylocatorwide.rsi + - type: ProximityBeeper + maximumDistance: 40 + minBeepInterval: 0.5 + maxBeepInterval: 0.5 + +- type: entity + id: AnomalyLocatorWide + parent: [ AnomalyLocatorWideUnpowered, PowerCellSlotSmallItem ] + suffix: Powered + components: + - type: PowerCellDraw + drawRate: 1 + useRate: 0 + +- type: entity + id: AnomalyLocatorWideEmpty + parent: AnomalyLocatorWide + suffix: Empty + components: + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml index 268a91c8de3..f928c9f00b9 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Research/rped.yml @@ -21,3 +21,7 @@ whitelist: components: - MachinePart + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - RPED diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/node_scanner.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/node_scanner.yml index 7406555fe32..673afc91ba1 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/node_scanner.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/node_scanner.yml @@ -12,6 +12,10 @@ - type: NodeScanner - type: UseDelay delay: 3 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - NodeScanner - type: GuideHelp guides: - ArtifactReports diff --git a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml index d500ef141c3..24eb0b02b24 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity name: haycutters parent: BaseItem id: Haycutters @@ -98,6 +98,7 @@ path: /Audio/Items/crowbar.ogg speed: 0.05 - type: TilePrying + - type: Prying - type: entity name: mooltitool diff --git a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml index a7f74a542f4..36f96f61af8 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jaws_of_life.yml @@ -24,6 +24,12 @@ - Prying speed: 1.5 useSound: /Audio/Items/jaws_pry.ogg + - type: Prying + pryPowered: !type:Bool + true + force: !type:Bool + true + useSound: /Audio/Items/jaws_pry.ogg - type: ToolForcePowered - type: MultipleTool statusShowBehavior: true @@ -77,4 +83,4 @@ - type: MeleeWeapon damage: types: - Blunt: 14 \ No newline at end of file + Blunt: 14 diff --git a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml index b87bbae0d86..d57a34c88f9 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml @@ -57,6 +57,13 @@ - type: Appearance - type: StaticPrice price: 100 +# - type: DynamicPrice +# price: 100 + - type: ReverseEngineering # Nyano + generic: true + difficulty: 3 + recipes: + - JetpackBlue - type: entity id: ActionToggleJetpack @@ -195,6 +202,10 @@ outputPressure: 42.6 air: volume: 1.5 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - JetpackMini # Filled mini - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index 3d58b2b079d..24e31adedcd 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -155,6 +155,7 @@ Steel: 100 - type: StaticPrice price: 22 + - type: Prying - type: entity parent: Crowbar @@ -314,6 +315,12 @@ materialComposition: Steel: 300 Plastic: 100 +# - type: DynamicPrice +# price: 100 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - PowerDrill - type: StaticPrice price: 100 - type: MeleeWeapon @@ -404,6 +411,12 @@ Plastic: 100 - type: StaticPrice price: 60 +# - type: DynamicPrice +# price: 60 + - type: ReverseEngineering # Nyano + difficulty: 3 + recipes: + - RCDAmmo - type: entity name: omnitool diff --git a/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml b/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml index d807bcc5a9f..4a8fa0da5cb 100644 --- a/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml +++ b/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml @@ -39,7 +39,7 @@ sound: path: /Audio/Effects/metalbreak.ogg - !type:ExplodeBehavior - + - type: entity parent: BaseVehicle id: BaseVehicleRideable @@ -198,7 +198,7 @@ baseSprintSpeed: 6 - type: Armor modifiers: - coeffecients: + coefficients: Blunt: 0.8 Slash: 0.6 Piercing: 0.85 @@ -289,7 +289,7 @@ maxBuckleDistance: 1 - type: Armor modifiers: - coeffecients: + coefficients: Blunt: 0.8 Slash: 0.6 Piercing: 0.85 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml index cb6f8627450..764683183d9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/armblade.yml @@ -20,3 +20,4 @@ - type: Tool qualities: - Prying + - type: Prying diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml index 9e747328f94..fcc2129a51f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml @@ -38,6 +38,7 @@ - Prying - type: TilePrying advanced: true + - type: Prying - type: entity id: FireAxeFlaming diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml index d182d9a00e9..3073ed7ab53 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/mining.yml @@ -61,6 +61,7 @@ - type: Tool qualities: - Prying + - type: Prying - type: entity name: crusher dagger diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml index 513e691395f..d6c2c69ce69 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml @@ -48,3 +48,7 @@ Brute: 10 types: Structural: 10 + - type: ReverseEngineering # Nyano + difficulty: 2 + recipes: + - MiningDrill diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index dc5c052639b..eea5d689938 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -122,6 +122,11 @@ size: 5 sprite: Objects/Weapons/Melee/flash.rsi - type: ItemCooldown +# - type: DynamicPrice +# price: 40 + - type: ReverseEngineering # Nyano + recipes: + - Flash - type: StaticPrice price: 40 - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/easy_pry.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/easy_pry.yml new file mode 100644 index 00000000000..04a58eebe07 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/easy_pry.yml @@ -0,0 +1,63 @@ +- type: entity + parent: AirlockExternal + id: AirlockExternalEasyPry + suffix: External, EasyPry + description: It opens, it closes, it might crush you, and there might be only space behind it. Has to be manually activated. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockExternalGlass + id: AirlockExternalGlassEasyPry + suffix: External, Glass, EasyPry + description: It opens, it closes, it might crush you, and there might be only space behind it. Has to be manually activated. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockGlassShuttle + id: AirlockGlassShuttleEasyPry + suffix: EasyPry, Docking + description: Necessary for connecting two space craft together. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockShuttle + id: AirlockShuttleEasyPry + suffix: EasyPry, Docking + description: Necessary for connecting two space craft together. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockExternalLocked + id: AirlockExternalEasyPryLocked + suffix: External, EasyPry, Locked + description: It opens, it closes, it might crush you, and there might be only space behind it. Has to be manually activated. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockExternalGlassLocked + id: AirlockExternalGlassEasyPryLocked + suffix: External, Glass, EasyPry, Locked + description: It opens, it closes, it might crush you, and there might be only space behind it. Has to be manually activated. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockExternalGlassShuttleLocked + id: AirlockGlassShuttleEasyPryLocked + suffix: EasyPry, Docking, Locked + description: Necessary for connecting two space craft together. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered + +- type: entity + parent: AirlockExternalShuttleLocked + id: AirlockShuttleEasyPryLocked + suffix: EasyPry, Docking, Locked + description: Necessary for connecting two space craft together. Has a valve labelled "TURN TO OPEN" + components: + - type: PryUnpowered diff --git a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml index 23f02156d77..1a81ac47024 100644 --- a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml +++ b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml @@ -15,6 +15,16 @@ state: icon - type: TimedDespawn lifetime: 90 + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 30 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: HoloFan @@ -58,17 +68,6 @@ - TableMask layer: - TableLayer - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Metallic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 30 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: TimedDespawn lifetime: 180 - type: PointLight diff --git a/Resources/Prototypes/Entities/Structures/Machines/bombs.yml b/Resources/Prototypes/Entities/Structures/Machines/bombs.yml index 40a3e36df89..a88da73550e 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/bombs.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/bombs.yml @@ -41,7 +41,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.45,-0.45,0.45,0.45" + bounds: "-0.3,-0.3,0.3,0.3" density: 190 mask: - MachineMask diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index f6fa327ac54..43b9bba01ca 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -135,6 +135,7 @@ - type: EmagLatheRecipes emagStaticRecipes: - CartridgePistol + - CartridgeSpecial # DeltaV - .38 Special revolver - CartridgeMagnum - ShellShotgun - ShellShotgunFlare @@ -147,6 +148,7 @@ - MagazineBoxLightRifle emagDynamicRecipes: - CartridgePistolRubber + - CartridgeSpecialRubber # DeltaV - .38 Special revolver - CartridgeMagnumRubber - ShellShotgunBeanbag - CartridgeRifleRubber @@ -203,6 +205,7 @@ - MiningDrill - AnomalyScanner - AnomalyLocator + - AnomalyLocatorWide - RCD - RCDAmmo - HandheldCrewMonitor @@ -365,6 +368,19 @@ - SodaDispenserMachineCircuitboard - TelecomServerCircuitboard - MassMediaCircuitboard + # Begin Nyano additions + - ReverseEngineeringMachineCircuitboard + - CrewMonitoringComputerCircuitboard + - DoorElectronics + - FireAlarmElectronics + - FirelockElectronics + - IntercomElectronics + - MailingUnitElectronics + - SalvageMagnetMachineCircuitboard + - StationMapElectronics +# - MetempsychoticMachineCircuitboard +# - DeepFryerMachineCircuitBoard + # End Nyano additions - type: MaterialStorage whitelist: tags: @@ -477,6 +493,12 @@ - HamtrLLeg - HamtrRLeg - VimHarness + # Begin Nyano additions + - ClothingOuterHardsuitJuggernautReverseEngineered + - ClothingOuterHardsuitSyndieReverseEngineered + - JetpackBlue + - JetpackMini + # End Nyano additions - type: MaterialStorage whitelist: tags: @@ -528,20 +550,25 @@ - MagazineRifle - MagazineLightRifle - MagazineBoxPistol + - MagazineBoxSpecial # DeltaV - .38 Special revolver - MagazineBoxMagnum - MagazineBoxRifle - MagazineBoxLightRifle - SpeedLoaderMagnum + - SpeedLoaderSpecial # DeltaV - .38 Special revolver - TargetHuman - TargetSyndicate - TargetClown dynamicRecipes: + - CartridgeSpecialRubber # DeltaV - .38 Special revolver - CartridgePistolRubber - CartridgeMagnumRubber - ShellShotgunBeanbag - CartridgeRifleRubber + - EncryptionKeySyndie # Nyano - CartridgeLightRifleRubber - MagazineBoxPistolRubber + - MagazineBoxSpecialRubber # DeltaV - .38 Special revolver - MagazineBoxMagnumRubber - MagazineBoxRifleRubber - MagazineBoxLightRifleRubber @@ -554,6 +581,8 @@ - MagazineBoxMagnumIncendiary - MagazineBoxLightRifleIncendiary - MagazineBoxRifleIncendiary + - CartridgeSpecialHoly # DeltaV - .38 Special revolver, Holy ammo + - CartridgeSpecialMindbreaker # DeltaV - .38 Special revolver, Mindbreaker ammo - Signaller - SignalTrigger - VoiceTrigger @@ -568,6 +597,8 @@ - WeaponLaserCannon - WeaponXrayCannon - WeaponTaser + - ClothingHeadHelmetInsulated # Nyanotrasen - Insulative headgear + - ClothingHeadCage # Nyanotrasen - Insulative headgear - type: MaterialStorage whitelist: tags: @@ -675,6 +706,8 @@ - Hemostat - BluespaceBeaker - SyringeBluespace + - ClothingEyesHudMedical # Nyano + - ChemicalPayload # Nyano - type: Machine board: MedicalTechFabCircuitboard @@ -738,6 +771,10 @@ - ClothingUniformJumpsuitLawyerBlack - ClothingUniformJumpsuitLibrarian - ClothingUniformJumpskirtColorLightBrown + - ClothingUniformMailCarrier # DeltaV - Courier Uniform + - ClothingUniformSkirtMailCarrier # DeltaV - Courier Uniform + - ClothingUniformJumpsuitMantis # Nyanotrasen - Forensic Mantis + - ClothingUniformSkirtMantis # Nyanotrasen - Forensic Mantis - ClothingUniformJumpsuitMedicalDoctor - ClothingUniformJumpskirtMedicalDoctor - ClothingUniformJumpsuitMime @@ -832,6 +869,7 @@ runningState: building canEjectStoredMaterials: false staticRecipes: + - BluespaceCrystal #Nyanotrasen Code - SheetSteel30 - SheetGlass30 - SheetRGlass30 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index f5c1f2015f9..b99b88483c2 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -82,10 +82,11 @@ - type: Appearance - type: GenericVisualizer visuals: - enum.PumpVisuals.Enabled: + enum.GasVolumePumpVisuals.State: enabled: - True: { state: pumpVolumeOn } - False: { state: pumpVolume } + On: { state: pumpVolumeOn } + Off: { state: pumpVolume } + Blocked: { state: pumpVolumeBlocked } - type: PipeColorVisuals - type: GasVolumePump enabled: false diff --git a/Resources/Prototypes/Entities/Structures/Specific/dragon.yml b/Resources/Prototypes/Entities/Structures/Specific/dragon.yml index 9c9b09c7c71..8a7f13d1a45 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/dragon.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/dragon.yml @@ -5,35 +5,43 @@ placement: mode: SnapgridCenter components: - - type: DragonRift - - type: Transform - anchored: true - - type: Physics - bodyType: Static - canCollide: false - - type: Fixtures - - type: Sprite - layers: - - sprite: Structures/Specific/carp_rift.rsi - state: icon - color: "#569fff" - shader: unshaded - - type: InteractionOutline - - type: Clickable - - type: PointLight - enabled: true - color: "#366db5" - radius: 10.0 - energy: 5.0 - netsync: false - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Metallic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] + - type: DragonRift + - type: Transform + anchored: true + - type: Physics + bodyType: Static + canCollide: false + - type: Fixtures + - type: Sprite + layers: + - sprite: Structures/Specific/carp_rift.rsi + state: icon + color: "#569fff" + shader: unshaded + - type: InteractionOutline + - type: Clickable + - type: PointLight + enabled: true + color: "#366db5" + radius: 10.0 + energy: 5.0 + netsync: false + - type: NavMapBeacon + color: "#ff0000" + text: carp rift + # only show after making the announcement at 50% + enabled: false + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: EmitSoundOnSpawn + sound: + path: /Audio/Weapons/Guns/Gunshots/rocket_launcher.ogg diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml index f4269b1fab3..5f3b841565d 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml @@ -156,4 +156,25 @@ - type: ExaminableSolution solution: tank - type: ReagentTank - transferAmount: 100 \ No newline at end of file + transferAmount: 100 + +- type: entity + id: GenericTank + parent: StorageTank + suffix: Empty + components: + - type: StaticPrice + price: 500 + - type: Sprite + sprite: Structures/Storage/tanks.rsi + layers: + - state: generictank-1 + - state: watertank-2-1 + map: ["enum.SolutionContainerLayers.Fill"] + visible: false + - type: Appearance + - type: SolutionContainerVisuals + maxFillLevels: 5 + fillBaseName: watertank-2- + - type: ExaminableSolution + solution: tank diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml index 2e3f00724a9..628b2e5852e 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/signs.yml @@ -1278,3 +1278,21 @@ components: - type: Sprite state: zero + +- type: entity + parent: BaseSign + id: SignSurvival + name: survival sign + description: A sign. "Survival" is written on it. + components: + - type: Sprite + state: survival + +- type: entity + parent: BaseSign + id: SignNTMine + name: mine sign + description: A sign. "Mine" is written on it. + components: + - type: Sprite + state: ntmining diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index 3e15f276636..07c2fb2d37c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -990,6 +990,79 @@ node: wall +# Lavalend Walls + +- type: entity + parent: BaseWall + id: WallNecropolis + name: stone wall + components: + - type: Tag + tags: + - Wall + - type: Sprite + sprite: Structures/Walls/necropolis.rsi + - type: Icon + sprite: Structures/Walls/necropolis.rsi + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 1000 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: IconSmooth + key: walls + base: necropolis + +- type: entity + parent: BaseWall + id: WallMining + name: wall + components: + - type: Tag + tags: + - Wall + - type: Sprite + sprite: Structures/Walls/mining.rsi + - type: Icon + sprite: Structures/Walls/mining.rsi + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 700 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: IconSmooth + key: walls + base: mining + +- type: entity + parent: WallShuttleDiagonal + id: WallMiningDiagonal + name: wall + suffix: diagonal + placement: + mode: SnapgridCenter + snap: + - Wall + components: + - type: Sprite + drawdepth: Walls + sprite: Structures/Walls/mining_diagonal.rsi + state: state0 + - type: IconSmooth + mode: Diagonal + key: walls + base: state + - type: Icon + sprite: Structures/Walls/mining_diagonal.rsi + state: state0 + + # Vault Walls - type: entity diff --git a/Resources/Prototypes/Flavors/flavors.yml b/Resources/Prototypes/Flavors/flavors.yml index 2b8e2b0e2f0..fc3b0ba5771 100644 --- a/Resources/Prototypes/Flavors/flavors.yml +++ b/Resources/Prototypes/Flavors/flavors.yml @@ -837,4 +837,9 @@ - type: flavor id: spaceshroomcooked flavorType: Complex - description: flavor-complex-spaceshroom-cooked \ No newline at end of file + description: flavor-complex-spaceshroom-cooked + +- type: flavor + id: lostfriendship + flavorType: Complex + description: flavor-complex-lost-friendship diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 0bfba08c734..2aa046035ca 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -68,13 +68,14 @@ - type: entity parent: BaseGameRule - id: Dragon + id: DragonSpawn noSpawn: true components: - type: StationEvent weight: 5 duration: 1 earliestStart: 45 + reoccurrenceDelay: 60 minimumPlayers: 20 - type: RandomSpawnRule prototype: SpawnPointGhostDragon diff --git a/Resources/Prototypes/GameRules/midround.yml b/Resources/Prototypes/GameRules/midround.yml index 1927cde53c3..d7dff95b51e 100644 --- a/Resources/Prototypes/GameRules/midround.yml +++ b/Resources/Prototypes/GameRules/midround.yml @@ -15,3 +15,15 @@ - NinjaSurviveObjective - type: NinjaRule threats: NinjaThreats + +# stores configuration for dragon +- type: entity + noSpawn: true + parent: BaseGameRule + id: Dragon + components: + - type: GenericAntagRule + agentName: dragon-round-end-agent-name + objectives: + - CarpRiftsObjective + - DragonSurviveObjective diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/backpack.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/backpack.yml new file mode 100644 index 00000000000..d72e0dd7cd8 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/backpack.yml @@ -0,0 +1,13 @@ +- type: entity + noSpawn: true + parent: ClothingBackpackScience + id: ClothingBackpackMantisFilled + components: + - type: StorageFill + contents: + - id: BoxSurvival + # - id: BoxForensicPad # DeltaV - Mantis is no longer a Detective + - id: HandLabeler + - id: PillMindbreakerToxin + - id: BoxFolderGrey + - id: RubberStampMantis diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/duffelbag.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/duffelbag.yml new file mode 100644 index 00000000000..982b820ad10 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/duffelbag.yml @@ -0,0 +1,13 @@ +- type: entity + noSpawn: true + parent: ClothingBackpackDuffelScience + id: ClothingBackpackDuffelMantisFilled + components: + - type: StorageFill + contents: + - id: BoxSurvival + # - id: BoxForensicPad # DeltaV - Mantis is no longer a Detective + - id: HandLabeler + - id: PillMindbreakerToxin + - id: BoxFolderGrey + - id: RubberStampMantis diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/satchel.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/satchel.yml new file mode 100644 index 00000000000..5644f36c9ce --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Backpacks/StarterGear/satchel.yml @@ -0,0 +1,13 @@ +- type: entity + noSpawn: true + parent: ClothingBackpackSatchelScience + id: ClothingBackpackSatchelMantisFilled + components: + - type: StorageFill + contents: + - id: BoxSurvival + # - id: BoxForensicPad # DeltaV - Mantis is no longer a Detective + - id: HandLabeler + - id: PillMindbreakerToxin + - id: BoxFolderGrey + - id: RubberStampMantis diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Books/lore.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Books/lore.yml new file mode 100644 index 00000000000..6c3eb06108f --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Books/lore.yml @@ -0,0 +1,24 @@ +- type: entity + name: epistemics book + parent: BookRandom # placeholder + id: BookSalvageEpistemics + noSpawn: true + description: 'A metallic hardcover book.' + +- type: entity + name: epistemics book + parent: BookSalvageEpistemics + id: BookSalvageEpistemicsRandom + components: + - type: RandomSpawner + prototypes: + - BookSalvageEpistemics1 + offset: 0.1 + +- type: entity + parent: BookSalvageEpistemics + id: BookSalvageEpistemics1 + suffix: 1 + components: + - type: Paper + content: book-text-epistemics1 diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Crates/syndicate.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Crates/syndicate.yml new file mode 100644 index 00000000000..23e1e4eb81e --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Crates/syndicate.yml @@ -0,0 +1,8 @@ +- type: entity + id: CrateSyndicateSamurai + parent: CrateSyndicate + components: + - type: StorageFill + contents: + - id: ClothingOuterArmorTouseiGusoku + - id: ClothingHeadHelmetKabuto diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Lockers/epistemics.yml b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Lockers/epistemics.yml new file mode 100644 index 00000000000..d1542229098 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Catalog/Fills/Lockers/epistemics.yml @@ -0,0 +1,27 @@ +- type: entity + id: LockerForensicMantisFilled + suffix: Filled + parent: LockerForensicMantis + components: + - type: StorageFill + contents: + # Tools + # - id: FlashlightSeclite # Deltav - Detective is in charge of investigating crimes. + # - id: ForensicScanner + # - id: BoxForensicPad + - id: AntiPsychicKnife + # Spare change of clothes + - id: ClothingUniformJumpsuitMantis + - id: ClothingUniformSkirtMantis + - id: ClothingBeltMantis + - id: ClothingShoesBootsMantis + - id: ClothingHandsGlovesForensic + - id: ClothingHeadHatFezMantis + - id: ClothingOuterCoatMantis + - id: ClothingOuterWinterCoatMantis + - id: ClothingEyesGlassesSunglasses + # Insulative headgear + - id: ClothingHeadTinfoil + - id: ClothingHeadCage + - id: ClothingHeadCage + - id: BoxZiptie diff --git a/Resources/Prototypes/Nyanotrasen/Catalog/uplink_catalog.yml b/Resources/Prototypes/Nyanotrasen/Catalog/uplink_catalog.yml index d721511045a..043e16054ff 100644 --- a/Resources/Prototypes/Nyanotrasen/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Nyanotrasen/Catalog/uplink_catalog.yml @@ -1,3 +1,17 @@ +- type: listing + id: UplinkKanabou + name: uplink-kanabou-name + description: uplink-kanabou-desc + productEntity: Kanabou + cost: + Telecrystal: 10 + categories: + - UplinkWeapons + conditions: + - !type:BuyerSpeciesCondition + whitelist: + - Oni + - type: listing id: UplinkRickenbacker name: uplink-rickenbacker4001-name @@ -11,3 +25,21 @@ - !type:BuyerJobCondition whitelist: - Musician + +- type: listing + id: UplinkSamurai + name: uplink-samurai-crate-name + description: uplink-samurai-crate-desc + productEntity: CrateSyndicateSamurai + cost: + Telecrystal: 6 + categories: + - UplinkArmor + conditions: + - !type:BuyerSpeciesCondition + whitelist: + - Oni + - !type:BuyerWhitelistCondition + blacklist: + components: + - SurplusBundle diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Belt/belts.yml index 70011547dd2..49bfcc247c5 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Belt/belts.yml @@ -1,7 +1,7 @@ - type: entity parent: ClothingBeltStorageBase id: ClothingBeltMantis - name: forensic mantis' belt + name: psionic mantis' belt # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Perfect for storing all of your forensic equipment. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Ears/headsets.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Ears/headsets.yml deleted file mode 100644 index 3c5565abb21..00000000000 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Ears/headsets.yml +++ /dev/null @@ -1,15 +0,0 @@ -- type: entity - parent: ClothingHeadsetAlt - id: ClothingHeadsetMantis - name: mantis headset - components: - - type: ContainerFill - containers: - key_slots: - - EncryptionKeyScience - - EncryptionKeySecurity - - EncryptionKeyCommon - - type: Sprite - sprite: Clothing/Ears/Headsets/science.rsi - - type: Clothing - sprite: Clothing/Ears/Headsets/science.rsi diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Head/hats.yml index 030c968a5f6..67d2ba995d2 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Head/hats.yml @@ -122,7 +122,7 @@ - type: entity parent: ClothingHeadBase id: ClothingHeadHatFezMantis - name: forensic mantis' fez + name: psionic mantis' fez # DeltaV - Rename Forensic Mantis to Psionic Mantis description: A fine red fez with a gold tassel. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/coats.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/coats.yml index 477a7da36c1..bbb04cad67e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/coats.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/coats.yml @@ -1,7 +1,7 @@ - type: entity parent: ClothingOuterStorageBase id: ClothingOuterCoatMantis - name: forensic mantis' jacket + name: psionic mantis' jacket # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Modeled after an ancient infantry uniform, this jacket may guard you against the unknown in your journey for the truth. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/hardsuits.yml index 8d5dfc63342..6498eda075e 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/hardsuits.yml @@ -19,8 +19,8 @@ sprite: Nyanotrasen/Clothing/OuterClothing/ReverseEngineering/syndicate.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieReverseEngineered -# - type: ReverseEngineering -# newItem: null + - type: ReverseEngineering + newItem: null - type: entity parent: ClothingOuterHardsuitJuggernaut @@ -35,8 +35,8 @@ sprite: Nyanotrasen/Clothing/OuterClothing/ReverseEngineering/juggernaut.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitJuggernautReverseEngineered -# - type: ReverseEngineering -# newItem: null + - type: ReverseEngineering + newItem: null - type: entity parent: ClothingOuterHardsuitERTLeader diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/wintercoats.yml index 7a3944e257f..e995f9e0eff 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/OuterClothing/wintercoats.yml @@ -47,7 +47,7 @@ - type: entity parent: ClothingOuterWinterCoat id: ClothingOuterWinterCoatMantis - name: forensic mantis' winter coat + name: psionic mantis' winter coat # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Solve cold cases in style. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Shoes/boots.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Shoes/boots.yml index e7012515cad..4b1cec27f6c 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Shoes/boots.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Shoes/boots.yml @@ -1,7 +1,7 @@ - type: entity parent: ClothingShoesBaseButcherable id: ClothingShoesBootsMantis - name: forensic mantis' boots + name: psionic mantis' boots # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Soft, comfortable, and good for rough terrain. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Uniforms/jumpsuits.yml index 37578193bb0..9b5c205f4e5 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Clothing/Uniforms/jumpsuits.yml @@ -72,7 +72,7 @@ - type: entity parent: ClothingUniformBase id: ClothingUniformJumpsuitMantis - name: forensic mantis' uniform + name: psionic mantis' uniform # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Modeled after an ancient infantry uniform, this uniform has superior mobility for tense situations. components: - type: Sprite @@ -83,7 +83,7 @@ - type: entity parent: ClothingUniformSkirtBase id: ClothingUniformSkirtMantis - name: forensic mantis' jumpskirt + name: psionic mantis' jumpskirt # DeltaV - Rename Forensic Mantis to Psionic Mantis description: Adapted from an ancient infantry uniform, this jumpskirt has superior mobility for tense situations. components: - type: Sprite diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/books.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/books.yml index 3842a3ade75..4188a8dd768 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/books.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/books.yml @@ -71,4 +71,5 @@ - BookGnominomicon - BookFishing - BookDetective + - BookSalvageEpistemics1 # Nyanotrasen - Epistemic Lore Book rareChance: 0.25 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml index 4bbc5400d08..336341e5684 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml @@ -61,7 +61,7 @@ - TraversalDistorterMachineCircuitboard - CloningPodMachineCircuitboard # - MetempsychoticMachineCircuitboard - # - ReverseEngineeringMachineCircuitboard + - ReverseEngineeringMachineCircuitboard - MedicalScannerMachineCircuitboard - DawInstrumentMachineCircuitboard - StasisBedMachineCircuitboard diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/jobs.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/jobs.yml index 2f2ea2e9797..fb618896adc 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/jobs.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/jobs.yml @@ -36,7 +36,7 @@ layers: - state: green - state: nyanoprisonguard - + - type: entity id: SpawnPointMailCarrier parent: SpawnPointJobBase @@ -62,3 +62,16 @@ layers: - state: green - state: nyanomartialartist + +- type: entity + id: SpawnPointForensicMantis + parent: SpawnPointJobBase + name: psionic mantis # DeltaV - Rename Forensic Mantis to Psionic Mantis + components: + - type: SpawnPoint + job_id: ForensicMantis + - type: Sprite + sprite: DeltaV/Markers/jobs.rsi + layers: + - state: green + - state: nyanomantis diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml new file mode 100644 index 00000000000..45a97fe8596 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml @@ -0,0 +1,26 @@ +- type: entity + id: ReverseEngineeringMachineCircuitboard + parent: BaseMachineCircuitboard + name: reverse engineering machine machine board + description: A machine printed circuit board for a reverse engineering machine + components: + - type: Sprite + state: engineering + - type: MachineBoard + prototype: ReverseEngineeringMachine + requirements: + MatterBin: 1 + Manipulator: 1 + materialRequirements: + Glass: 1 + Cable: 1 + Diamond: 10 + tagRequirements: + BorgArm: + Amount: 3 + DefaultPrototype: LeftArmBorg + ExamineName: borg arm + - type: ReverseEngineering + difficulty: 3 + recipes: + - ReverseEngineeringMachineCircuitboard diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/Misc/identification_cards.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/Misc/identification_cards.yml index 240ca4caebc..ff9b3f8f2a0 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/Misc/identification_cards.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/Misc/identification_cards.yml @@ -63,3 +63,16 @@ state: nyanomartialartist - type: PresetIdCard job: MartialArtist + +- type: entity + parent: IDCardStandard + id: ForensicMantisIDCard + name: psionic mantis ID card # DeltaV - Rename Forensic Mantis to Psionic Mantis + components: + - type: Sprite + layers: + - state: default + - sprite: DeltaV/Objects/Misc/id_cards.rsi + state: nyanomantis + - type: PresetIdCard + job: ForensicMantis diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml index b9056a9239c..2fb24c6d42f 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/pda.yml @@ -32,7 +32,7 @@ accentVColor: "#DFDFDF" - type: Icon state: pda-security - + - type: entity parent: BasePDA id: MailCarrierPDA @@ -62,10 +62,47 @@ state: pda-mailcarrier - type: entity - parent: BoxerPDA + parent: BasePDA id: MartialArtistPDA name: martial artist PDA + description: Smells like straw. components: + - type: Sprite + sprite: DeltaV/Objects/Devices/pda.rsi + layers: + - map: [ "enum.PdaVisualLayers.Base" ] + - state: "light_overlay" + map: [ "enum.PdaVisualLayers.Flashlight" ] + shader: "unshaded" + visible: false + - state: "id_overlay" + map: [ "enum.PdaVisualLayers.IdLight" ] + shader: "unshaded" + visible: false - type: Pda id: MartialArtistIDCard - state: pda-boxer + state: pda-martialartist + - type: PdaBorderColor + borderColor: "#d7d7d0" + accentHColor: "#232323" + - type: Icon + sprite: DeltaV/Objects/Devices/pda.rsi + state: pda-martialartist + +- type: entity + parent: BasePDA + id: ForensicMantisPDA + name: psionic mantis PDA # DeltaV - Rename Forensic Mantis to Psionic Mantis + description: Smells like illegal substances. + components: + - type: Pda + id: ForensicMantisIDCard + state: pda-science + - type: Icon + state: pda-science + # - type: CartridgeLoader + # preinstalled: + # - CrewManifestCartridge + # - NotekeeperCartridge + # - NewsReadCartridge + # - GlimmerMonitorCartridge # Uncomment this entire thing if we re-implement the glimmer monitor. diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Materials/materials.yml index 5aed17363ba..ea280e8fef5 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Materials/materials.yml @@ -1,3 +1,47 @@ +- type: entity + parent: MaterialBase + id: MaterialBluespace + suffix: Full + name: bluespace crystal + components: + - type: Sprite + sprite: Nyanotrasen/Objects/Materials/materials.rsi + layers: + - state: bluespace_3 + map: ["base"] + - type: Appearance + - type: Material + - type: PhysicalComposition + materialComposition: + Bluespace: 100 + - type: Tag + tags: + - BluespaceCrystal + - RawMaterial + - type: Stack + stackType: Bluespace + baseLayer: base + layerStates: + - bluespace + - bluespace_2 + - bluespace_3 + count: 5 + - type: Item + size: 5 + +- type: entity + parent: MaterialBluespace + id: MaterialBluespace1 + suffix: 1 + components: + - type: Sprite + state: bluespace + - type: Stack + stackType: Bluespace + count: 1 + - type: Item + size: 1 + - type: entity parent: BaseItem id: HideMothroach diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Misc/paper.yml new file mode 100644 index 00000000000..22361c9aef6 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Misc/paper.yml @@ -0,0 +1,17 @@ +- type: entity + name: psionic mantis' seal # DeltaV - Rename Forensic Mantis to Psionic Mantis + parent: RubberStampBase + id: RubberStampMantis + suffix: DO NOT MAP + description: An old-fashioned seal for marking important documents, made of polished bronze. + components: + - type: Stamp + stampedName: stamp-component-stamped-name-mantis + stampedColor: "#777777" + stampState: "paper_stamp-mantis" + - type: Sprite + sprite: Nyanotrasen/Objects/Misc/bureaucracy.rsi + state: stamp-mantis + - type: Tag + tags: + - ForensicBeltEquip diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml index 73d0af4ad2a..efc26f80b67 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail.yml @@ -111,8 +111,8 @@ prob: 0.10 - id: BookGnominomicon prob: 0.2 -# - id: BookSalvageEpistemics1 -# prob: 0.025 + - id: BookSalvageEpistemics1 + prob: 0.025 - type: entity noSpawn: true diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml index bdf50f5edf8..38526966b80 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Mail/mail_epistemology.yml @@ -1,13 +1,12 @@ -#- type: entity -# noSpawn: true -# parent: BaseMail -# id: MailEpistemologyBluespace -# suffix: bluespace -# components: -# - type: Mail -# contents: -# - id: MaterialBluespace1 -# Awaiting bluespace to be implemented +- type: entity + noSpawn: true + parent: BaseMail + id: MailEpistemologyBluespace + suffix: bluespace + components: + - type: Mail + contents: + - id: MaterialBluespace1 - type: entity noSpawn: true @@ -51,8 +50,8 @@ - type: entity noSpawn: true parent: BaseMail - id: MailForensicMantisForensicSupplement - suffix: forensicsupplement + id: MailDetectiveForensicSupplement # Deltav - Detective is in charge of investigating crimes. + suffix: detectivesupplement # Deltav - Detective is in charge of investigating crimes. components: - type: Mail contents: diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Medical/pills.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Medical/pills.yml new file mode 100644 index 00000000000..3aa516064b9 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Specific/Medical/pills.yml @@ -0,0 +1,13 @@ +- type: entity + name: mindbreaker toxin + parent: Pill + id: PillMindbreakerToxin + description: Removes psionics when ingested. Mildly poisonous. + components: + - type: SolutionContainerManager + solutions: + food: + maxVol: 20 + reagents: + - ReagentId: MindbreakerToxin + Quantity: 20 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Weapons/Melee/knives.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Weapons/Melee/knives.yml index 720fceccbf5..b44714c1cea 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Weapons/Melee/knives.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Weapons/Melee/knives.yml @@ -19,7 +19,6 @@ # Slash: 1.2 # Piercing: 1.2 # Holy: 1.2 - - type: Sprite sprite: Nyanotrasen/Objects/Weapons/Melee/anti_psychic_knife.rsi state: icon @@ -27,5 +26,5 @@ sprite: Nyanotrasen/Objects/Weapons/Melee/anti_psychic_knife.rsi - type: Tag tags: -# - ForensicBeltEquip + - ForensicBeltEquip - HighRiskItem diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/reverseEngineering.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/reverseEngineering.yml new file mode 100644 index 00000000000..b3233a5c4df --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/reverseEngineering.yml @@ -0,0 +1,78 @@ +- type: entity + parent: BaseMachinePowered + id: ReverseEngineeringMachine + name: reverse engineering machine + description: Destructively analyses pieces of technology in the hopes that we can retrieve information from them. + components: + - type: ReverseEngineeringMachine + - type: Sprite + sprite: Nyanotrasen/Structures/Machines/reverse_engineering.rsi + snapCardinals: true + layers: + - state: open + map: ["open"] + - state: unlit + shader: unshaded + map: ["enum.PowerDeviceVisualLayers.Powered"] + noRot: true + - type: ActivatableUI + key: enum.ReverseEngineeringMachineUiKey.Key + - type: UserInterface + interfaces: + - key: enum.ReverseEngineeringMachineUiKey.Key + type: ReverseEngineeringMachineBoundUserInterface + - type: ActivatableUIRequiresPower + - type: ItemSlots + slots: + target_slot: + name: ReverseEngineeringTarget + whitelist: + components: + - ReverseEngineering + - type: Construction + graph: Machine + node: machine + containers: + - machine_board + - machine_parts + - type: ContainerContainer + containers: + machine_board: !type:Container + machine_parts: !type:Container + target_slot: !type:ContainerSlot + - type: EmptyOnMachineDeconstruct + containers: + - target_slot + - type: Machine + board: ReverseEngineeringMachineCircuitboard + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + - type: SpriteFade + - type: AmbientSound + enabled: false + volume: -5 + range: 5 + sound: + path: /Audio/Ambience/Objects/revMachine_ambience.ogg +# - type: GuideHelp +# guides: +# - ReverseEngineering + - type: Appearance + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + enum.PowerDeviceVisualLayers.Powered: + True: { visible: true } + False: { visible: false } + enum.ReverseEngineeringVisuals.ChamberOpen: + open: + True: { state: open } + False: { state: closed } diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Storage/Closets/Lockers/lockers.yml new file mode 100644 index 00000000000..508ea269271 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Storage/Closets/Lockers/lockers.yml @@ -0,0 +1,31 @@ +- type: entity + id: LockerForensicMantis + parent: LockerDetective + suffix: Empty + name: psionic mantis' cabinet # DeltaV - Rename Forensic Mantis to Psionic Mantis + description: You'll never know what's inside until you collapse the quantum superposition of all possible mysteries. + components: + # Because it holds a traitor objective, StrongMetallic, + # but not as much HP as LockerBaseSecure, because it's not a Head's locker. + - type: Damageable + damageContainer: Inorganic + damageModifierSet: StrongMetallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 2 + MaterialWoodPlank1: + min: 1 + max: 2 diff --git a/Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml b/Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml new file mode 100644 index 00000000000..debf04a9013 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml @@ -0,0 +1,10 @@ +- type: entity + noSpawn: true + parent: BaseTraitorStealObjective + id: MantisKnifeStealObjective + components: + - type: NotJobRequirement + job: ForensicMantis + - type: StealCondition + prototype: AntiPsychicKnife + owner: job-name-mantis diff --git a/Resources/Prototypes/Nyanotrasen/Reagents/Materials/materials.yml b/Resources/Prototypes/Nyanotrasen/Reagents/Materials/materials.yml new file mode 100644 index 00000000000..e33394e09bd --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Reagents/Materials/materials.yml @@ -0,0 +1,7 @@ +- type: material + id: Bluespace + name: bluespace + icon: /Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace.png + color: "#53a9ff" + stackEntity: MaterialBluespace + price: 15 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Construction/Graphs/structures/altars.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Construction/Graphs/structures/altars.yml index 201d9c7d158..b98e0a919d5 100644 --- a/Resources/Prototypes/Nyanotrasen/Recipes/Construction/Graphs/structures/altars.yml +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Construction/Graphs/structures/altars.yml @@ -10,8 +10,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -21,8 +21,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -32,8 +32,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -43,8 +43,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -54,8 +54,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -65,8 +65,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -76,8 +76,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -87,8 +87,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -98,8 +98,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -109,8 +109,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -120,8 +120,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -131,8 +131,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -142,8 +142,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -153,8 +153,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -164,8 +164,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -175,8 +175,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -186,8 +186,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 @@ -197,8 +197,8 @@ steps: - material: Plasteel amount: 10 - # - material: Bluespace - # amount: 3 + - material: Bluespace + amount: 3 - material: Gold amount: 4 doAfter: 5 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/bluespace.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/bluespace.yml new file mode 100644 index 00000000000..8007dd03266 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/bluespace.yml @@ -0,0 +1,10 @@ +- type: latheRecipe + id: BluespaceCrystal + icon: + sprite: Nyanotrasen/Objects/Materials/materials.rsi + state: bluespace + result: MaterialBluespace1 + applyMaterialDiscount: false + completetime: 4 + materials: + Bluespace: 100 \ No newline at end of file diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/clothing.yml index d498a4ee5f5..aa4befb6fe5 100644 --- a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/clothing.yml @@ -7,3 +7,43 @@ completetime: 4 materials: Cloth: 300 + +- type: latheRecipe + id: ClothingUniformJumpsuitMantis + icon: + sprite: Nyanotrasen/Clothing/Uniforms/Jumpsuit/mantis_uniform.rsi + state: icon + result: ClothingUniformJumpsuitMantis + completetime: 4 + materials: + Cloth: 300 + +- type: latheRecipe + id: ClothingUniformSkirtMantis + icon: + sprite: Nyanotrasen/Clothing/Uniforms/Jumpskirt/mantis_jumpskirt.rsi + state: icon + result: ClothingUniformSkirtMantis + completetime: 4 + materials: + Cloth: 300 + +- type: latheRecipe + id: ClothingUniformMailCarrier + icon: + sprite: Nyanotrasen/Clothing/Uniforms/Jumpsuit/mailman.rsi + state: icon + result: ClothingUniformMailCarrier + completetime: 4 + materials: + Cloth: 300 + +- type: latheRecipe + id: ClothingUniformSkirtMailCarrier + icon: + sprite: Nyanotrasen/Clothing/Uniforms/Jumpskirt/mailman.rsi + state: icon + result: ClothingUniformSkirtMailCarrier + completetime: 4 + materials: + Cloth: 300 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/devices.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/devices.yml new file mode 100644 index 00000000000..8b95b9dfe26 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/devices.yml @@ -0,0 +1,26 @@ +- type: latheRecipe + id: EncryptionKeySyndie + result: EncryptionKeySyndie + completetime: 4 + materials: + Steel: 100 + Glass: 100 + Gold: 100 + +- type: latheRecipe + id: JetpackBlue + result: JetpackBlue + completetime: 10 + materials: + Steel: 8000 + Plastic: 8000 + Gold: 50 + +- type: latheRecipe + id: JetpackMini + result: JetpackMini + completetime: 10 + materials: + Steel: 4000 + Plastic: 4000 + Gold: 50 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml new file mode 100644 index 00000000000..5b5fd618b03 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml @@ -0,0 +1,44 @@ +#- type: latheRecipe +# id: MetempsychoticMachineCircuitboard +# result: MetempsychoticMachineCircuitboard +# completetime: 4 +# materials: +# Steel: 100 +# Glass: 900 +# Gold: 100 + +- type: latheRecipe + id: ReverseEngineeringMachineCircuitboard + result: ReverseEngineeringMachineCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 + Gold: 100 + +- type: latheRecipe + id: SalvageMagnetMachineCircuitboard + result: SalvageMagnetMachineCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 + Gold: 100 + +- type: latheRecipe + id: CrewMonitoringComputerCircuitboard + result: CrewMonitoringComputerCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 + +- type: latheRecipe + id: ClothingEyesHudMedical + icon: { sprite: Clothing/Eyes/Hud/med.rsi, state: icon } + result: ClothingEyesHudMedical + completetime: 4 + materials: + Steel: 100 + Glass: 300 + Plasma: 200 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/hardsuits.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/hardsuits.yml new file mode 100644 index 00000000000..560c03db49c --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/hardsuits.yml @@ -0,0 +1,21 @@ +- type: latheRecipe + id: ClothingOuterHardsuitSyndieReverseEngineered + result: ClothingOuterHardsuitSyndieReverseEngineered + completetime: 25 + materials: + Steel: 6000 + Glass: 1500 + Uranium: 100 + Plastic: 100 + Gold: 200 + +- type: latheRecipe + id: ClothingOuterHardsuitJuggernautReverseEngineered + result: ClothingOuterHardsuitJuggernautReverseEngineered + completetime: 25 + materials: + Steel: 12000 + Glass: 3000 + Uranium: 500 + Plastic: 500 + Gold: 250 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/parts.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/parts.yml new file mode 100644 index 00000000000..8a4e2d26b5f --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/parts.yml @@ -0,0 +1,30 @@ +# Rating 4 +- type: latheRecipe + id: QuadraticCapacitorStockPart + result: QuadraticCapacitorStockPart + completetime: 3 + materials: + Plastic: 100 + Gold: 50 + Plasma: 50 + Bluespace: 100 + +- type: latheRecipe + id: FemtoManipulatorStockPart + result: FemtoManipulatorStockPart + completetime: 3 + materials: + Plastic: 100 + Gold: 50 + Plasma: 50 + Bluespace: 100 + +- type: latheRecipe + id: BluespaceMatterBinStockPart + result: BluespaceMatterBinStockPart + completetime: 3 + materials: + Plastic: 100 + Gold: 50 + Plasma: 50 + Bluespace: 100 diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml new file mode 100644 index 00000000000..c7ca6a40ae6 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/security.yml @@ -0,0 +1,18 @@ +- type: latheRecipe + id: ClothingHeadCage + icon: + sprite: Nyanotrasen/Clothing/Head/Hats/cage.rsi + state: icon + result: ClothingHeadCage + completetime: 4 + materials: + Steel: 400 + Bluespace: 20 + +- type: latheRecipe + id: ClothingHeadHelmetInsulated + result: ClothingHeadHelmetInsulated + completetime: 4 + materials: + Steel: 400 + Bluespace: 20 diff --git a/Resources/Prototypes/Nyanotrasen/Research/experimental.yml b/Resources/Prototypes/Nyanotrasen/Research/experimental.yml new file mode 100644 index 00000000000..262b24067d5 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Research/experimental.yml @@ -0,0 +1,31 @@ +# Tier 2 + +- type: technology + id: PsionicCountermeasures + name: research-technology-psionic-countermeasures + icon: + sprite: Nyanotrasen/Clothing/Head/Helmets/insulative_skullcap.rsi # DeltaV - Change the icon to the insulative skullcap + state: icon + discipline: Experimental + tier: 2 + cost: 7500 + recipeUnlocks: + - ClothingHeadHelmetInsulated + - ClothingHeadCage + # - ShellSoulbreaker + +# Tier 3 + +# - type: technology +# id: Teleportation +# name: research-technology-teleportation +# icon: +# sprite: Nyanotrasen/Objects/Devices/QSI.rsi +# state: icon +# discipline: Experimental +# tier: 3 +# cost: 15000 +# recipeUnlocks: +# - CoreSilver +# - HandTeleporter +# - QSI diff --git a/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml b/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml new file mode 100644 index 00000000000..077632458b4 --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml @@ -0,0 +1,41 @@ +- type: job + id: ForensicMantis + name: job-name-mantis + description: job-description-mantis + playTimeTracker: JobForensicMantis + requirements: + - !type:OverallPlaytimeRequirement + time: 18000 + - !type:DepartmentTimeRequirement + department: Science + time: 3600 + startingGear: ForensicMantisGear + icon: "JobIconForensicMantis" + supervisors: job-supervisors-rd + antagAdvantage: 5 # DeltaV - From 4 to 5 + canBeAntag: true # DeltaV - Mantis is no longer a Detective + # whitelistRequired: true + access: + - Research + - Maintenance + # special: + # - !type:AddComponentSpecial + # components: + # - type: Psionic + # - type: MetapsionicPower + +- type: startingGear + id: ForensicMantisGear + equipment: + jumpsuit: ClothingUniformJumpsuitMantis + back: ClothingBackpackMantisFilled + shoes: ClothingShoesBootsMantis + head: ClothingHeadHatFezMantis + id: ForensicMantisPDA + eyes: ClothingEyesGlassesSunglasses + ears: ClothingHeadsetScience # DeltaV - Mantis is part of Epistemics + gloves: ClothingHandsGlovesColorWhite + outerClothing: ClothingOuterCoatMantis + belt: ClothingBeltMantis + # pocket2: ForensicScanner # DeltaV - Mantis is no longer a Detective + innerclothingskirt: ClothingUniformSkirtMantis diff --git a/Resources/Prototypes/Nyanotrasen/Roles/play_time_trackers.yml b/Resources/Prototypes/Nyanotrasen/Roles/play_time_trackers.yml index f0767906192..d3dfec1383e 100644 --- a/Resources/Prototypes/Nyanotrasen/Roles/play_time_trackers.yml +++ b/Resources/Prototypes/Nyanotrasen/Roles/play_time_trackers.yml @@ -12,3 +12,6 @@ - type: playTimeTracker id: JobPrisonGuard + +- type: playTimeTracker + id: JobForensicMantis diff --git a/Resources/Prototypes/Nyanotrasen/Stacks/materials.yml b/Resources/Prototypes/Nyanotrasen/Stacks/materials.yml new file mode 100644 index 00000000000..e8c1b98b93a --- /dev/null +++ b/Resources/Prototypes/Nyanotrasen/Stacks/materials.yml @@ -0,0 +1,7 @@ +- type: stack + id: Bluespace + name: bluespace + icon: { sprite: Nyanotrasen/Objects/Materials/materials.rsi, state: bluespace } + spawn: MaterialBluespace + maxCount: 5 + itemSize: 1 diff --git a/Resources/Prototypes/Nyanotrasen/StatusEffects/job.yml b/Resources/Prototypes/Nyanotrasen/StatusEffects/job.yml index 105c27590ab..64a597d590e 100644 --- a/Resources/Prototypes/Nyanotrasen/StatusEffects/job.yml +++ b/Resources/Prototypes/Nyanotrasen/StatusEffects/job.yml @@ -11,7 +11,7 @@ icon: sprite: DeltaV/Interface/Misc/job_icons.rsi state: nyanoPrisonGuard - + - type: statusIcon parent: JobIcon id: JobIconMailCarrier @@ -25,3 +25,10 @@ icon: sprite: DeltaV/Interface/Misc/job_icons.rsi state: nyanoMartialArtist + +- type: statusIcon + parent: JobIcon + id: JobIconForensicMantis + icon: + sprite: DeltaV/Interface/Misc/job_icons.rsi + state: nyanoMantis diff --git a/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml b/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml index b67a52079df..bc59cbb1d63 100644 --- a/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml +++ b/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml @@ -45,6 +45,7 @@ MailVagueThreat: 0.4 # This is mainly for Glacier. MailWinterCoat: 1.5 + MailBooksAll: 0.5 # DeltaV - All the other books not in MailBooks, see Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml # Department and job-specific mail can have slightly higher weights, # since they'll be merged with the everyone pool. @@ -68,9 +69,9 @@ MailSecurityFlashlight: 2 MailSecurityNonlethalsKit: 2 #MailSecuritySpaceLaw: 1 - Epistemology: + Science: # DeltaV - Epistemics Department replacing Science but keeping their IDs MailBooks: 1 - # MailEpistemologyBluespace: 1 + MailEpistemologyBluespace: 1 MailEpistemologyIngotGold: 2 MailEpistemologyResearchDisk: 1 MailEpistemologyTinfoilHat: 1 @@ -95,8 +96,8 @@ Clown: MailClownGildedBikeHorn: 0.5 MailClownHonkSupplement: 3 - ForensicMantis: - MailForensicMantisForensicSupplement: 2 + Detective: # Deltav - Detective is in charge of investigating crimes. + MailDetectiveForensicSupplement: 2 # Deltav - Detective is in charge of investigating crimes. HeadOfPersonnel: MailHoPBureaucracy: 2 MailHoPSupplement: 3 @@ -108,7 +109,7 @@ MailMimeArtsCrafts: 3 MailMimeBlankBook: 2 MailMimeBottleOfNothing: 1 - Mystagogue: + ResearchDirector: # DeltaV - Epistemics Department replacing Science but keeping their IDs MailEpistemologyIngotGold: 2 Musician: MailMusicianInstrumentSmall: 1 diff --git a/Resources/Prototypes/Nyanotrasen/tags.yml b/Resources/Prototypes/Nyanotrasen/tags.yml index 6ffc5454d86..97360dc9c5a 100644 --- a/Resources/Prototypes/Nyanotrasen/tags.yml +++ b/Resources/Prototypes/Nyanotrasen/tags.yml @@ -3,3 +3,6 @@ - type: Tag id: MagazineUniversalCaselessRifle + +- type: Tag + id: BluespaceCrystal diff --git a/Resources/Prototypes/Objectives/dragon.yml b/Resources/Prototypes/Objectives/dragon.yml new file mode 100644 index 00000000000..2cf7eb292f7 --- /dev/null +++ b/Resources/Prototypes/Objectives/dragon.yml @@ -0,0 +1,42 @@ +- type: entity + abstract: true + parent: BaseObjective + id: BaseDragonObjective + components: + - type: Objective + # difficulty isn't used at all since objective are fixed + difficulty: 1.5 + issuer: dragon + - type: RoleRequirement + roles: + components: + - DragonRole + +- type: entity + noSpawn: true + parent: BaseDragonObjective + id: CarpRiftsObjective + components: + - type: Objective + icon: + sprite: Structures/Specific/carp_rift.rsi + state: icon_blue + - type: NumberObjective + # dragon can only spawn 3 rifts so keep objective the same + min: 3 + max: 3 + title: objective-carp-rifts-title + description: objective-carp-rifts-description + - type: CarpRiftsCondition + +- type: entity + noSpawn: true + parent: [BaseDragonObjective, BaseSurviveObjective] + id: DragonSurviveObjective + name: Survive + description: You have to stay alive to maintain control. + components: + - type: Objective + icon: + sprite: Mobs/Aliens/Carps/dragon.rsi + state: alive diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index cf77e37da4f..f6432f81932 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -16,6 +16,7 @@ NukeDiskStealObjective: 1 MagbootsStealObjective: 1 # CorgiMeatStealObjective: 1 # DeltaV - Disable the horrible murder of Ian as an objective + MantisKnifeStealObjective: 1 # Nyanotrasen - ForensicMantis steal objective, see Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml CaptainGunStealObjective: 0.5 CaptainJetpackStealObjective: 0.5 HandTeleporterStealObjective: 0.5 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/food/steak.yml b/Resources/Prototypes/Recipes/Construction/Graphs/food/steak.yml index 76159ec5ac4..74854084f53 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/food/steak.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/food/steak.yml @@ -117,3 +117,16 @@ - node: goliath steak entity: FoodMeatGoliathCooked + +# rouny steak +- type: constructionGraph + id: RounySteak + start: start + graph: + - node: start + edges: + - to: rouny steak + steps: + - minTemperature: 445 #rouny + - node: rouny steak + entity: FoodMeatRounyCooked diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml b/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml index c0736c4973e..6bbbd4f2fff 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml @@ -124,6 +124,8 @@ entity: !type:BoardNodeEntity { container: board } edges: - to: monitorUnsecured + conditions: + - !type:AllWiresCut {} steps: - tool: Screwing diff --git a/Resources/Prototypes/Recipes/Lathes/chemistry.yml b/Resources/Prototypes/Recipes/Lathes/chemistry.yml index 959c8e30a0f..f82d66ec156 100644 --- a/Resources/Prototypes/Recipes/Lathes/chemistry.yml +++ b/Resources/Prototypes/Recipes/Lathes/chemistry.yml @@ -71,16 +71,16 @@ materials: Glass: 50 -- type: latheRecipe - id: Vape - icon: - sprite: Objects/Consumable/Smokeables/Vapes/vape-standart.rsi - state: icon - result: Vape - completetime: 2 - materials: - Plastic: 100 - Steel: 250 +# - type: latheRecipe # DeltaV - Disable the Vape +# id: Vape +# icon: +# sprite: Objects/Consumable/Smokeables/Vapes/vape-standart.rsi +# state: icon +# result: Vape +# completetime: 2 +# materials: +# Plastic: 100 +# Steel: 250 - type: latheRecipe id: ClothingEyesGlassesChemical diff --git a/Resources/Prototypes/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Recipes/Lathes/clothing.yml index fea18760b76..328b557460b 100644 --- a/Resources/Prototypes/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/clothing.yml @@ -552,6 +552,15 @@ Cloth: 150 Durathread: 150 +- type: latheRecipe + id: ClothingNeckMantleQM + result: ClothingNeckMantleQM + completetime: 2.8 + materials: + Cloth: 150 + Durathread: 150 + + - type: latheRecipe id: ClothingOuterWinterMusician result: ClothingOuterWinterMusician diff --git a/Resources/Prototypes/Recipes/Lathes/devices.yml b/Resources/Prototypes/Recipes/Lathes/devices.yml index de79b975133..ed73dc1b644 100644 --- a/Resources/Prototypes/Recipes/Lathes/devices.yml +++ b/Resources/Prototypes/Recipes/Lathes/devices.yml @@ -68,6 +68,14 @@ Steel: 400 Glass: 100 +- type: latheRecipe + id: AnomalyLocatorWide + result: AnomalyLocatorWideEmpty + completetime: 3 + materials: + Steel: 400 + Glass: 100 + - type: latheRecipe id: AnomalyScanner result: AnomalyScanner diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml index 5d0d2cef84f..3cdc19de16a 100644 --- a/Resources/Prototypes/Research/arsenal.yml +++ b/Resources/Prototypes/Research/arsenal.yml @@ -76,10 +76,12 @@ recipeUnlocks: - ShellShotgunBeanbag - CartridgePistolRubber + - CartridgeSpecialRubber # DeltaV - .38 Special revolver - CartridgeMagnumRubber - CartridgeLightRifleRubber - CartridgeRifleRubber - MagazineBoxPistolRubber + - MagazineBoxSpecialRubber # DeltaV - .38 Special revolver - MagazineBoxMagnumRubber - MagazineBoxLightRifleRubber - MagazineBoxRifleRubber diff --git a/Resources/Prototypes/Research/experimental.yml b/Resources/Prototypes/Research/experimental.yml index c1730bb15ea..02d66c06bf7 100644 --- a/Resources/Prototypes/Research/experimental.yml +++ b/Resources/Prototypes/Research/experimental.yml @@ -26,6 +26,7 @@ recipeUnlocks: - AnomalyScanner - AnomalyLocator + - AnomalyLocatorWide - BorgModuleAnomaly - APECircuitboard - AnomalyVesselCircuitboard diff --git a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml index 03597dc64e9..c8c17445752 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml @@ -151,7 +151,7 @@ eyes: ClothingEyesHudMedical ears: ClothingHeadsetAltSyndicate gloves: ClothingHandsGlovesCombat - outerClothing: ClothingOuterHardsuitSyndieElite + outerClothing: ClothingOuterHardsuitMedic shoes: ClothingShoesBootsMagSyndie id: SyndiPDA pocket1: DoubleEmergencyOxygenTankFilled @@ -282,7 +282,7 @@ head: ClothingHeadHatTophat ears: ClothingHeadsetService jumpsuit: ClothingUniformJumpsuitJacketMonkey - id: BartenderIDCard + id: PunPunIDCard # Passenger but without the ID, bag, or headset diff --git a/Resources/Prototypes/Roles/Jobs/departments.yml b/Resources/Prototypes/Roles/Jobs/departments.yml index db2fde72bf3..3703fb87eb9 100644 --- a/Resources/Prototypes/Roles/Jobs/departments.yml +++ b/Resources/Prototypes/Roles/Jobs/departments.yml @@ -95,6 +95,7 @@ - Scientist - ResearchAssistant - Chaplain # DeltaV - Move Chaplain into Epistemics + - ForensicMantis # Nyanotrasen - ForensicMantis, see Resources/Prototypes/Nyanotrasen/Roles/Jobs/Epistemics/forensicmantis.yml - type: department id: Specific diff --git a/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml new file mode 100644 index 00000000000..f321ec26e2f --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/Traits/disabilities.yml @@ -0,0 +1,8 @@ +- type: trait + id: Nearsighted + name: trait-nearsighted-name + description: You require glasses to see properly. + traitGear: ClothingEyesGlasses + components: + - type: Nearsighted + diff --git a/Resources/Prototypes/SimpleStation14/benches.yml b/Resources/Prototypes/SimpleStation14/benches.yml new file mode 100644 index 00000000000..aa939c8fae1 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/benches.yml @@ -0,0 +1,257 @@ +# Base benches +- type: entity + name: bench + id: BenchBaseMiddle + suffix: Middle + abstract: true + parent: SeatBase + description: Multiple seats spanning a single object. Truly a marvel of science. + components: + - type: Transform + anchored: true + - type: Rotatable + - type: Sprite + state: middle + +# Park benches +- type: entity + name: park bench + id: BenchParkMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi + +- type: entity + id: BenchParkLeft + suffix: Left + parent: BenchParkMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchParkRight + suffix: Right + parent: BenchParkMiddle + components: + - type: Sprite + state: right + +# Bamboo benches +- type: entity + name: park bench + id: BenchParkBambooMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi + +- type: entity + id: BenchParkBambooLeft + suffix: Left + parent: BenchParkBambooMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchParkBambooRight + suffix: Right + parent: BenchParkBambooMiddle + components: + - type: Sprite + state: right + +# Pews +- type: entity + name: pew + id: BenchPewMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/pews.rsi + +- type: entity + id: BenchPewLeft + suffix: Left + parent: BenchPewMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchPewRight + suffix: Right + parent: BenchPewMiddle + components: + - type: Sprite + state: right + +# Steel benches +- type: entity + name: steel bench + id: BenchSteelMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi + +- type: entity + id: BenchSteelLeft + suffix: Left + parent: BenchSteelMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchSteelRight + suffix: Right + parent: BenchSteelMiddle + components: + - type: Sprite + state: right + +# White steel benches +- type: entity + name: white steel bench + id: BenchSteelWhiteMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi + +- type: entity + id: BenchSteelWhiteLeft + suffix: Left + parent: BenchSteelWhiteMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchSteelWhiteRight + suffix: Right + parent: BenchSteelWhiteMiddle + components: + - type: Sprite + state: right + +# Standard sofa +- type: entity + name: sofa + id: BenchSofaMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/sofa.rsi + +- type: entity + id: BenchSofaLeft + suffix: Left + parent: BenchSofaMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchSofaRight + suffix: Right + parent: BenchSofaMiddle + components: + - type: Sprite + state: right + +- type: entity + name: sofa + id: BenchSofaCorner + suffix: Corner +# parent: BenchSofaMiddle + placement: + mode: SnapgridCenter + components: + - type: Transform + anchored: true + - type: Rotatable + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/sofa.rsi + state: corner + - type: Clickable + - type: InteractionOutline + - type: Physics + bodyType: Dynamic + - type: Pullable + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/metalbreak.ogg + +# Corp sofa +- type: entity + name: grey sofa + id: BenchSofaCorpMiddle + parent: BenchBaseMiddle + components: + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi + +- type: entity + id: BenchSofaCorpLeft + suffix: Left + parent: BenchSofaCorpMiddle + components: + - type: Sprite + state: left + +- type: entity + id: BenchSofaCorpRight + suffix: Right + parent: BenchSofaCorpMiddle + components: + - type: Sprite + state: right + +- type: entity + name: grey sofa + id: BenchSofaCorpCorner + suffix: Corner +# parent: BenchSofaCorpMiddle + placement: + mode: SnapgridCenter + components: + - type: Transform + anchored: true + - type: Rotatable + - type: Sprite + sprite: SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi + state: corner + - type: Clickable + - type: InteractionOutline + - type: Physics + bodyType: Dynamic + - type: Pullable + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/metalbreak.ogg diff --git a/Resources/Prototypes/SimpleStation14/tags.yml b/Resources/Prototypes/SimpleStation14/tags.yml new file mode 100644 index 00000000000..3b885a58016 --- /dev/null +++ b/Resources/Prototypes/SimpleStation14/tags.yml @@ -0,0 +1,2 @@ +- type: Tag + id: GlassesNearsight diff --git a/Resources/Prototypes/lobbyscreens.yml b/Resources/Prototypes/lobbyscreens.yml index 37bf53344d6..3700a0a94ac 100644 --- a/Resources/Prototypes/lobbyscreens.yml +++ b/Resources/Prototypes/lobbyscreens.yml @@ -16,4 +16,8 @@ - type: lobbyBackground id: Oracle - background: /Textures/LobbyScreens/oracle.png \ No newline at end of file + background: /Textures/LobbyScreens/oracle.png + +- type: lobbyBackground + id: aBadShift + background: /Textures/LobbyScreens/aBadShift.png diff --git a/Resources/Prototypes/threats.yml b/Resources/Prototypes/threats.yml index 6e21cc1037d..cb20ce19d97 100644 --- a/Resources/Prototypes/threats.yml +++ b/Resources/Prototypes/threats.yml @@ -5,12 +5,12 @@ Dragon: 1 Revenant: 1 -- type: threat +- type: ninjaHackingThreat id: Dragon announcement: terror-dragon rule: Dragon -- type: threat +- type: ninjaHackingThreat id: Revenant announcement: terror-revenant rule: RevenantSpawn diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon-flash.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon-flash.png new file mode 100644 index 00000000000..6d63fa871b4 Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon-flash.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon.png new file mode 100644 index 00000000000..6b2df0e84fd Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/meta.json b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/meta.json new file mode 100644 index 00000000000..b69addc4760 --- /dev/null +++ b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Based on tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e, modified by EmoGarbage404 (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "icon-flash" + }, + { + "name": "off-equipped-HELMET", + "directions": 4 + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-equipped-HELMET", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-equipped-HELMET.png new file mode 100644 index 00000000000..37d8a092d9c Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-equipped-HELMET.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-left.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-left.png new file mode 100644 index 00000000000..97f21fd350b Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-left.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-right.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-right.png new file mode 100644 index 00000000000..0e950a6674a Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/off-inhand-right.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-equipped-HELMET.png new file mode 100644 index 00000000000..44443b7755b Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-equipped-HELMET.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-left.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-left.png new file mode 100644 index 00000000000..0e174c04c33 Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-left.png differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-right.png b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-right.png new file mode 100644 index 00000000000..b0494003486 Binary files /dev/null and b/Resources/Textures/Clothing/Head/Hardsuits/syndiemedic.rsi/on-inhand-right.png differ diff --git a/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/equipped-NECK.png b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/equipped-NECK.png new file mode 100644 index 00000000000..96e25143001 Binary files /dev/null and b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/equipped-NECK.png differ diff --git a/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/icon.png b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/icon.png new file mode 100644 index 00000000000..addab15d615 Binary files /dev/null and b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/meta.json b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/meta.json new file mode 100644 index 00000000000..1b05cf9b674 --- /dev/null +++ b/Resources/Textures/Clothing/Neck/mantles/qmmantle.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "drawn by Ubaser", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-NECK", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 00000000000..2fc4a8bc9d0 Binary files /dev/null and b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/icon.png b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/icon.png new file mode 100644 index 00000000000..8f2ed21fe50 Binary files /dev/null and b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-left.png b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-left.png new file mode 100644 index 00000000000..6fdf0f3318a Binary files /dev/null and b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-left.png differ diff --git a/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-right.png b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-right.png new file mode 100644 index 00000000000..0e6f5a83c86 Binary files /dev/null and b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/inhand-right.png differ diff --git a/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/meta.json b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/meta.json new file mode 100644 index 00000000000..373d282410c --- /dev/null +++ b/Resources/Textures/Clothing/OuterClothing/Hardsuits/syndiemedic.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Based on tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e, modified by EmoGarbage404 (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/equipped-FEET.png b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/equipped-FEET.png new file mode 100644 index 00000000000..6e8c884f33a Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/equipped-FEET.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/icon.png b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/icon.png new file mode 100644 index 00000000000..0fcb05940bf Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/icon.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-left.png b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-left.png new file mode 100644 index 00000000000..2b4754255ad Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-left.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-right.png b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-right.png new file mode 100644 index 00000000000..467a79e9fa9 Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/inhand-right.png differ diff --git a/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/meta.json b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/meta.json new file mode 100644 index 00000000000..e484bbb13af --- /dev/null +++ b/Resources/Textures/Clothing/Shoes/Boots/winterboots.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "drawn by Ubaser", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-FEET", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/equipped-INNERCLOTHING.png index 475c96e522e..4b5753f7925 100644 Binary files a/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/equipped-INNERCLOTHING.png and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/equipped-INNERCLOTHING.png differ diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/meta.json index 37207b882f8..b02e5f4b8a6 100644 --- a/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/meta.json +++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/bartender.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039, monkey made by brainfood1183 (github), monkey made by brainfood1183 (github) for ss14", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039, monkey made by brainfood1183 (github), monkey made by brainfood1183 (github) for ss14, default suit edit by Skarletto (github)", "size": { "x": 32, "y": 32 diff --git a/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/meta.json b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/meta.json index 8dd9e5b3d0d..af8fd25b2e7 100644 --- a/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/meta.json +++ b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/meta.json @@ -21,6 +21,9 @@ }, { "name": "nyanoMartialArtist" + }, + { + "name": "nyanoMantis" } ] } diff --git a/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/nyanoMantis.png b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/nyanoMantis.png new file mode 100644 index 00000000000..3406d5d0ca1 Binary files /dev/null and b/Resources/Textures/DeltaV/Interface/Misc/job_icons.rsi/nyanoMantis.png differ diff --git a/Resources/Textures/DeltaV/Markers/jobs.rsi/meta.json b/Resources/Textures/DeltaV/Markers/jobs.rsi/meta.json index 4b52c0c4dba..c85f82772b4 100644 --- a/Resources/Textures/DeltaV/Markers/jobs.rsi/meta.json +++ b/Resources/Textures/DeltaV/Markers/jobs.rsi/meta.json @@ -24,6 +24,9 @@ }, { "name": "nyanomartialartist" + }, + { + "name": "nyanomantis" } ] } diff --git a/Resources/Textures/DeltaV/Markers/jobs.rsi/nyanomantis.png b/Resources/Textures/DeltaV/Markers/jobs.rsi/nyanomantis.png new file mode 100644 index 00000000000..2eec6024156 Binary files /dev/null and b/Resources/Textures/DeltaV/Markers/jobs.rsi/nyanomantis.png differ diff --git a/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/meta.json index 142839f0c5b..b5937ff0ced 100644 --- a/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/meta.json +++ b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/59f2a4e10e5ba36033c9734ddebfbbdc6157472d", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/59f2a4e10e5ba36033c9734ddebfbbdc6157472d, pda-martialartist by Floofers", "size": { "x": 32, "y": 32 @@ -25,6 +25,9 @@ }, { "name": "pda-chaplain" + }, + { + "name": "pda-martialartist" } ] } diff --git a/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-martialartist.png b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-martialartist.png new file mode 100644 index 00000000000..74ca7cbce8b Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Devices/pda.rsi/pda-martialartist.png differ diff --git a/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/meta.json index 5c43fa4f9d6..521c6e58fa7 100644 --- a/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/meta.json +++ b/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/meta.json @@ -24,6 +24,9 @@ }, { "name": "nyanomartialartist" + }, + { + "name": "nyanomantis" } ] } diff --git a/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/nyanomantis.png b/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/nyanomantis.png new file mode 100644 index 00000000000..f80e175ec33 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Misc/id_cards.rsi/nyanomantis.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/base.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/base.png new file mode 100644 index 00000000000..2380a277fa4 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/base.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/mag-1.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/mag-1.png new file mode 100644 index 00000000000..43833995197 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/mag-1.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/meta.json new file mode 100644 index 00000000000..d50b99b0a23 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/raw/89456d18dd3e7c330839121e3c6bc8c609700137/icons/obj/ammo.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "base" + }, + { + "name": "mag-1" + }, + { + "name": "practice" + }, + { + "name": "rubber" + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/practice.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/practice.png new file mode 100644 index 00000000000..f45782a6d14 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/practice.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/rubber.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/rubber.png new file mode 100644 index 00000000000..8da8a2f937c Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/Boxes/special.rsi/rubber.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-1.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-1.png new file mode 100644 index 00000000000..67c3ddd4b8f Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-1.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-2.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-2.png new file mode 100644 index 00000000000..2d7bae76be1 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-2.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-3.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-3.png new file mode 100644 index 00000000000..f516e824d35 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-3.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-4.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-4.png new file mode 100644 index 00000000000..310afbdb96d Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-4.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-5.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-5.png new file mode 100644 index 00000000000..9e024d7b9dc Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-5.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-6.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-6.png new file mode 100644 index 00000000000..174c21f8af6 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base-6.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base.png new file mode 100644 index 00000000000..dd46aa81038 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/base.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-1.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-1.png new file mode 100644 index 00000000000..63bf305bbc5 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-1.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-2.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-2.png new file mode 100644 index 00000000000..b0adec9bc6f Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-2.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-3.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-3.png new file mode 100644 index 00000000000..b4a7c390c29 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-3.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-4.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-4.png new file mode 100644 index 00000000000..f2b8fa50d61 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-4.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-5.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-5.png new file mode 100644 index 00000000000..1138054fd00 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-5.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-6.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-6.png new file mode 100644 index 00000000000..89bfca7f6dd Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/high-velocity-6.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/meta.json new file mode 100644 index 00000000000..dbecaae60b9 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/meta.json @@ -0,0 +1,86 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/discordia-space/CEV-Eris/raw/aed9cbddbf9039dae1e4f02bab592248b0539431/icons/obj/ammo_speed.dmi", + "states": [ + { + "name": "base" + }, + { + "name": "base-1" + }, + { + "name": "base-2" + }, + { + "name": "base-3" + }, + { + "name": "base-4" + }, + { + "name": "base-5" + }, + { + "name": "base-6" + }, + { + "name": "high-velocity-1" + }, + { + "name": "high-velocity-2" + }, + { + "name": "high-velocity-3" + }, + { + "name": "high-velocity-4" + }, + { + "name": "high-velocity-5" + }, + { + "name": "high-velocity-6" + }, + { + "name": "practice-1" + }, + { + "name": "practice-2" + }, + { + "name": "practice-3" + }, + { + "name": "practice-4" + }, + { + "name": "practice-5" + }, + { + "name": "practice-6" + }, + { + "name": "rubber-1" + }, + { + "name": "rubber-2" + }, + { + "name": "rubber-3" + }, + { + "name": "rubber-4" + }, + { + "name": "rubber-5" + }, + { + "name": "rubber-6" + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-1.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-1.png new file mode 100644 index 00000000000..7cea456b83a Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-1.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-2.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-2.png new file mode 100644 index 00000000000..95258e57a55 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-2.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-3.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-3.png new file mode 100644 index 00000000000..2df8d04d138 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-3.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-4.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-4.png new file mode 100644 index 00000000000..6288b36718d Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-4.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-5.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-5.png new file mode 100644 index 00000000000..6f294593ff6 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-5.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-6.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-6.png new file mode 100644 index 00000000000..f3329b1114b Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/practice-6.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-1.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-1.png new file mode 100644 index 00000000000..a55a20f4403 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-1.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-2.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-2.png new file mode 100644 index 00000000000..eeee78f6fe7 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-2.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-3.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-3.png new file mode 100644 index 00000000000..85fd3c747c5 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-3.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-4.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-4.png new file mode 100644 index 00000000000..baccd8fc23f Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-4.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-5.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-5.png new file mode 100644 index 00000000000..53183ac0234 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-5.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-6.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-6.png new file mode 100644 index 00000000000..3bd88af36b4 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Special/special_speed_loader.rsi/rubber-6.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/equipped-BELT.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/equipped-BELT.png new file mode 100644 index 00000000000..a025c457ab1 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/icon.png new file mode 100644 index 00000000000..a9f3b2a08ad Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/icon.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-left.png new file mode 100644 index 00000000000..51f59ed1efa Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-left.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-right.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-right.png new file mode 100644 index 00000000000..113b83b08cc Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/inhand-right.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/meta.json new file mode 100644 index 00000000000..49689890f11 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/faith.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken and modified from https://github.com/BeeStation/BeeStation-Hornet/commit/063d95caba064383fb069190487e633d6c0bc556", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BELT", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/equipped-BELT.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/equipped-BELT.png new file mode 100644 index 00000000000..13cea8c3a8b Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/icon.png new file mode 100644 index 00000000000..270499a209e Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/icon.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-left.png new file mode 100644 index 00000000000..a616fd9f013 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-left.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-right.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-right.png new file mode 100644 index 00000000000..053f0597b0e Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/inhand-right.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/meta.json new file mode 100644 index 00000000000..49689890f11 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/fitz.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken and modified from https://github.com/BeeStation/BeeStation-Hornet/commit/063d95caba064383fb069190487e633d6c0bc556", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BELT", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/equipped-BELT.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/equipped-BELT.png new file mode 100644 index 00000000000..4ed02781890 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/icon.png new file mode 100644 index 00000000000..a25350ddde7 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/icon.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-left.png new file mode 100644 index 00000000000..e3d991bcf76 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-left.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-right.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-right.png new file mode 100644 index 00000000000..401ec45de88 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/inhand-right.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/meta.json new file mode 100644 index 00000000000..1939b175256 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/k38master.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken and modified from https://github.com/space-wizards/space-station-14/commit/7eec71dcfc25ff907e62a72e0f50c79a173f97fb", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BELT", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/equipped-BELT.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/equipped-BELT.png new file mode 100644 index 00000000000..ee0d41747a5 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/equipped-BELT.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/icon.png new file mode 100644 index 00000000000..a294055c674 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/icon.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-left.png new file mode 100644 index 00000000000..bbd805c4847 Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-left.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-right.png b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-right.png new file mode 100644 index 00000000000..ba722898dfc Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/inhand-right.png differ diff --git a/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/meta.json new file mode 100644 index 00000000000..1939b175256 --- /dev/null +++ b/Resources/Textures/DeltaV/Objects/Weapons/Guns/Revolvers/lucky.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken and modified from https://github.com/space-wizards/space-station-14/commit/7eec71dcfc25ff907e62a72e0f50c79a173f97fb", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BELT", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/DeltaV/Shaders/hologram.swsl b/Resources/Textures/DeltaV/Shaders/hologram.swsl new file mode 100644 index 00000000000..63c06fea692 --- /dev/null +++ b/Resources/Textures/DeltaV/Shaders/hologram.swsl @@ -0,0 +1,267 @@ +light_mode unshaded; + +uniform highp float hue; +uniform highp float textureHeight; + +// +// Description : Array and textureless GLSL 2D/3D/4D simplex +// noise functions. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : stegu +// Lastmod : 20201014 (stegu) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// https://github.com/stegu/webgl-noise +// + +highp vec3 mod289(highp vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +highp vec4 mod289(highp vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +highp vec4 permute(highp vec4 x) { + return mod289(((x*34.0)+10.0)*x); +} + +highp vec4 taylorInvSqrt(highp vec4 r) +{ + return 1.79284291400159 - 0.85373472095314 * r; +} + +highp float snoise(highp vec3 v) + { + const highp vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const highp vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + +// First corner + highp vec3 i = floor(v + dot(v, C.yyy) ); + highp vec3 x0 = v - i + dot(i, C.xxx) ; + +// Other corners + highp vec3 g = step(x0.yzx, x0.xyz); + highp vec3 l = 1.0 - g; + highp vec3 i1 = min( g.xyz, l.zxy ); + highp vec3 i2 = max( g.xyz, l.zxy ); + + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + highp vec3 x1 = x0 - i1 + C.xxx; + highp vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y + highp vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y + +// Permutations + i = mod289(i); + highp vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + +// Gradients: 7x7 points over a square, mapped onto an octahedron. +// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + highp float n_ = 0.142857142857; // 1.0/7.0 + highp vec3 ns = n_ * D.wyz - D.xzx; + + highp vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) + + highp vec4 x_ = floor(j * ns.z); + highp vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + highp vec4 x = x_ *ns.x + ns.yyyy; + highp vec4 y = y_ *ns.x + ns.yyyy; + highp vec4 h = 1.0 - abs(x) - abs(y); + + highp vec4 b0 = vec4( x.xy, y.xy ); + highp vec4 b1 = vec4( x.zw, y.zw ); + + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + highp vec4 s0 = floor(b0)*2.0 + 1.0; + highp vec4 s1 = floor(b1)*2.0 + 1.0; + highp vec4 sh = -step(h, vec4(0.0)); + + highp vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + highp vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + highp vec3 p0 = vec3(a0.xy,h.x); + highp vec3 p1 = vec3(a0.zw,h.y); + highp vec3 p2 = vec3(a1.xy,h.z); + highp vec3 p3 = vec3(a1.zw,h.w); + +//Normalise gradients + highp vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + +// Mix final noise value + highp vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); + } + + +// +// https://github.com/jamieowen/glsl-blend +// +// The MIT License (MIT) Copyright (c) 2015 Jamie Owen +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +highp float blendOverlay(highp float base, highp float blend) { + return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend)); +} + +highp vec3 blendOverlay(highp vec3 base, highp vec3 blend) { + return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b)); +} + +highp vec3 blendOverlay(highp vec3 base, highp vec3 blend, highp float opacity) { + return (blendOverlay(base, blend) * opacity + base * (1.0 - opacity)); +} + +highp float blendLinearDodge(highp float base, highp float blend) { + // Note : Same implementation as BlendAddf + return min(base+blend,1.0); +} + +highp vec3 blendLinearDodge(highp vec3 base, highp vec3 blend) { + // Note : Same implementation as BlendAdd + return min(base+blend,vec3(1.0)); +} + +highp vec3 blendLinearDodge(highp vec3 base, highp vec3 blend, highp float opacity) { + return (blendLinearDodge(base, blend) * opacity + base * (1.0 - opacity)); +} + +highp float blendScreen(highp float base, highp float blend) { + return 1.0-((1.0-base)*(1.0-blend)); +} + +highp vec3 blendScreen(highp vec3 base, highp vec3 blend) { + return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b)); +} + +highp vec3 blendScreen(highp vec3 base, highp vec3 blend, highp float opacity) { + return (blendScreen(base, blend) * opacity + base * (1.0 - opacity)); +} + + +// +// https://gamedev.stackexchange.com/a/59808 +// +// Author: sam hocevar +// Answered: Jul 27, 2013 at 13:33 +// License: CC BY-SA 3.0 +// + +highp vec3 rgb2hsv(highp vec3 c) +{ + highp vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + highp vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + highp vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + highp float d = q.x - min(q.w, q.y); + /* float e = 1.0e-10; */ + highp float e = 0.0000000001; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +highp vec3 hsv2rgb(highp vec3 c) +{ + highp vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + highp vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + +// +// Author: @Vordenburg +// License: follows Nyanotrasen/LICENSE.TXT as of this commit. +// + +highp float pingpong(highp float value) +{ + highp float tmp = mod(value, 1.0) * 2.0; + return tmp < 1.0 ? tmp : 2.0 - tmp; +} + +void fragment() +{ + const highp float TIME_OFFSET1 = 138.11; + const highp float TIME_OFFSET2 = 517.43; + const highp float TIME_OFFSET3 = 1298.67; + + highp vec4 product = zTexture(UV); + + // Colorize + highp vec3 hsv = rgb2hsv(product.rgb); + hsv.x = hue; + product.rgb = hsv2rgb(hsv); + + + // Scanlines + const highp float LINE_SCROLL_SPEED = 0.12; + + highp float uv_noise = snoise(vec3(UV * 100.0, TIME)); + highp float Y = UV.y + uv_noise * 0.1; + highp float MX = 4.0; + highp float MY = textureHeight / MX / 4.0; + + highp float lines = + ( + mod(TIME * LINE_SCROLL_SPEED + Y, 1.0 / MX) + ) + * MX + ; + + lines = floor(lines * MY) / MY; + highp vec3 line3 = hsv2rgb(vec3(hue, 0.9, 2.0 * lines)); + + product.xyz = blendScreen(product.xyz, line3, 0.33); + + + // Noise + const highp float noise_scale = 32.0; + const highp float noise_limit = 4.0; + const highp float noise_rate = 1.4; + const highp float noise_density = 0.0; + + highp float noise_hue = hue - 0.2 * pingpong((TIME_OFFSET1 + TIME) * 0.21); + + highp vec2 noise_coord = floor(UV * noise_scale); + highp float noise_result = snoise(vec3(noise_coord, (TIME_OFFSET2 + TIME) * noise_rate)); + + highp vec3 noise3 = hsv2rgb(vec3(noise_hue, 1.0, noise_result)); + product.xyz = blendOverlay(product.xyz, noise3, noise_result < 0.3 ? 0.0 : 0.5); + + + // Alpha + product.w *= 0.9 - 0.4 * pingpong((TIME_OFFSET3 + TIME) * 0.36); + + COLOR = product; +} diff --git a/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png b/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png index cce1b027b61..6c9b54e52e2 100644 Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health0.png differ diff --git a/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png b/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png index 2ec0eb65515..186d07386ec 100644 Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health1.png differ diff --git a/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png b/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png index 4fa9ffeccc3..6463eb386fa 100644 Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health2.png differ diff --git a/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png b/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png index 0daa1136c41..d7b8d559ef3 100644 Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health3.png differ diff --git a/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png b/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png index ea55a429b24..9ae49ead79f 100644 Binary files a/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png and b/Resources/Textures/Interface/Alerts/human_alive.rsi/health4.png differ diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_argali.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_argali.png index f66087be661..1efa87c6aa1 100644 Binary files a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_argali.png and b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_argali.png differ diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_ayrshire.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_ayrshire.png index 0390a1fc690..6c0d0b5b93d 100644 Binary files a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_ayrshire.png and b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_ayrshire.png differ diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_bighorn.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_bighorn.png index 9ecc93c42bb..3a0995654cc 100644 Binary files a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_bighorn.png and b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_bighorn.png differ diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_myrsore.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_myrsore.png index 176a619bad7..e5e5d54c010 100644 Binary files a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_myrsore.png and b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/horns_myrsore.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-left.png b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-left.png new file mode 100644 index 00000000000..a536818eee9 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-left.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-right.png b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-right.png new file mode 100644 index 00000000000..c7e0adca9a1 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-inhand-right.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-slime.png b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-slime.png new file mode 100644 index 00000000000..b2a611f5118 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Slime/organs.rsi/brain-slime.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-l-slime.png b/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-l-slime.png new file mode 100644 index 00000000000..0c4591ed9bf Binary files /dev/null and b/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-l-slime.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-r-slime.png b/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-r-slime.png new file mode 100644 index 00000000000..f27bca82449 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Slime/organs.rsi/lung-r-slime.png differ diff --git a/Resources/Textures/Mobs/Species/Slime/organs.rsi/meta.json b/Resources/Textures/Mobs/Species/Slime/organs.rsi/meta.json new file mode 100644 index 00000000000..cacfcdc40bb --- /dev/null +++ b/Resources/Textures/Mobs/Species/Slime/organs.rsi/meta.json @@ -0,0 +1,28 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Sprited by Nimfar11 (Github) for Space Station 14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "brain-slime" + }, + { + "name": "brain-inhand-left", + "directions": 4 + }, + { + "name": "brain-inhand-right", + "directions": 4 + }, + { + "name": "lung-l-slime" + }, + { + "name": "lung-r-slime" + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace.png b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace.png new file mode 100644 index 00000000000..b8f045aef88 Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace.png differ diff --git a/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_2.png b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_2.png new file mode 100644 index 00000000000..bbd1c1a7d06 Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_2.png differ diff --git a/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_3.png b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_3.png new file mode 100644 index 00000000000..f0460760c28 Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/bluespace_3.png differ diff --git a/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/meta.json b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/meta.json new file mode 100644 index 00000000000..87a4078ff76 --- /dev/null +++ b/Resources/Textures/Nyanotrasen/Objects/Materials/materials.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/f8f4aeda930fcd0805ca4cc76d9bc9412a5b3428", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "bluespace" + }, + { + "name": "bluespace_2" + }, + { + "name": "bluespace_3" + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/meta.json b/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/meta.json new file mode 100644 index 00000000000..15abf83ff59 --- /dev/null +++ b/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from Nyanotrasen at https://github.com/Nyanotrasen/Nyanotrasen/commit/3fd6fff706c3f2f61b6cd52a38e0c998ba5d92ef", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "stamp-mantis" + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/stamp-mantis.png b/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/stamp-mantis.png new file mode 100644 index 00000000000..da5e9597ff1 Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Misc/bureaucracy.rsi/stamp-mantis.png differ diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/closed.png b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/closed.png new file mode 100644 index 00000000000..ceb48191451 Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/closed.png differ diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/meta.json b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/meta.json new file mode 100644 index 00000000000..a5b1af208ec --- /dev/null +++ b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "Hyenh#6078 (313846233099927552)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "open" + }, + { + "name": "closed" + }, + { + "name": "unlit" + } + ] +} diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/open.png b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/open.png new file mode 100644 index 00000000000..a6b2fbdf15c Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/open.png differ diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/unlit.png b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/unlit.png new file mode 100644 index 00000000000..891e9776d5e Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/reverse_engineering.rsi/unlit.png differ diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json index 2bbe89d1f9f..f1aa4d3446d 100644 --- a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json +++ b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation and modified by Swept and potato1234x at https://github.com/tgstation/tgstation/commit/40d75cc340c63582fb66ce15bf75a36115f6bdaa", + "copyright": "Taken from tgstation and modified by Swept, potato1234x and deltanedas at https://github.com/tgstation/tgstation/commit/40d75cc340c63582fb66ce15bf75a36115f6bdaa", "size": { "x": 32, "y": 32 @@ -188,6 +188,12 @@ }, { "name": "dragon_veins" + }, + { + "name": "rouny" + }, + { + "name": "rouny-cooked" } ] } diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny-cooked.png b/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny-cooked.png new file mode 100644 index 00000000000..cba050d693c Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny-cooked.png differ diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny.png b/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny.png new file mode 100644 index 00000000000..bf87e1bef26 Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/meat.rsi/rouny.png differ diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/idbrigmedic.png b/Resources/Textures/Objects/Misc/id_cards.rsi/idbrigmedic.png index a12f705a036..1f64eb4845a 100644 Binary files a/Resources/Textures/Objects/Misc/id_cards.rsi/idbrigmedic.png and b/Resources/Textures/Objects/Misc/id_cards.rsi/idbrigmedic.png differ diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/idsecurityofficer.png b/Resources/Textures/Objects/Misc/id_cards.rsi/idsecurityofficer.png index f0e1562168b..6456d644396 100644 Binary files a/Resources/Textures/Objects/Misc/id_cards.rsi/idsecurityofficer.png and b/Resources/Textures/Objects/Misc/id_cards.rsi/idsecurityofficer.png differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/caution.png b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/caution.png deleted file mode 100644 index fdd5c1d2cbb..00000000000 Binary files a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/caution.png and /dev/null differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 00000000000..96667a706bc Binary files /dev/null and b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/icon.png b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/icon.png new file mode 100644 index 00000000000..204e8b8813f Binary files /dev/null and b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-left.png index aa3d9fc9c14..ed1e8946e7c 100644 Binary files a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-left.png and b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-right.png b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-right.png index 286dec22cd1..355d215fcd7 100644 Binary files a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-right.png and b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/meta.json b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/meta.json index bc202f443a9..75c381313e4 100644 --- a/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Janitorial/wet_floor_sign.rsi/meta.json @@ -1,14 +1,18 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/f8f4aeda930fcd0805ca4cc76d9bc9412a5b3428", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/da42afcbaeaa04e5ba288ade027c011efb3ef0ab, modified by Skarlet and Psychpsyo", "size": { "x": 32, "y": 32 }, "states": [ { - "name": "caution" + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 }, { "name": "inhand-left", diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/icon.png b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/icon.png new file mode 100644 index 00000000000..fe7c1c92276 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-left.png new file mode 100644 index 00000000000..0b7fd844196 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-right.png b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-right.png new file mode 100644 index 00000000000..b32e8514252 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/meta.json b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/meta.json new file mode 100644 index 00000000000..c72c0d8dc40 --- /dev/null +++ b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC0-1.0", + "copyright": "Created by TheShuEd (github) for Space Station 14.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "screen", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/screen.png b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/screen.png new file mode 100644 index 00000000000..cce49dbf743 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocatorwide.rsi/screen.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/left.png new file mode 100644 index 00000000000..8122a89be08 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/meta.json new file mode 100644 index 00000000000..9e46cf47f5e --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGStation at https://github.com/lessthnthree/tgstation/blob/2ca948b578cdb46b60d19e029782483b1218004e/icons/obj/sofa.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/middle.png new file mode 100644 index 00000000000..249972dec8f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/right.png new file mode 100644 index 00000000000..e91037826f8 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_bamboo.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/left.png new file mode 100644 index 00000000000..b2e4e6650bd Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/meta.json new file mode 100644 index 00000000000..9e46cf47f5e --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGStation at https://github.com/lessthnthree/tgstation/blob/2ca948b578cdb46b60d19e029782483b1218004e/icons/obj/sofa.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/middle.png new file mode 100644 index 00000000000..31ba1d8e2dd Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/right.png new file mode 100644 index 00000000000..35965a297e5 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/parkbench_wooden.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_left.png new file mode 100644 index 00000000000..50931020c57 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_right.png new file mode 100644 index 00000000000..6be992bd27f Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/arm_right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/left.png new file mode 100644 index 00000000000..9631b4b1714 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/meta.json new file mode 100644 index 00000000000..4c2c748e3ab --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/meta.json @@ -0,0 +1,31 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGStation at https://github.com/lessthnthree/tgstation/blob/2ca948b578cdb46b60d19e029782483b1218004e/icons/obj/sofa.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + }, + { + "name": "arm_left", + "directions": 4 + }, + { + "name": "arm_right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/middle.png new file mode 100644 index 00000000000..09939795dd1 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/right.png new file mode 100644 index 00000000000..ea0922930fe Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/pews.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_left.png new file mode 100644 index 00000000000..0c5ea7ab8f4 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_right.png new file mode 100644 index 00000000000..8989852c209 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/arm_right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/corner.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/corner.png new file mode 100644 index 00000000000..d18237d23ab Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/corner.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/left.png new file mode 100644 index 00000000000..dd4dd8e8009 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/meta.json new file mode 100644 index 00000000000..94d6013eeb5 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/meta.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "TGStation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + }, + { + "name": "corner", + "directions": 4 + }, + { + "name": "arm_left", + "directions": 4 + }, + { + "name": "arm_right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/middle.png new file mode 100644 index 00000000000..589526aa751 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/right.png new file mode 100644 index 00000000000..fd1d1142702 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_left.png new file mode 100644 index 00000000000..17debb44c06 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_right.png new file mode 100644 index 00000000000..2434e680c15 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/arm_right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/corner.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/corner.png new file mode 100644 index 00000000000..306d354e2ce Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/corner.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/left.png new file mode 100644 index 00000000000..181e9e53de9 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/meta.json new file mode 100644 index 00000000000..ad13615da13 --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/meta.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "TGStation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + }, + { + "name": "corner", + "directions": 4 + }, + { + "name": "arm_left", + "directions": 4 + }, + { + "name": "arm_right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/middle.png new file mode 100644 index 00000000000..b12c5e3a726 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/right.png new file mode 100644 index 00000000000..78abf84955d Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/sofa_corp.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/left.png new file mode 100644 index 00000000000..260c7298f77 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/meta.json new file mode 100644 index 00000000000..9e46cf47f5e --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGStation at https://github.com/lessthnthree/tgstation/blob/2ca948b578cdb46b60d19e029782483b1218004e/icons/obj/sofa.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/middle.png new file mode 100644 index 00000000000..949a1e5cee3 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/right.png new file mode 100644 index 00000000000..b6c1ef00fcb Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench.rsi/right.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/left.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/left.png new file mode 100644 index 00000000000..d456300e104 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/left.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/meta.json b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/meta.json new file mode 100644 index 00000000000..9e46cf47f5e --- /dev/null +++ b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGStation at https://github.com/lessthnthree/tgstation/blob/2ca948b578cdb46b60d19e029782483b1218004e/icons/obj/sofa.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "left", + "directions": 4 + }, + { + "name": "right", + "directions": 4 + }, + { + "name": "middle", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/middle.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/middle.png new file mode 100644 index 00000000000..fcf97d15836 Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/middle.png differ diff --git a/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/right.png b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/right.png new file mode 100644 index 00000000000..a412a51871b Binary files /dev/null and b/Resources/Textures/SimpleStation14/Structures/Furniture/Benches/steel_bench_white.rsi/right.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json index d3d3ce6ba99..14a5a244bf6 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json @@ -52,6 +52,11 @@ "name":"pumpVolumeOn", "directions":4, "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + }, + { + "name":"pumpVolumeBlocked", + "directions":4, + "delays":[ [ 1.0, 1.0 ], [ 1.0, 1.0 ], [ 1.0, 1.0 ], [ 1.0, 1.0 ] ] } ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpVolumeBlocked.png b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpVolumeBlocked.png new file mode 100644 index 00000000000..27bb092f470 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpVolumeBlocked.png differ diff --git a/Resources/Textures/Structures/Specific/carp_rift.rsi/icon_blue.png b/Resources/Textures/Structures/Specific/carp_rift.rsi/icon_blue.png new file mode 100644 index 00000000000..5d55d70b481 Binary files /dev/null and b/Resources/Textures/Structures/Specific/carp_rift.rsi/icon_blue.png differ diff --git a/Resources/Textures/Structures/Specific/carp_rift.rsi/meta.json b/Resources/Textures/Structures/Specific/carp_rift.rsi/meta.json index 2567d69886b..76699055fb2 100644 --- a/Resources/Textures/Structures/Specific/carp_rift.rsi/meta.json +++ b/Resources/Textures/Structures/Specific/carp_rift.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "https://github.com/tgstation/tgstation/blob/19da0cee1869bad0186d54d6bcd8a55ed30b9db6/icons/obj/carp_rift.dmi", + "copyright": "Taken from tgstations at https://github.com/tgstation/tgstation/blob/19da0cee1869bad0186d54d6bcd8a55ed30b9db6/icons/obj/carp_rift.dmi. icon_blue recolored by deltanedas (github)", "size": { "x": 32, "y": 32 @@ -16,6 +16,16 @@ 0.2 ] ] + }, + { + "name": "icon_blue", + "delays": [ + [ + 0.2, + 0.2, + 0.2 + ] + ] } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/Structures/Storage/tanks.rsi/generictank-1.png b/Resources/Textures/Structures/Storage/tanks.rsi/generictank-1.png new file mode 100644 index 00000000000..238e0733abd Binary files /dev/null and b/Resources/Textures/Structures/Storage/tanks.rsi/generictank-1.png differ diff --git a/Resources/Textures/Structures/Storage/tanks.rsi/meta.json b/Resources/Textures/Structures/Storage/tanks.rsi/meta.json index 5dfa9273d1a..93b557cf5a2 100644 --- a/Resources/Textures/Structures/Storage/tanks.rsi/meta.json +++ b/Resources/Textures/Structures/Storage/tanks.rsi/meta.json @@ -114,6 +114,9 @@ }, { "name": "watercooler-2-4" + }, + { + "name": "generictank-1" } ] } diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json b/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json index 209c9c7d752..e2cbbff9892 100644 --- a/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json +++ b/Resources/Textures/Structures/Wallmounts/signs.rsi/meta.json @@ -5,7 +5,7 @@ "y": 32 }, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 4e0bbe682d0a00192d24708fdb7031008aa03f18 and bee station at commit https://github.com/BeeStation/BeeStation-Hornet/commit/13dd5ac712385642574138f6d7b30eea7c2fab9c, except numerical signs which were created by discord: brainfood#7460", + "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 4e0bbe682d0a00192d24708fdb7031008aa03f18 and bee station at commit https://github.com/BeeStation/BeeStation-Hornet/commit/13dd5ac712385642574138f6d7b30eea7c2fab9c, except numerical signs which were created by discord: brainfood#7460, states: 'survival' and 'ntmining' from https://github.com/tgstation/tgstation/commit/f743754ec3ef446c8172388431effa73aeddb7ff#diff-b429dd7fccbca60d740d4887c1077a178abf1efffe57e7ae2a0b607c8a9e2202", "states": [ { "name": "ai", @@ -1357,6 +1357,22 @@ 1 ] ] + }, + { + "name": "survival", + "delays": [ + [ + 1 + ] + ] + }, + { + "name": "ntmining", + "delays": [ + [ + 1 + ] + ] } ] } diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/ntmining.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/ntmining.png new file mode 100644 index 00000000000..bd452d172ba Binary files /dev/null and b/Resources/Textures/Structures/Wallmounts/signs.rsi/ntmining.png differ diff --git a/Resources/Textures/Structures/Wallmounts/signs.rsi/survival.png b/Resources/Textures/Structures/Wallmounts/signs.rsi/survival.png new file mode 100644 index 00000000000..a4261fbcf88 Binary files /dev/null and b/Resources/Textures/Structures/Wallmounts/signs.rsi/survival.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/full.png b/Resources/Textures/Structures/Walls/mining.rsi/full.png new file mode 100644 index 00000000000..8103f03126e Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/full.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/meta.json b/Resources/Textures/Structures/Walls/mining.rsi/meta.json new file mode 100644 index 00000000000..4ce4691c516 --- /dev/null +++ b/Resources/Textures/Structures/Walls/mining.rsi/meta.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/f743754ec3ef446c8172388431effa73aeddb7ff#diff-b429dd7fccbca60d740d4887c1077a178abf1efffe57e7ae2a0b607c8a9e2202 and modified.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "mining0", + "directions": 4 + }, + { + "name": "mining1", + "directions": 4 + }, + { + "name": "mining2", + "directions": 4 + }, + { + "name": "mining3", + "directions": 4 + }, + { + "name": "mining4", + "directions": 4 + }, + { + "name": "mining5", + "directions": 4 + }, + { + "name": "mining6", + "directions": 4 + }, + { + "name": "mining7", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining0.png b/Resources/Textures/Structures/Walls/mining.rsi/mining0.png new file mode 100644 index 00000000000..b0f8c711706 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining0.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining1.png b/Resources/Textures/Structures/Walls/mining.rsi/mining1.png new file mode 100644 index 00000000000..d2bc3f00e9e Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining1.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining2.png b/Resources/Textures/Structures/Walls/mining.rsi/mining2.png new file mode 100644 index 00000000000..b0f8c711706 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining2.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining3.png b/Resources/Textures/Structures/Walls/mining.rsi/mining3.png new file mode 100644 index 00000000000..d2bc3f00e9e Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining3.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining4.png b/Resources/Textures/Structures/Walls/mining.rsi/mining4.png new file mode 100644 index 00000000000..12ae4d0b8b1 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining4.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining5.png b/Resources/Textures/Structures/Walls/mining.rsi/mining5.png new file mode 100644 index 00000000000..e162be41e3f Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining5.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining6.png b/Resources/Textures/Structures/Walls/mining.rsi/mining6.png new file mode 100644 index 00000000000..12ae4d0b8b1 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining6.png differ diff --git a/Resources/Textures/Structures/Walls/mining.rsi/mining7.png b/Resources/Textures/Structures/Walls/mining.rsi/mining7.png new file mode 100644 index 00000000000..92810f3c1e5 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining.rsi/mining7.png differ diff --git a/Resources/Textures/Structures/Walls/mining_diagonal.rsi/meta.json b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/meta.json new file mode 100644 index 00000000000..d908dd0c08a --- /dev/null +++ b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/f743754ec3ef446c8172388431effa73aeddb7ff#diff-b429dd7fccbca60d740d4887c1077a178abf1efffe57e7ae2a0b607c8a9e2202 and modified.", + "states": [ + { + "name": "state0" + }, + { + "name": "state1" + } + ] +} diff --git a/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state0.png b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state0.png new file mode 100644 index 00000000000..c8f7db27920 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state0.png differ diff --git a/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state1.png b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state1.png new file mode 100644 index 00000000000..c8f7db27920 Binary files /dev/null and b/Resources/Textures/Structures/Walls/mining_diagonal.rsi/state1.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/full.png b/Resources/Textures/Structures/Walls/necropolis.rsi/full.png new file mode 100644 index 00000000000..f03d79132b4 Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/full.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/meta.json b/Resources/Textures/Structures/Walls/necropolis.rsi/meta.json new file mode 100644 index 00000000000..f36c37e48b7 --- /dev/null +++ b/Resources/Textures/Structures/Walls/necropolis.rsi/meta.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/9dbe3253d0bc712e086ec6b5bc4a7fd69bdf337f#diff-a93b44bf8dd39fddb41a69ad1c2dd2d294244b7a46fa885ac6023ed8cdb54080 and modified.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "necropolis0", + "directions": 4 + }, + { + "name": "necropolis1", + "directions": 4 + }, + { + "name": "necropolis2", + "directions": 4 + }, + { + "name": "necropolis3", + "directions": 4 + }, + { + "name": "necropolis4", + "directions": 4 + }, + { + "name": "necropolis5", + "directions": 4 + }, + { + "name": "necropolis6", + "directions": 4 + }, + { + "name": "necropolis7", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis0.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis0.png new file mode 100644 index 00000000000..608d29c03ed Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis0.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis1.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis1.png new file mode 100644 index 00000000000..0c4c7d7912a Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis1.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis2.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis2.png new file mode 100644 index 00000000000..608d29c03ed Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis2.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis3.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis3.png new file mode 100644 index 00000000000..0c4c7d7912a Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis3.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis4.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis4.png new file mode 100644 index 00000000000..8efe7109c6a Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis4.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis5.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis5.png new file mode 100644 index 00000000000..28bbea2a946 Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis5.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis6.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis6.png new file mode 100644 index 00000000000..8efe7109c6a Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis6.png differ diff --git a/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis7.png b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis7.png new file mode 100644 index 00000000000..745e5b0ce39 Binary files /dev/null and b/Resources/Textures/Structures/Walls/necropolis.rsi/necropolis7.png differ diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index e3e7a09657b..1b82435861a 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -89,6 +89,9 @@ binds: - function: ShowEscapeMenu type: State key: F10 +- function: ToggleFullscreen + type: State + key: F11 - function: CycleChatChannelForward type: State key: Tab diff --git a/Resources/mapping_actions.yml b/Resources/mapping_actions.yml index 918333adfbd..0dda6b38a52 100644 --- a/Resources/mapping_actions.yml +++ b/Resources/mapping_actions.yml @@ -692,6 +692,7 @@ entity: RailingRound name: RailingRound keywords: [] + checkCanInteract: False clientExclusive: True autoPopulate: False temporary: True @@ -700,8 +701,7 @@ entityType: RailingRound assignments: - 5: 9 -- action: !type:InstantAction - checkCanInteract: False +- action: !type:InstantActionComponent icon: entity: AirlockMaintLocked keywords: [] diff --git a/RobustToolbox b/RobustToolbox index 8f6b189d293..58aa6e5c756 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 8f6b189d293dc03fc8a33d83340bb2ce66c5c233 +Subproject commit 58aa6e5c7563c40baa51460a9def164a7ebc1791 diff --git a/Tools/actions_changelogs_since_last_run.py b/Tools/actions_changelogs_since_last_run.py index 0c46cd22ec8..a2501753a67 100755 --- a/Tools/actions_changelogs_since_last_run.py +++ b/Tools/actions_changelogs_since_last_run.py @@ -19,7 +19,7 @@ DISCORD_WEBHOOK_URL = os.environ.get("DISCORD_WEBHOOK_URL") -CHANGELOG_FILE = "Resources/Changelog/Changelog.yml" +CHANGELOG_FILE = "Resources/Changelog/DeltaVChangelog.yml" TYPES_TO_EMOJI = { "Fix": "🐛", @@ -130,4 +130,4 @@ def send_to_discord(entries: Iterable[ChangelogEntry]) -> None: requests.post(DISCORD_WEBHOOK_URL, json=body) -main() \ No newline at end of file +main()