diff --git a/Content.Benchmarks/RaiseEventBenchmark.cs b/Content.Benchmarks/RaiseEventBenchmark.cs index 4c4e0d9125..e3d377ccb3 100644 --- a/Content.Benchmarks/RaiseEventBenchmark.cs +++ b/Content.Benchmarks/RaiseEventBenchmark.cs @@ -23,6 +23,8 @@ public class RaiseEventBenchmark PoolManager.Startup(typeof(BenchSystem).Assembly); _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); var entMan = _pair.Server.EntMan; + var fact = _pair.Server.ResolveDependency(); + var bus = (EntityEventBus)entMan.EventBus; _sys = entMan.System(); _pair.Server.WaitPost(() => @@ -30,6 +32,8 @@ public class RaiseEventBenchmark var uid = entMan.Spawn(); _sys.Ent = new(uid, entMan.GetComponent(uid)); _sys.Ent2 = new(_sys.Ent.Owner, _sys.Ent.Comp); + _sys.NetId = fact.GetRegistration().NetID!.Value; + _sys.EvSubs = bus.GetNetCompEventHandlers(); }) .GetAwaiter() .GetResult(); @@ -60,6 +64,12 @@ public class RaiseEventBenchmark return _sys.RaiseICompEvent(); } + [Benchmark] + public int RaiseNetEvent() + { + return _sys.RaiseNetIdEvent(); + } + [Benchmark] public int RaiseCSharpEvent() { @@ -74,6 +84,8 @@ public class RaiseEventBenchmark public delegate void EntityEventHandler(EntityUid uid, TransformComponent comp, ref BenchEv ev); public event EntityEventHandler? OnCSharpEvent; + public ushort NetId; + internal EntityEventBus.DirectedEventHandler?[] EvSubs = default!; public override void Initialize() { @@ -92,7 +104,7 @@ public class RaiseEventBenchmark public int RaiseCompEvent() { var ev = new BenchEv(); - EntityManager.EventBus.RaiseComponentEvent(Ent.Owner, Ent.Comp, ref ev); + RaiseComponentEvent(Ent.Owner, Ent.Comp, ref ev); return ev.N; } @@ -100,7 +112,16 @@ public class RaiseEventBenchmark { // Raise with an IComponent instead of concrete type var ev = new BenchEv(); - EntityManager.EventBus.RaiseComponentEvent(Ent2.Owner, Ent2.Comp, ref ev); + RaiseComponentEvent(Ent2.Owner, Ent2.Comp, ref ev); + return ev.N; + } + + public int RaiseNetIdEvent() + { + // Raise a "IComponent" event using a net-id index delegate array (for PVS & client game-state events) + var ev = new BenchEv(); + ref var unitEv = ref Unsafe.As(ref ev); + EvSubs[NetId]?.Invoke(Ent2.Owner, Ent2.Comp, ref unitEv); return ev.N; } @@ -118,6 +139,7 @@ public class RaiseEventBenchmark } [ByRefEvent] + [ComponentEvent(Exclusive = false)] public struct BenchEv { public int N; diff --git a/Content.Client/Commands/QuickInspectCommand.cs b/Content.Client/Commands/QuickInspectCommand.cs new file mode 100644 index 0000000000..dc3aae615a --- /dev/null +++ b/Content.Client/Commands/QuickInspectCommand.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Content.Shared.CCVar; +using Content.Shared.Input; +using Robust.Client.Input; +using Robust.Shared.Configuration; +using Robust.Shared.Console; + +namespace Content.Client.Commands; + +/// +/// Sets the a CVar to the name of a component, which allows the client to quickly open a VV window for that component +/// by using the Alt+C or Alt+B hotkeys. +/// +public sealed class QuickInspectCommand : LocalizedEntityCommands +{ + [Dependency] private readonly IConfigurationManager _configurationManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + + public override string Command => "quickinspect"; + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 1) + { + shell.WriteLine(Loc.GetString("shell-wrong-arguments-number")); + return; + } + + _configurationManager.SetCVar(CCVars.DebugQuickInspect, args[0]); + + var serverKey = _inputManager.GetKeyFunctionButtonString(ContentKeyFunctions.InspectServerComponent); + var clientKey = _inputManager.GetKeyFunctionButtonString(ContentKeyFunctions.InspectClientComponent); + shell.WriteLine(Loc.GetString($"cmd-quickinspect-success", ("component", args[0]), ("serverKeybind", serverKey), ("clientKeybind", clientKey))); + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length == 1) + { + // Not ideal since it only shows client-side components, but you can still type in any name you want. + // If you know how to get server component names on the client then please fix this. + var options = EntityManager.ComponentFactory.AllRegisteredTypes + .Select(p => new CompletionOption( + EntityManager.ComponentFactory.GetComponentName(p) + )); + + return CompletionResult.FromOptions(options); + } + + return CompletionResult.Empty; + } +} diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index d4fdfc41d4..952bd27f64 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -100,7 +100,6 @@ namespace Content.Client.Entry _componentFactory.IgnoreMissingComponents(); // Do not add to these, they are legacy. - _componentFactory.RegisterClass(); _componentFactory.RegisterClass(); // Do not add to the above, they are legacy diff --git a/Content.Client/Gameplay/GameplayStateBase.cs b/Content.Client/Gameplay/GameplayStateBase.cs index 69e6e0b58b..c2b10fd01a 100644 --- a/Content.Client/Gameplay/GameplayStateBase.cs +++ b/Content.Client/Gameplay/GameplayStateBase.cs @@ -3,6 +3,7 @@ using System.Numerics; using Content.Client.Clickable; using Content.Client.UserInterface; using Content.Client.Viewport; +using Content.Shared.CCVar; using Content.Shared.Input; using Robust.Client.ComponentTrees; using Robust.Client.GameObjects; @@ -13,6 +14,7 @@ using Robust.Client.State; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Graphics; using Robust.Shared.Input; @@ -40,6 +42,7 @@ namespace Content.Client.Gameplay [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IViewVariablesManager _vvm = default!; [Dependency] private readonly IConsoleHost _conHost = default!; + [Dependency] private readonly IConfigurationManager _configurationManager = default!; private ClickableEntityComparer _comparer = default!; @@ -83,6 +86,8 @@ namespace Content.Client.Gameplay _comparer = new ClickableEntityComparer(); CommandBinds.Builder .Bind(ContentKeyFunctions.InspectEntity, new PointerInputCmdHandler(HandleInspect, outsidePrediction: true)) + .Bind(ContentKeyFunctions.InspectServerComponent, new PointerInputCmdHandler(HandleInspectServerComponent, outsidePrediction: true)) + .Bind(ContentKeyFunctions.InspectClientComponent, new PointerInputCmdHandler(HandleInspectClientComponent, outsidePrediction: true)) .Register(); } @@ -99,6 +104,21 @@ namespace Content.Client.Gameplay return true; } + private bool HandleInspectServerComponent(ICommonSession? session, EntityCoordinates coords, EntityUid uid) + { + var component = _configurationManager.GetCVar(CCVars.DebugQuickInspect); + if (_entityManager.TryGetNetEntity(uid, out var net)) + _conHost.ExecuteCommand($"vv /entity/{net.Value.Id}/{component}"); + return true; + } + + private bool HandleInspectClientComponent(ICommonSession? session, EntityCoordinates coords, EntityUid uid) + { + var component = _configurationManager.GetCVar(CCVars.DebugQuickInspect); + _conHost.ExecuteCommand($"vv /c/entity/{uid}/{component}"); + return true; + } + public EntityUid? GetClickedEntity(MapCoordinates coordinates) { return GetClickedEntity(coordinates, _eyeManager.CurrentEye); diff --git a/Content.Client/Gravity/GravityGeneratorSystem.cs b/Content.Client/Gravity/GravityGeneratorSystem.cs new file mode 100644 index 0000000000..b74ea35daa --- /dev/null +++ b/Content.Client/Gravity/GravityGeneratorSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Gravity; + +namespace Content.Client.Gravity; + +public sealed class GravityGeneratorSystem : SharedGravityGeneratorSystem +{ + +} diff --git a/Content.Client/Gravity/GravitySystem.cs b/Content.Client/Gravity/GravitySystem.cs index 60e043cc99..f1e09fdb44 100644 --- a/Content.Client/Gravity/GravitySystem.cs +++ b/Content.Client/Gravity/GravitySystem.cs @@ -12,14 +12,14 @@ public sealed partial class GravitySystem : SharedGravitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnAppearanceChange); InitializeShake(); } /// /// Ensures that the visible state of gravity generators are synced with their sprites. /// - private void OnAppearanceChange(EntityUid uid, SharedGravityGeneratorComponent comp, ref AppearanceChangeEvent args) + private void OnAppearanceChange(EntityUid uid, GravityGeneratorComponent comp, ref AppearanceChangeEvent args) { if (args.Sprite == null) return; diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 47f0cda2f6..01e7dc367c 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -38,6 +38,8 @@ namespace Content.Client.Input common.AddFunction(ContentKeyFunctions.ZoomIn); common.AddFunction(ContentKeyFunctions.ResetZoom); common.AddFunction(ContentKeyFunctions.InspectEntity); + common.AddFunction(ContentKeyFunctions.InspectServerComponent); + common.AddFunction(ContentKeyFunctions.InspectClientComponent); common.AddFunction(ContentKeyFunctions.ToggleRoundEndSummaryWindow); // Not in engine, because engine cannot check for sanbox/admin status before starting placement. diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index f92f66df31..40d1836c08 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -268,6 +268,8 @@ namespace Content.Client.Options.UI.Tabs AddButton(EngineKeyFunctions.ShowDebugMonitors); AddButton(EngineKeyFunctions.HideUI); AddButton(ContentKeyFunctions.InspectEntity); + AddButton(ContentKeyFunctions.InspectServerComponent); + AddButton(ContentKeyFunctions.InspectClientComponent); AddHeader("ui-options-header-text-cursor"); AddButton(EngineKeyFunctions.TextCursorLeft); diff --git a/Content.Client/Tips/TipsSystem.cs b/Content.Client/Tips/TipsSystem.cs new file mode 100644 index 0000000000..00fc08437c --- /dev/null +++ b/Content.Client/Tips/TipsSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared.Tips; + +namespace Content.Client.Tips; + +public sealed class TipsSystem : SharedTipsSystem; diff --git a/Content.IntegrationTests/Tests/GravityGridTest.cs b/Content.IntegrationTests/Tests/GravityGridTest.cs index 8257035de6..047ec0259a 100644 --- a/Content.IntegrationTests/Tests/GravityGridTest.cs +++ b/Content.IntegrationTests/Tests/GravityGridTest.cs @@ -1,4 +1,3 @@ -using Content.Server.Gravity; using Content.Server.Power.Components; using Content.Shared.Gravity; using Robust.Shared.GameObjects; diff --git a/Content.IntegrationTests/Tests/Power/PowerTest.cs b/Content.IntegrationTests/Tests/Power/PowerTest.cs index ab8a421c03..85bd366697 100644 --- a/Content.IntegrationTests/Tests/Power/PowerTest.cs +++ b/Content.IntegrationTests/Tests/Power/PowerTest.cs @@ -402,8 +402,8 @@ namespace Content.IntegrationTests.Tests.Power battery = entityManager.GetComponent(generatorEnt); consumer = entityManager.GetComponent(consumerEnt); - batterySys.SetMaxCharge(generatorEnt, startingCharge, battery); - batterySys.SetCharge(generatorEnt, startingCharge, battery); + batterySys.SetMaxCharge((generatorEnt, battery), startingCharge); + batterySys.SetCharge((generatorEnt, battery), startingCharge); netBattery.MaxSupply = 400; netBattery.SupplyRampRate = 400; netBattery.SupplyRampTolerance = 100; @@ -513,8 +513,8 @@ namespace Content.IntegrationTests.Tests.Power supplier.SupplyRampRate = rampRate; supplier.SupplyRampTolerance = rampTol; - batterySys.SetMaxCharge(batteryEnt, 100_000, battery); - batterySys.SetCharge(batteryEnt, 100_000, battery); + batterySys.SetMaxCharge((batteryEnt, battery), 100_000); + batterySys.SetCharge((batteryEnt, battery), 100_000); netBattery.MaxSupply = draw / 2; netBattery.SupplyRampRate = rampRate; netBattery.SupplyRampTolerance = rampTol; @@ -600,7 +600,7 @@ namespace Content.IntegrationTests.Tests.Power supplier.MaxSupply = 500; supplier.SupplyRampTolerance = 500; - batterySys.SetMaxCharge(batteryEnt, 100_000, battery); + batterySys.SetMaxCharge((batteryEnt, battery), 100_000); netBattery.MaxChargeRate = 1_000; netBattery.Efficiency = 0.5f; }); @@ -670,8 +670,8 @@ namespace Content.IntegrationTests.Tests.Power netBattery.MaxSupply = 400; netBattery.SupplyRampTolerance = 400; netBattery.SupplyRampRate = 100_000; - batterySys.SetMaxCharge(batteryEnt, 100_000, battery); - batterySys.SetCharge(batteryEnt, 100_000, battery); + batterySys.SetMaxCharge((batteryEnt, battery), 100_000); + batterySys.SetCharge((batteryEnt, battery), 100_000); }); // Run some ticks so everything is stable. @@ -750,8 +750,8 @@ namespace Content.IntegrationTests.Tests.Power netBattery.SupplyRampTolerance = 400; netBattery.SupplyRampRate = 100_000; netBattery.Efficiency = 0.5f; - batterySys.SetMaxCharge(batteryEnt, 1_000_000, battery); - batterySys.SetCharge(batteryEnt, 1_000_000, battery); + batterySys.SetMaxCharge((batteryEnt, battery), 1_000_000); + batterySys.SetCharge((batteryEnt, battery), 1_000_000); }); // Run some ticks so everything is stable. @@ -841,8 +841,8 @@ namespace Content.IntegrationTests.Tests.Power supplier.MaxSupply = 1000; supplier.SupplyRampTolerance = 1000; - batterySys.SetMaxCharge(batteryEnt1, 1_000_000, battery1); - batterySys.SetMaxCharge(batteryEnt2, 1_000_000, battery2); + batterySys.SetMaxCharge((batteryEnt1, battery1), 1_000_000); + batterySys.SetMaxCharge((batteryEnt2, battery2), 1_000_000); netBattery1.MaxChargeRate = 1_000; netBattery2.MaxChargeRate = 1_000; @@ -945,10 +945,10 @@ namespace Content.IntegrationTests.Tests.Power netBattery2.SupplyRampTolerance = 1000; netBattery1.SupplyRampRate = 100_000; netBattery2.SupplyRampRate = 100_000; - batterySys.SetMaxCharge(batteryEnt1, 100_000, battery1); - batterySys.SetMaxCharge(batteryEnt2, 100_000, battery2); - batterySys.SetCharge(batteryEnt1, 100_000, battery1); - batterySys.SetCharge(batteryEnt2, 100_000, battery2); + batterySys.SetMaxCharge((batteryEnt1, battery1), 100_000); + batterySys.SetMaxCharge((batteryEnt2, battery2), 100_000); + batterySys.SetCharge((batteryEnt1, battery1), 100_000); + batterySys.SetCharge((batteryEnt2, battery2), 100_000); }); // Run some ticks so everything is stable. @@ -1031,8 +1031,8 @@ namespace Content.IntegrationTests.Tests.Power supplier.MaxSupply = 1000; supplier.SupplyRampTolerance = 1000; - batterySys.SetMaxCharge(batteryEnt1, 1_000_000, battery1); - batterySys.SetMaxCharge(batteryEnt2, 1_000_000, battery2); + batterySys.SetMaxCharge((batteryEnt1, battery1), 1_000_000); + batterySys.SetMaxCharge((batteryEnt2, battery2), 1_000_000); netBattery1.MaxChargeRate = 20; netBattery2.MaxChargeRate = 20; @@ -1107,8 +1107,8 @@ namespace Content.IntegrationTests.Tests.Power netBattery.MaxSupply = 1000; netBattery.SupplyRampTolerance = 200; netBattery.SupplyRampRate = 10; - batterySys.SetMaxCharge(batteryEnt, 100_000, battery); - batterySys.SetCharge(batteryEnt, 100_000, battery); + batterySys.SetMaxCharge((batteryEnt, battery), 100_000); + batterySys.SetCharge((batteryEnt, battery), 100_000); }); // Run some ticks so everything is stable. @@ -1253,7 +1253,7 @@ namespace Content.IntegrationTests.Tests.Power generatorSupplier.MaxSupply = 1000; generatorSupplier.SupplyRampTolerance = 1000; - batterySys.SetCharge(apcEnt, 0, apcBattery); + batterySys.SetCharge((apcEnt, apcBattery), 0); }); server.RunTicks(5); //let run a few ticks for PowerNets to reevaluate and start charging apc @@ -1314,8 +1314,8 @@ namespace Content.IntegrationTests.Tests.Power extensionCableSystem.SetProviderTransferRange(apcExtensionEnt, range); extensionCableSystem.SetReceiverReceptionRange(powerReceiverEnt, range); - batterySys.SetMaxCharge(apcEnt, 10000, battery); //arbitrary nonzero amount of charge - batterySys.SetCharge(apcEnt, battery.MaxCharge, battery); //fill battery + batterySys.SetMaxCharge((apcEnt, battery), 10000); //arbitrary nonzero amount of charge + batterySys.SetCharge((apcEnt, battery), battery.MaxCharge); //fill battery receiver.Load = 1; //arbitrary small amount of power }); diff --git a/Content.Server/Administration/Commands/TippyCommand.cs b/Content.Server/Administration/Commands/TippyCommand.cs new file mode 100644 index 0000000000..b79c160706 --- /dev/null +++ b/Content.Server/Administration/Commands/TippyCommand.cs @@ -0,0 +1,103 @@ +using Content.Shared.Administration; +using Content.Shared.Tips; +using Robust.Server.Player; +using Robust.Shared.Console; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; + +namespace Content.Server.Administration.Commands; + +[AdminCommand(AdminFlags.Fun)] +public sealed class TippyCommand : LocalizedEntityCommands +{ + [Dependency] private readonly SharedTipsSystem _tips = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IPlayerManager _player = default!; + + public override string Command => "tippy"; + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length < 2) + { + shell.WriteLine(Loc.GetString("cmd-tippy-help")); + return; + } + + ICommonSession? targetSession = null; + if (args[0] != "all") + { + if (!_player.TryGetSessionByUsername(args[0], out targetSession)) + { + shell.WriteLine(Loc.GetString("cmd-tippy-error-no-user")); + return; + } + } + + var msg = args[1]; + + EntProtoId? prototype = null; + if (args.Length > 2) + { + if (args[2] == "null") + prototype = null; + else if (!_prototype.HasIndex(args[2])) + { + shell.WriteError(Loc.GetString("cmd-tippy-error-no-prototype", ("proto", args[2]))); + return; + } + else + prototype = args[2]; + } + + var speakTime = _tips.GetSpeechTime(msg); + var slideTime = 3f; + var waddleInterval = 0.5f; + + if (args.Length > 3 && float.TryParse(args[3], out var parsedSpeakTime)) + speakTime = parsedSpeakTime; + + if (args.Length > 4 && float.TryParse(args[4], out var parsedSlideTime)) + slideTime = parsedSlideTime; + + if (args.Length > 5 && float.TryParse(args[5], out var parsedWaddleInterval)) + waddleInterval = parsedWaddleInterval; + + if (targetSession != null) // send to specified player + _tips.SendTippy(targetSession, msg, prototype, speakTime, slideTime, waddleInterval); + else // send to everyone + _tips.SendTippy(msg, prototype, speakTime, slideTime, waddleInterval); + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + return args.Length switch + { + 1 => CompletionResult.FromHintOptions( + CompletionHelper.SessionNames(players: _player), + Loc.GetString("cmd-tippy-auto-1")), + 2 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-2")), + 3 => CompletionResult.FromHintOptions( + CompletionHelper.PrototypeIdsLimited(args[2], _prototype), + Loc.GetString("cmd-tippy-auto-3")), + 4 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-4")), + 5 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-5")), + 6 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-6")), + _ => CompletionResult.Empty + }; + } +} + +[AdminCommand(AdminFlags.Fun)] +public sealed class TipCommand : LocalizedEntityCommands +{ + [Dependency] private readonly SharedTipsSystem _tips = default!; + + public override string Command => "tip"; + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + _tips.AnnounceRandomTip(); + _tips.RecalculateNextTipTime(); + } +} diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs index 41228b5ac8..4f96a25a5c 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs @@ -169,7 +169,7 @@ public sealed partial class AdminVerbSystem Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/fill_battery.png")), Act = () => { - _batterySystem.SetCharge(args.Target, battery.MaxCharge, battery); + _batterySystem.SetCharge((args.Target, battery), battery.MaxCharge); }, Impact = LogImpact.Medium, Message = Loc.GetString("admin-trick-refill-battery-description"), @@ -184,7 +184,7 @@ public sealed partial class AdminVerbSystem Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/drain_battery.png")), Act = () => { - _batterySystem.SetCharge(args.Target, 0, battery); + _batterySystem.SetCharge((args.Target, battery), 0); }, Impact = LogImpact.Medium, Message = Loc.GetString("admin-trick-drain-battery-description"), @@ -200,9 +200,8 @@ public sealed partial class AdminVerbSystem Act = () => { var recharger = EnsureComp(args.Target); - recharger.AutoRecharge = true; recharger.AutoRechargeRate = battery.MaxCharge; // Instant refill. - recharger.AutoRechargePause = false; // No delay. + recharger.AutoRechargePauseTime = TimeSpan.Zero; // No delay. }, Impact = LogImpact.Medium, Message = Loc.GetString("admin-trick-infinite-battery-object-description"), @@ -553,7 +552,7 @@ public sealed partial class AdminVerbSystem if (!HasComp(ent)) continue; var battery = EnsureComp(ent); - _batterySystem.SetCharge(ent, battery.MaxCharge, battery); + _batterySystem.SetCharge((ent, battery), battery.MaxCharge); } }, Impact = LogImpact.Extreme, @@ -574,7 +573,7 @@ public sealed partial class AdminVerbSystem if (!HasComp(ent)) continue; var battery = EnsureComp(ent); - _batterySystem.SetCharge(ent, 0, battery); + _batterySystem.SetCharge((ent, battery), 0); } }, Impact = LogImpact.Extreme, @@ -599,9 +598,8 @@ public sealed partial class AdminVerbSystem var recharger = EnsureComp(ent); var battery = EnsureComp(ent); - recharger.AutoRecharge = true; recharger.AutoRechargeRate = battery.MaxCharge; // Instant refill. - recharger.AutoRechargePause = false; // No delay. + recharger.AutoRechargePauseTime = TimeSpan.Zero; // No delay. } }, Impact = LogImpact.Extreme, diff --git a/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs b/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs new file mode 100644 index 0000000000..d59fbc82b4 --- /dev/null +++ b/Content.Server/Antag/AntagMultipleRoleSpawnerSystem.cs @@ -0,0 +1,40 @@ +using Content.Server.Antag.Components; +using Robust.Shared.Random; + +namespace Content.Server.Antag; + +public sealed class AntagMultipleRoleSpawnerSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ILogManager _log = default!; + + private ISawmill _sawmill = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnSelectEntity); + + _sawmill = _log.GetSawmill("antag_multiple_spawner"); + } + + private void OnSelectEntity(Entity ent, ref AntagSelectEntityEvent args) + { + // If its more than one the logic breaks + if (args.AntagRoles.Count != 1) + { + _sawmill.Fatal($"Antag multiple role spawner had more than one antag ({args.AntagRoles.Count})"); + return; + } + + var role = args.AntagRoles[0]; + + var entProtos = ent.Comp.AntagRoleToPrototypes[role]; + + if (entProtos.Count == 0) + return; // You will just get a normal job + + args.Entity = Spawn(ent.Comp.PickAndTake ? _random.PickAndTake(entProtos) : _random.Pick(entProtos)); + } +} diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 9c134cf5ef..3b413214cb 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -271,7 +271,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem(player, out var spawnerComp)) { Log.Error($"Antag spawner {player} does not have a GhostRoleAntagSpawnerComponent."); - _adminLogger.Add(LogType.AntagSelection,$"Antag spawner {player} in gamerule {ToPrettyString(ent)} failed due to not having GhostRoleAntagSpawnerComponent."); + _adminLogger.Add(LogType.AntagSelection, $"Antag spawner {player} in gamerule {ToPrettyString(ent)} failed due to not having GhostRoleAntagSpawnerComponent."); if (session != null) { ent.Comp.AssignedSessions.Remove(session); @@ -543,21 +544,21 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem [ByRefEvent] -public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity GameRule) +public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity GameRule, List> AntagRoles) { public readonly ICommonSession? Session = Session; + /// list of antag role prototypes associated with a entity. used by the + public readonly List> AntagRoles = AntagRoles; + public bool Handled => Entity != null; public EntityUid? Entity; @@ -625,12 +629,15 @@ public record struct AntagSelectEntityEvent(ICommonSession? Session, Entity [ByRefEvent] -public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity GameRule) +public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity GameRule, EntityUid Entity) { public readonly ICommonSession? Session = Session; public bool Handled => Coordinates.Any(); + // the entity of the antagonist + public EntityUid Entity = Entity; + public List Coordinates = new(); } diff --git a/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs b/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs new file mode 100644 index 0000000000..5a9103a82a --- /dev/null +++ b/Content.Server/Antag/Components/AntagMultipleRoleSpawnerComponent.cs @@ -0,0 +1,23 @@ +using Content.Shared.Roles; +using Robust.Shared.Prototypes; + +namespace Content.Server.Antag.Components; + +/// +/// Selects and spawns one prototype from a list for each antag prototype selected by the +/// +[RegisterComponent] +public sealed partial class AntagMultipleRoleSpawnerComponent : Component +{ + /// + /// antag prototype -> list of possible entities to spawn for that antag prototype. Will choose from the list randomly once with replacement unless is set to true + /// + [DataField] + public Dictionary, List> AntagRoleToPrototypes; + + /// + /// Should you remove ent prototypes from the list after spawning one. + /// + [DataField] + public bool PickAndTake; +} diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs index 29f091f340..96a5c69457 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Linq; using Content.Server.Atmos.Components; using Content.Server.Atmos.Piping.Components; using Content.Server.NodeContainer.NodeGroups; @@ -14,6 +13,22 @@ namespace Content.Server.Atmos.EntitySystems; public partial class AtmosphereSystem { + /* + General API for interacting with AtmosphereSystem. + + If you feel like you're stepping on eggshells because you can't access things in AtmosphereSystem, + consider adding a method here instead of making your own way to work around it. + */ + + /// + /// Gets the that an entity is contained within. + /// + /// The entity to get the mixture for. + /// If true, will ignore mixtures that the entity is contained in + /// (ex. lockers and cryopods) and just get the tile mixture. + /// If true, will mark the tile as active for atmosphere processing. + /// A if one could be found, null otherwise. + [PublicAPI] public GasMixture? GetContainingMixture(Entity ent, bool ignoreExposed = false, bool excite = false) { if (!Resolve(ent, ref ent.Comp)) @@ -22,6 +37,17 @@ public partial class AtmosphereSystem return GetContainingMixture(ent, ent.Comp.GridUid, ent.Comp.MapUid, ignoreExposed, excite); } + /// + /// Gets the that an entity is contained within. + /// + /// The entity to get the mixture for. + /// The grid that the entity may be on. + /// The map that the entity may be on. + /// If true, will ignore mixtures that the entity is contained in + /// (ex. lockers and cryopods) and just get the tile mixture. + /// If true, will mark the tile as active for atmosphere processing. + /// A if one could be found, null otherwise. + [PublicAPI] public GasMixture? GetContainingMixture( Entity ent, Entity? grid, @@ -49,16 +75,38 @@ public partial class AtmosphereSystem return GetTileMixture(grid, map, position, excite); } - public bool HasAtmosphere(EntityUid gridUid) => _atmosQuery.HasComponent(gridUid); + /// + /// Checks if a grid has an atmosphere. + /// + /// The grid to check. + /// True if the grid has an atmosphere, false otherwise. + [PublicAPI] + public bool HasAtmosphere(EntityUid gridUid) + { + return _atmosQuery.HasComponent(gridUid); + } + /// + /// Sets whether a grid is simulated by Atmospherics. + /// + /// The grid to set. + /// Whether the grid should be simulated. + /// >True if the grid's simulated state was changed, false otherwise. + [PublicAPI] public bool SetSimulatedGrid(EntityUid gridUid, bool simulated) { + // TODO ATMOS this event literally has no subscribers. Did this just get silently refactored out? var ev = new SetSimulatedGridMethodEvent(gridUid, simulated); RaiseLocalEvent(gridUid, ref ev); return ev.Handled; } + /// + /// Checks whether a grid is simulated by Atmospherics. + /// + /// The grid to check. + /// >True if the grid is simulated, false otherwise. public bool IsSimulatedGrid(EntityUid gridUid) { var ev = new IsSimulatedGridMethodEvent(gridUid); @@ -67,24 +115,53 @@ public partial class AtmosphereSystem return ev.Simulated; } + /// + /// Gets all s on a grid. + /// + /// The grid to get mixtures for. + /// Whether to mark all tiles as active for atmosphere processing. + /// An enumerable of all gas mixtures on the grid. + [PublicAPI] public IEnumerable GetAllMixtures(EntityUid gridUid, bool excite = false) { var ev = new GetAllMixturesMethodEvent(gridUid, excite); RaiseLocalEvent(gridUid, ref ev); - if(!ev.Handled) - return Enumerable.Empty(); + if (!ev.Handled) + return []; DebugTools.AssertNotNull(ev.Mixtures); return ev.Mixtures!; } + /// + /// Invalidates a tile on a grid, marking it for revalidation. + /// + /// Frequently used tile data like are determined once and cached. + /// If this tile's state changes, ex. being added or removed, then this position in the map needs to + /// be updated. + /// + /// Tiles that need to be updated are marked as invalid and revalidated before all other + /// processing stages. + /// + /// The grid entity. + /// The tile to invalidate. + [PublicAPI] public void InvalidateTile(Entity entity, Vector2i tile) { if (_atmosQuery.Resolve(entity.Owner, ref entity.Comp, false)) entity.Comp.InvalidatedCoords.Add(tile); } + /// + /// Gets the gas mixtures for a list of tiles on a grid or map. + /// + /// The grid to get mixtures from. + /// The map to get mixtures from. + /// The list of tiles to get mixtures for. + /// Whether to mark the tiles as active for atmosphere processing. + /// >An array of gas mixtures corresponding to the input tiles. + [PublicAPI] public GasMixture?[]? GetTileMixtures( Entity? grid, Entity? map, @@ -95,7 +172,7 @@ public partial class AtmosphereSystem var handled = false; // If we've been passed a grid, try to let it handle it. - if (grid is {} gridEnt && Resolve(gridEnt, ref gridEnt.Comp1)) + if (grid is { } gridEnt && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp1)) { if (excite) Resolve(gridEnt, ref gridEnt.Comp2); @@ -128,7 +205,7 @@ public partial class AtmosphereSystem // We either don't have a grid, or the event wasn't handled. // Let the map handle it instead, and also broadcast the event. - if (map is {} mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp)) + if (map is { } mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp)) { mixtures ??= new GasMixture?[tiles.Count]; for (var i = 0; i < tiles.Count; i++) @@ -145,10 +222,21 @@ public partial class AtmosphereSystem { mixtures[i] ??= GasMixture.SpaceGas; } + return mixtures; } - public GasMixture? GetTileMixture (Entity entity, bool excite = false) + /// + /// Gets the gas mixture for a specific tile that an entity is on. + /// + /// The entity to get the tile mixture for. + /// Whether to mark the tile as active for atmosphere processing. + /// A if one could be found, null otherwise. + /// This does not return the that the entity + /// may be contained in, ex. if the entity is currently in a locker/crate with its own + /// . + [PublicAPI] + public GasMixture? GetTileMixture(Entity entity, bool excite = false) { if (!Resolve(entity.Owner, ref entity.Comp)) return null; @@ -157,6 +245,15 @@ public partial class AtmosphereSystem return GetTileMixture(entity.Comp.GridUid, entity.Comp.MapUid, indices, excite); } + /// + /// Gets the gas mixture for a specific tile on a grid or map. + /// + /// The grid to get the mixture from. + /// The map to get the mixture from. + /// The tile to get the mixture from. + /// Whether to mark the tile as active for atmosphere processing. + /// >A if one could be found, null otherwise. + [PublicAPI] public GasMixture? GetTileMixture( Entity? grid, Entity? map, @@ -164,8 +261,8 @@ public partial class AtmosphereSystem bool excite = false) { // If we've been passed a grid, try to let it handle it. - if (grid is {} gridEnt - && Resolve(gridEnt, ref gridEnt.Comp1, false) + if (grid is { } gridEnt + && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp1, false) && gridEnt.Comp1.Tiles.TryGetValue(gridTile, out var tile)) { if (excite) @@ -177,13 +274,20 @@ public partial class AtmosphereSystem return tile.Air; } - if (map is {} mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp, false)) + if (map is { } mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp, false)) return mapEnt.Comp.Mixture; // Default to a space mixture... This is a space game, after all! return GasMixture.SpaceGas; } + /// + /// Triggers a tile's to react. + /// + /// The grid to react the tile on. + /// The tile to react. + /// The result of the reaction. + [PublicAPI] public ReactionResult ReactTile(EntityUid gridId, Vector2i tile) { var ev = new ReactTileMethodEvent(gridId, tile); @@ -194,24 +298,49 @@ public partial class AtmosphereSystem return ev.Result; } - public bool IsTileAirBlocked(EntityUid gridUid, Vector2i tile, AtmosDirection directions = AtmosDirection.All, MapGridComponent? mapGridComp = null) + /// + /// Checks if a tile on a grid is air-blocked in the specified directions. + /// + /// The grid to check. + /// The tile on the grid to check. + /// The directions to check for air-blockage. + /// Optional map grid component associated with the grid. + /// True if the tile is air-blocked in the specified directions, false otherwise. + [PublicAPI] + public bool IsTileAirBlocked(EntityUid gridUid, + Vector2i tile, + AtmosDirection directions = AtmosDirection.All, + MapGridComponent? mapGridComp = null) { if (!Resolve(gridUid, ref mapGridComp, false)) return false; + // TODO ATMOS: This reconstructs the data instead of getting the cached version. Might want to include a method to get the cached version later. var data = GetAirtightData(gridUid, mapGridComp, tile); return data.BlockedDirections.IsFlagSet(directions); } + /// + /// Checks if a tile on a grid or map is space as defined by a tile's definition of space. + /// Some tiles can hold back space and others cannot - for example, plating can hold + /// back space, whereas scaffolding cannot, exposing the map atmosphere beneath. + /// + /// This does not check if the on the tile is space, + /// it only checks the current tile's ability to hold back space. + /// The grid to check. + /// The map to check. + /// The tile to check. + /// True if the tile is space, false otherwise. + [PublicAPI] public bool IsTileSpace(Entity? grid, Entity? map, Vector2i tile) { - if (grid is {} gridEnt && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp, false) - && gridEnt.Comp.Tiles.TryGetValue(tile, out var tileAtmos)) + if (grid is { } gridEnt && _atmosQuery.Resolve(gridEnt, ref gridEnt.Comp, false) + && gridEnt.Comp.Tiles.TryGetValue(tile, out var tileAtmos)) { return tileAtmos.Space; } - if (map is {} mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp, false)) + if (map is { } mapEnt && _mapAtmosQuery.Resolve(mapEnt, ref mapEnt.Comp, false)) return mapEnt.Comp.Space; // If nothing handled the event, it'll default to true. @@ -219,28 +348,77 @@ public partial class AtmosphereSystem return true; } + /// + /// Checks if the gas mixture on a tile is "probably safe". + /// Probably safe is defined as having at least air alarm-grade safe pressure and temperature. + /// (more than 260K, less than 360K, and between safe low and high pressure as defined in + /// and ) + /// + /// The grid to check. + /// The map to check. + /// The tile to check. + /// True if the tile's mixture is probably safe, false otherwise. + [PublicAPI] public bool IsTileMixtureProbablySafe(Entity? grid, Entity map, Vector2i tile) { return IsMixtureProbablySafe(GetTileMixture(grid, map, tile)); } + /// + /// Gets the heat capacity of the gas mixture on a tile. + /// + /// The grid to check. + /// The map to check. + /// The tile on the grid/map to check. + /// >The heat capacity of the tile's mixture, or the heat capacity of space if a mixture could not be found. + [PublicAPI] public float GetTileHeatCapacity(Entity? grid, Entity map, Vector2i tile) { return GetHeatCapacity(GetTileMixture(grid, map, tile) ?? GasMixture.SpaceGas); } + /// + /// Gets an enumerator for the adjacent tile mixtures of a tile on a grid. + /// + /// The grid to get adjacent tile mixtures from. + /// The tile to get adjacent mixtures for. + /// Whether to include blocked adjacent tiles. + /// Whether to mark the adjacent tiles as active for atmosphere processing. + /// An enumerator for the adjacent tile mixtures. + [PublicAPI] public TileMixtureEnumerator GetAdjacentTileMixtures(Entity grid, Vector2i tile, bool includeBlocked = false, bool excite = false) { + // TODO ATMOS includeBlocked and excite parameters are unhandled currently. if (!_atmosQuery.Resolve(grid, ref grid.Comp, false)) return TileMixtureEnumerator.Empty; return !grid.Comp.Tiles.TryGetValue(tile, out var atmosTile) ? TileMixtureEnumerator.Empty - : new(atmosTile.AdjacentTiles); + : new TileMixtureEnumerator(atmosTile.AdjacentTiles); } - public void HotspotExpose(Entity grid, Vector2i tile, float exposedTemperature, float exposedVolume, - EntityUid? sparkSourceUid = null, bool soh = false) + /// + /// Exposes a tile to a hotspot of given temperature and volume, igniting it if conditions are met. + /// + /// The grid to expose the tile on. + /// The tile to expose. + /// The temperature of the hotspot to expose. + /// You can think of this as exposing a temperature of a flame. + /// The volume of the hotspot to expose. + /// You can think of this as how big the flame is initially. + /// Bigger flames will ramp a fire faster. + /// Whether to "boost" a fire that's currently on the tile already. + /// Does nothing if the tile isn't already a hotspot. + /// This clamps the temperature and volume of the hotspot to the maximum + /// of the provided parameters and whatever's on the tile. + /// Entity that started the exposure for admin logging. + [PublicAPI] + public void HotspotExpose(Entity grid, + Vector2i tile, + float exposedTemperature, + float exposedVolume, + EntityUid? sparkSourceUid = null, + bool soh = false) { if (!_atmosQuery.Resolve(grid, ref grid.Comp, false)) return; @@ -249,8 +427,26 @@ public partial class AtmosphereSystem HotspotExpose(grid.Comp, atmosTile, exposedTemperature, exposedVolume, soh, sparkSourceUid); } - public void HotspotExpose(TileAtmosphere tile, float exposedTemperature, float exposedVolume, - EntityUid? sparkSourceUid = null, bool soh = false) + /// + /// Exposes a tile to a hotspot of given temperature and volume, igniting it if conditions are met. + /// + /// The to expose. + /// The temperature of the hotspot to expose. + /// You can think of this as exposing a temperature of a flame. + /// The volume of the hotspot to expose. + /// You can think of this as how big the flame is initially. + /// Bigger flames will ramp a fire faster. + /// Whether to "boost" a fire that's currently on the tile already. + /// Does nothing if the tile isn't already a hotspot. + /// This clamps the temperature and volume of the hotspot to the maximum + /// of the provided parameters and whatever's on the tile. + /// Entity that started the exposure for admin logging. + [PublicAPI] + public void HotspotExpose(TileAtmosphere tile, + float exposedTemperature, + float exposedVolume, + EntityUid? sparkSourceUid = null, + bool soh = false) { if (!_atmosQuery.TryGetComponent(tile.GridIndex, out var atmos)) return; @@ -259,12 +455,25 @@ public partial class AtmosphereSystem HotspotExpose(atmos, tile, exposedTemperature, exposedVolume, soh, sparkSourceUid); } + /// + /// Extinguishes a hotspot on a tile. + /// + /// The grid to extinguish the hotspot on. + /// The tile on the grid to extinguish the hotspot on. + [PublicAPI] public void HotspotExtinguish(EntityUid gridUid, Vector2i tile) { var ev = new HotspotExtinguishMethodEvent(gridUid, tile); RaiseLocalEvent(gridUid, ref ev); } + /// + /// Checks if a hotspot is active on a tile. + /// + /// The grid to check. + /// The tile on the grid to check. + /// True if a hotspot is active on the tile, false otherwise. + [PublicAPI] public bool IsHotspotActive(EntityUid gridUid, Vector2i tile) { var ev = new IsHotspotActiveMethodEvent(gridUid, tile); @@ -274,11 +483,25 @@ public partial class AtmosphereSystem return ev.Result; } + /// + /// Adds a to a grid. + /// + /// The grid to add the pipe net to. + /// The pipe net to add. + /// True if the pipe net was added, false otherwise. + [PublicAPI] public bool AddPipeNet(Entity grid, PipeNet pipeNet) { return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Add(pipeNet); } + /// + /// Removes a from a grid. + /// + /// The grid to remove the pipe net from. + /// The pipe net to remove. + /// True if the pipe net was removed, false otherwise. + [PublicAPI] public bool RemovePipeNet(Entity grid, PipeNet pipeNet) { // Technically this event can be fired even on grids that don't @@ -292,6 +515,13 @@ public partial class AtmosphereSystem return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Remove(pipeNet); } + /// + /// Adds an entity with an to a grid's list of atmos devices. + /// + /// The grid to add the device to. + /// The device to add. + /// True if the device was added, false otherwise. + [PublicAPI] public bool AddAtmosDevice(Entity grid, Entity device) { DebugTools.Assert(device.Comp.JoinedGrid == null); @@ -307,6 +537,12 @@ public partial class AtmosphereSystem return true; } + /// + /// Removes an entity with an from a grid's list of atmos devices. + /// + /// The grid to remove the device from. + /// The device to remove. + /// True if the device was removed, false otherwise. public bool RemoveAtmosDevice(Entity grid, Entity device) { DebugTools.Assert(device.Comp.JoinedGrid == grid); @@ -418,23 +654,44 @@ public partial class AtmosphereSystem return contains; } - [ByRefEvent] private record struct SetSimulatedGridMethodEvent - (EntityUid Grid, bool Simulated, bool Handled = false); + [ByRefEvent] + private record struct SetSimulatedGridMethodEvent( + EntityUid Grid, + bool Simulated, + bool Handled = false); - [ByRefEvent] private record struct IsSimulatedGridMethodEvent - (EntityUid Grid, bool Simulated = false, bool Handled = false); + [ByRefEvent] + private record struct IsSimulatedGridMethodEvent( + EntityUid Grid, + bool Simulated = false, + bool Handled = false); - [ByRefEvent] private record struct GetAllMixturesMethodEvent - (EntityUid Grid, bool Excite = false, IEnumerable? Mixtures = null, bool Handled = false); + [ByRefEvent] + private record struct GetAllMixturesMethodEvent( + EntityUid Grid, + bool Excite = false, + IEnumerable? Mixtures = null, + bool Handled = false); - [ByRefEvent] private record struct ReactTileMethodEvent - (EntityUid GridId, Vector2i Tile, ReactionResult Result = default, bool Handled = false); + [ByRefEvent] + private record struct ReactTileMethodEvent( + EntityUid GridId, + Vector2i Tile, + ReactionResult Result = default, + bool Handled = false); - [ByRefEvent] private record struct HotspotExtinguishMethodEvent - (EntityUid Grid, Vector2i Tile, bool Handled = false); + [ByRefEvent] + private record struct HotspotExtinguishMethodEvent( + EntityUid Grid, + Vector2i Tile, + bool Handled = false); - [ByRefEvent] private record struct IsHotspotActiveMethodEvent - (EntityUid Grid, Vector2i Tile, bool Result = false, bool Handled = false); + [ByRefEvent] + private record struct IsHotspotActiveMethodEvent( + EntityUid Grid, + Vector2i Tile, + bool Result = false, + bool Handled = false); } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs index 596368f000..a402cf20f3 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs @@ -11,9 +11,15 @@ namespace Content.Server.Atmos.EntitySystems; public partial class AtmosphereSystem { + /* + Partial class that stores miscellaneous utility methods for Atmospherics. + */ + /// - /// Gets the particular price of an air mixture. + /// Gets the particular price of a . /// + /// The to get the price of. + /// The price of the gas mixture. public double GetPrice(GasMixture mixture) { float basePrice = 0; // moles of gas * price/mole @@ -26,7 +32,7 @@ public partial class AtmosphereSystem maxComponent = Math.Max(maxComponent, mixture.Moles[i]); } - // Pay more for gas canisters that are more pure + // Pay more for gas canisters that are purer float purity = 1; if (totalMoles > 0) { @@ -36,12 +42,32 @@ public partial class AtmosphereSystem return basePrice * purity; } + /// + /// Marks a tile's visual overlay as needing to be redetermined. + /// + /// A tile's overlay (how it looks like, ex. water vapor's texture) + /// is determined via determining how much gas there is on the tile. + /// This is expensive to do for every tile/gas that may have a custom overlay, + /// so its done once and only updated when it needs to be updated. + /// + /// The grid the tile is on. + /// The tile to invalidate. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void InvalidateVisuals(Entity grid, Vector2i tile) { _gasTileOverlaySystem.Invalidate(grid, tile); } + /// + /// Marks a tile's visual overlay as needing to be redetermined. + /// + /// A tile's overlay (how it looks like, ex. water vapor's texture) + /// is determined via determining how much gas there is on the tile. + /// This is expensive to do for every tile/gas that may have a custom overlay, + /// so its done once and only updated when it needs to be updated. + /// + /// The grid the tile is on. + /// The tile to invalidate. [MethodImpl(MethodImplOptions.AggressiveInlining)] private void InvalidateVisuals( Entity ent, @@ -51,7 +77,7 @@ public partial class AtmosphereSystem } /// - /// Gets the volume in liters for a number of tiles, on a specific grid. + /// Gets the volume in liters for a number of tiles, on a specific grid. /// /// The grid in question. /// The amount of tiles. @@ -79,6 +105,18 @@ public partial class AtmosphereSystem bool NoAirWhenBlocked, bool FixVacuum); + /// + /// Updates the for a + /// immediately. + /// + /// This method is extremely important if you are doing something in Atmospherics + /// that is time-sensitive! is cached and invalidated on + /// a cycle, so airtight changes performed during or after an invalidation will + /// not take effect until the next Atmospherics tick! + /// The entity the grid is on. + /// The the tile is on. + /// The the tile is on. + /// The to update. private void UpdateAirtightData(EntityUid uid, GridAtmosphereComponent atmos, MapGridComponent grid, TileAtmosphere tile) { var oldBlocked = tile.AirtightData.BlockedDirections; @@ -91,6 +129,15 @@ public partial class AtmosphereSystem ExcitedGroupDispose(atmos, tile.ExcitedGroup); } + /// + /// Retrieves current for a tile on a grid. + /// This is determined on-the-fly, not from cached data, so it will reflect + /// changes done in the current Atmospherics tick. + /// + /// The entity the grid is on. + /// The the tile is on. + /// The indices of the tile. + /// The current for the tile. private AirtightData GetAirtightData(EntityUid uid, MapGridComponent grid, Vector2i tile) { var blockedDirs = AtmosDirection.Invalid; @@ -118,7 +165,7 @@ public partial class AtmosphereSystem } /// - /// Pries a tile in a grid. + /// Pries a tile in a grid. /// /// The grid in question. /// The indices of the tile. diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index 69cc1c4165..1973daa5a1 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -35,6 +35,7 @@ public sealed partial class GameTicker private bool StartPreset(ICommonSession[] origReadyPlayers, bool force) { + _sawmill.Info($"Attempting to start preset '{CurrentPreset?.ID}'"); var startAttempt = new RoundStartAttemptEvent(origReadyPlayers, force); RaiseLocalEvent(startAttempt); @@ -56,9 +57,12 @@ public sealed partial class GameTicker var fallbackPresets = _cfg.GetCVar(CCVars.GameLobbyFallbackPreset).Split(","); var startFailed = true; + _sawmill.Info($"Fallback - Failed to start round, attempting to start fallback presets."); foreach (var preset in fallbackPresets) { + _sawmill.Info($"Fallback - Clearing up gamerules"); ClearGameRules(); + _sawmill.Info($"Fallback - Attempting to start '{preset}'"); SetGamePreset(preset, resetDelay: 1); AddGamePresetRules(); StartGamePresetRules(); @@ -76,6 +80,7 @@ public sealed partial class GameTicker startFailed = false; break; } + _sawmill.Info($"Fallback - '{preset}' failed to start."); } if (startFailed) @@ -87,6 +92,7 @@ public sealed partial class GameTicker else { + _sawmill.Info($"Fallback - Failed to start preset but fallbacks are disabled. Returning to Lobby."); FailedPresetRestart(); return false; } diff --git a/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs new file mode 100644 index 0000000000..742890226f --- /dev/null +++ b/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs @@ -0,0 +1,33 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.GameTicking.Rules.Components; + +[RegisterComponent, Access(typeof(XenoborgsRuleSystem))] +[AutoGenerateComponentPause] +public sealed partial class XenoborgsRuleComponent : Component +{ + /// + /// When the round will next check for round end. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan? NextRoundEndCheck; + + /// + /// The amount of time between each check for the end of the round. + /// + [DataField] + public TimeSpan EndCheckDelay = TimeSpan.FromSeconds(15); + + /// + /// After this amount of the crew become xenoborgs, the shuttle will be automatically called. + /// + [DataField] + public float XenoborgShuttleCallPercentage = 0.7f; + + /// + /// If the announcment of the death of the mothership core was sent + /// + [DataField] + public bool MothershipCoreDeathAnnouncmentSent = false; +} diff --git a/Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs b/Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs index 9ae8c5ff83..aafed20704 100644 --- a/Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs @@ -129,5 +129,6 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem : EntitySystem where T : ICompon while (query.MoveNext(out var uid, out _, out var gameRule)) { var minPlayers = gameRule.MinPlayers; + var name = ToPrettyString(uid); + if (args.Players.Length >= minPlayers) continue; @@ -46,8 +48,10 @@ public abstract partial class GameRuleSystem : EntitySystem where T : ICompon ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-players", ("readyPlayersCount", args.Players.Length), ("minimumPlayers", minPlayers), - ("presetName", ToPrettyString(uid)))); + ("presetName", name))); args.Cancel(); + //TODO remove this once announcements are logged + Log.Info($"Rule '{name}' requires {minPlayers} players, but only {args.Players.Length} are ready."); } else { diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index bf7056b3f4..e9f830e43a 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -112,6 +112,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem { args.AddLine(Loc.GetString("nukeops-list-name-user", ("name", name), ("user", sessionData.UserName))); } + args.AddLine(""); } private void OnNukeExploded(NukeExplodedEvent ev) diff --git a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs index ef773f59d1..d2cd27022f 100644 --- a/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RevolutionaryRuleSystem.cs @@ -118,6 +118,7 @@ public sealed class RevolutionaryRuleSystem : GameRuleSystem if (_whitelist.IsWhitelistFail(ent.Comp.SpawnerWhitelist, uid)) continue; + if (TryComp(uid, out var gridSpawnPointWhitelistComponent)) + { + if (!_whitelist.CheckBoth(args.Entity, gridSpawnPointWhitelistComponent.Blacklist, gridSpawnPointWhitelistComponent.Whitelist)) + continue; + } + args.Coordinates.Add(_transform.GetMapCoordinates(xform)); } } diff --git a/Content.Server/GameTicking/Rules/SurvivorRuleSystem.cs b/Content.Server/GameTicking/Rules/SurvivorRuleSystem.cs index d673444665..046ecedad6 100644 --- a/Content.Server/GameTicking/Rules/SurvivorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/SurvivorRuleSystem.cs @@ -106,6 +106,7 @@ public sealed class SurvivorRuleSystem : GameRuleSystem args.AddLine(Loc.GetString("survivor-round-end-dead-count", ("deadCount", deadSurvivors))); args.AddLine(Loc.GetString("survivor-round-end-alive-count", ("aliveCount", aliveMarooned))); args.AddLine(Loc.GetString("survivor-round-end-alive-on-shuttle-count", ("aliveCount", aliveOnShuttle))); + args.AddLine(""); // Player manifest at EOR shows who's a survivor so no need for extra info here. } diff --git a/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs b/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs new file mode 100644 index 0000000000..94b6315a6b --- /dev/null +++ b/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs @@ -0,0 +1,168 @@ +using Content.Server.Antag; +using Content.Server.Chat.Systems; +using Content.Server.GameTicking.Rules.Components; +using Content.Server.RoundEnd; +using Content.Server.Station.Systems; +using Content.Shared.Destructible; +using Content.Shared.GameTicking.Components; +using Content.Shared.Mind; +using Content.Shared.Mobs.Systems; +using Content.Shared.Xenoborgs.Components; +using Robust.Shared.Timing; + +namespace Content.Server.GameTicking.Rules; + +public sealed class XenoborgsRuleSystem : GameRuleSystem +{ + [Dependency] private readonly AntagSelectionSystem _antag = default!; + [Dependency] private readonly ChatSystem _chatSystem = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly RoundEndSystem _roundEnd = default!; + [Dependency] private readonly StationSystem _station = default!; + [Dependency] private readonly IGameTiming _timing = default!; + + private static readonly Color AnnouncmentColor = Color.Gold; + + public void SendXenoborgDeathAnnouncement(Entity ent, bool mothershipCoreAlive) + { + if (ent.Comp.MothershipCoreDeathAnnouncmentSent) + return; + + var status = mothershipCoreAlive ? "alive" : "dead"; + _chatSystem.DispatchGlobalAnnouncement( + Loc.GetString($"xenoborgs-no-more-threat-mothership-core-{status}-announcement"), + colorOverride: AnnouncmentColor); + } + + public void SendMothershipDeathAnnouncement(Entity ent) + { + _chatSystem.DispatchGlobalAnnouncement( + Loc.GetString("mothership-destroyed-announcement"), + colorOverride: AnnouncmentColor); + + ent.Comp.MothershipCoreDeathAnnouncmentSent = true; + } + + // TODO: Refactor the end of round text + protected override void AppendRoundEndText(EntityUid uid, + XenoborgsRuleComponent component, + GameRuleComponent gameRule, + ref RoundEndTextAppendEvent args) + { + base.AppendRoundEndText(uid, component, gameRule, ref args); + + var numXenoborgs = GetNumberXenoborgs(); + var numHumans = _mindSystem.GetAliveHumans().Count; + + if (numXenoborgs < 5) + args.AddLine(Loc.GetString("xenoborgs-crewmajor")); + else if (4 * numXenoborgs < numHumans) + args.AddLine(Loc.GetString("xenoborgs-crewmajor")); + else if (2 * numXenoborgs < numHumans) + args.AddLine(Loc.GetString("xenoborgs-crewminor")); + else if (1.5 * numXenoborgs < numHumans) + args.AddLine(Loc.GetString("xenoborgs-neutral")); + else if (numXenoborgs < numHumans) + args.AddLine(Loc.GetString("xenoborgs-borgsminor")); + else + args.AddLine(Loc.GetString("xenoborgs-borgsmajor")); + + var numMothershipCores = GetNumberMothershipCores(); + + if (numMothershipCores == 0) + args.AddLine(Loc.GetString("xenoborgs-cond-all-xenoborgs-dead-core-dead")); + else if (numXenoborgs == 0) + args.AddLine(Loc.GetString("xenoborgs-cond-all-xenoborgs-dead-core-alive")); + else + args.AddLine(Loc.GetString("xenoborgs-cond-xenoborgs-alive", ("count", numXenoborgs))); + + args.AddLine(Loc.GetString("xenoborgs-list-start")); + + var antags = _antag.GetAntagIdentifiers(uid); + + foreach (var (_, sessionData, name) in antags) + { + args.AddLine(Loc.GetString("xenoborgs-list", ("name", name), ("user", sessionData.UserName))); + } + args.AddLine(""); + } + + private void CheckRoundEnd(XenoborgsRuleComponent xenoborgsRuleComponent) + { + var numXenoborgs = GetNumberXenoborgs(); + var numHumans = _mindSystem.GetAliveHumans().Count; + + if ((float)numXenoborgs / (numHumans + numXenoborgs) > xenoborgsRuleComponent.XenoborgShuttleCallPercentage) + { + foreach (var station in _station.GetStations()) + { + _chatSystem.DispatchStationAnnouncement(station, Loc.GetString("xenoborg-shuttle-call"), colorOverride: Color.BlueViolet); + } + _roundEnd.RequestRoundEnd(null, false); + } + } + + protected override void Started(EntityUid uid, XenoborgsRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) + { + base.Started(uid, component, gameRule, args); + + component.NextRoundEndCheck = _timing.CurTime + component.EndCheckDelay; + } + + protected override void ActiveTick(EntityUid uid, XenoborgsRuleComponent component, GameRuleComponent gameRule, float frameTime) + { + base.ActiveTick(uid, component, gameRule, frameTime); + + if (!component.NextRoundEndCheck.HasValue || component.NextRoundEndCheck > _timing.CurTime) + return; + + CheckRoundEnd(component); + component.NextRoundEndCheck = _timing.CurTime + component.EndCheckDelay; + } + + /// + /// Get the number of xenoborgs + /// + /// if it should only include xenoborgs with a mind + /// if it should only include xenoborgs that are alive + /// the number of xenoborgs + private int GetNumberXenoborgs(bool playerControlled = true, bool alive = true) + { + var numberXenoborgs = 0; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var xenoborg, out _)) + { + if (HasComp(xenoborg)) + continue; + + if (playerControlled && !_mindSystem.TryGetMind(xenoborg, out _, out _)) + continue; + + if (alive && !_mobState.IsAlive(xenoborg)) + continue; + + numberXenoborgs++; + } + + return numberXenoborgs; + } + + /// + /// Gets the number of xenoborg cores + /// + /// the number of xenoborg cores + private int GetNumberMothershipCores() + { + var numberMothershipCores = 0; + + var mothershipCoreQuery = EntityQueryEnumerator(); + while (mothershipCoreQuery.MoveNext(out _, out _)) + { + numberMothershipCores++; + } + + return numberMothershipCores; + } +} diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index c6da622bb4..11f8d756a0 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -106,6 +106,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem ("name", meta.EntityName), ("username", username))); } + args.AddLine(""); } /// diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index af1a433d1a..3486e2024b 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -333,7 +333,8 @@ namespace Content.Server.Ghost if (_followerSystem.GetMostGhostFollowed() is not {} target) return; - WarpTo(uid, target); + // If there is a ghostnado happening you almost definitely wanna join it, so we automatically follow instead of just warping. + _followerSystem.StartFollowingEntity(uid, target); } private void WarpTo(EntityUid uid, EntityUid target) diff --git a/Content.Server/Gravity/GravityGeneratorComponent.cs b/Content.Server/Gravity/GravityGeneratorComponent.cs deleted file mode 100644 index c715a5e5f3..0000000000 --- a/Content.Server/Gravity/GravityGeneratorComponent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Content.Shared.Gravity; -using Content.Shared.Construction.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.Gravity -{ - [RegisterComponent] - [Access(typeof(GravityGeneratorSystem))] - public sealed partial class GravityGeneratorComponent : SharedGravityGeneratorComponent - { - [DataField("lightRadiusMin")] public float LightRadiusMin { get; set; } - [DataField("lightRadiusMax")] public float LightRadiusMax { get; set; } - - /// - /// Is the gravity generator currently "producing" gravity? - /// - [ViewVariables] - public bool GravityActive { get; set; } = false; - } -} diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 9d58b82d69..8e714cf884 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Gravity; namespace Content.Server.Gravity; -public sealed class GravityGeneratorSystem : EntitySystem +public sealed class GravityGeneratorSystem : SharedGravityGeneratorSystem { [Dependency] private readonly GravitySystem _gravitySystem = default!; [Dependency] private readonly SharedPointLightSystem _lights = default!; @@ -36,6 +36,7 @@ public sealed class GravityGeneratorSystem : EntitySystem private void OnActivated(Entity ent, ref ChargedMachineActivatedEvent args) { ent.Comp.GravityActive = true; + Dirty(ent, ent.Comp); var xform = Transform(ent); @@ -48,6 +49,7 @@ public sealed class GravityGeneratorSystem : EntitySystem private void OnDeactivated(Entity ent, ref ChargedMachineDeactivatedEvent args) { ent.Comp.GravityActive = false; + Dirty(ent, ent.Comp); var xform = Transform(ent); diff --git a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs index 0aea245c79..eddef87853 100644 --- a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs +++ b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs @@ -145,7 +145,7 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem { if (entity.Comp.State == EmergencyLightState.On) { - if (!_battery.TryUseCharge(entity.Owner, entity.Comp.Wattage * frameTime, battery)) + if (!_battery.TryUseCharge((entity.Owner, battery), entity.Comp.Wattage * frameTime)) { SetState(entity.Owner, entity.Comp, EmergencyLightState.Empty); TurnOff(entity); @@ -153,8 +153,8 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem } else { - _battery.SetCharge(entity.Owner, battery.CurrentCharge + entity.Comp.ChargingWattage * frameTime * entity.Comp.ChargingEfficiency, battery); - if (_battery.IsFull(entity, battery)) + _battery.SetCharge((entity.Owner, battery), battery.CurrentCharge + entity.Comp.ChargingWattage * frameTime * entity.Comp.ChargingEfficiency); + if (_battery.IsFull((entity.Owner, battery))) { if (TryComp(entity.Owner, out var receiver)) { diff --git a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs index 2c8d18539f..7167aa4963 100644 --- a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs +++ b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs @@ -253,7 +253,7 @@ namespace Content.Server.Light.EntitySystems _appearance.SetData(uid, HandheldLightVisuals.Power, HandheldLightPowerStates.Dying, appearanceComponent); } - if (component.Activated && !_battery.TryUseCharge(batteryUid.Value, component.Wattage * frameTime, battery)) + if (component.Activated && !_battery.TryUseCharge((batteryUid.Value, battery), component.Wattage * frameTime)) TurnOff(uid, false); UpdateLevel(uid); diff --git a/Content.Server/Mech/Systems/MechSystem.cs b/Content.Server/Mech/Systems/MechSystem.cs index 923c701868..89297a6e86 100644 --- a/Content.Server/Mech/Systems/MechSystem.cs +++ b/Content.Server/Mech/Systems/MechSystem.cs @@ -340,7 +340,7 @@ public sealed partial class MechSystem : SharedMechSystem if (!TryComp(battery, out var batteryComp)) return false; - _battery.SetCharge(battery!.Value, batteryComp.CurrentCharge + delta.Float(), batteryComp); + _battery.SetCharge((battery.Value, batteryComp), batteryComp.CurrentCharge + delta.Float()); if (batteryComp.CurrentCharge != component.Energy) //if there's a discrepency, we have to resync them { Log.Debug($"Battery charge was not equal to mech charge. Battery {batteryComp.CurrentCharge}. Mech {component.Energy}"); diff --git a/Content.Server/Ninja/Systems/BatteryDrainerSystem.cs b/Content.Server/Ninja/Systems/BatteryDrainerSystem.cs index e563386608..7b9d229d73 100644 --- a/Content.Server/Ninja/Systems/BatteryDrainerSystem.cs +++ b/Content.Server/Ninja/Systems/BatteryDrainerSystem.cs @@ -95,17 +95,17 @@ public sealed class BatteryDrainerSystem : SharedBatteryDrainerSystem // higher tier storages can charge more var maxDrained = pnb.MaxSupply * comp.DrainTime; var input = Math.Min(Math.Min(available, required / comp.DrainEfficiency), maxDrained); - if (!_battery.TryUseCharge(target, input, targetBattery)) + if (!_battery.TryUseCharge((target, targetBattery), input)) return false; var output = input * comp.DrainEfficiency; - _battery.SetCharge(comp.BatteryUid.Value, battery.CurrentCharge + output, battery); + _battery.SetCharge((comp.BatteryUid.Value, battery), battery.CurrentCharge + output); // TODO: create effect message or something Spawn("EffectSparks", Transform(target).Coordinates); _audio.PlayPvs(comp.SparkSound, target); _popup.PopupEntity(Loc.GetString("battery-drainer-success", ("battery", target)), uid, uid); // repeat the doafter until battery is full - return !_battery.IsFull(comp.BatteryUid.Value, battery); + return !_battery.IsFull((comp.BatteryUid.Value, battery)); } } diff --git a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs index ff88926723..fd7f908738 100644 --- a/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs +++ b/Content.Server/Ninja/Systems/SpaceNinjaSystem.cs @@ -106,7 +106,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem /// public override bool TryUseCharge(EntityUid user, float charge) { - return GetNinjaBattery(user, out var uid, out var battery) && _battery.TryUseCharge(uid.Value, charge, battery); + return GetNinjaBattery(user, out var uid, out var battery) && _battery.TryUseCharge((uid.Value, battery), charge); } /// diff --git a/Content.Server/Power/Components/BatterySelfRechargerComponent.cs b/Content.Server/Power/Components/BatterySelfRechargerComponent.cs deleted file mode 100644 index 1cb92d9cd6..0000000000 --- a/Content.Server/Power/Components/BatterySelfRechargerComponent.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace Content.Server.Power.Components -{ - /// - /// Self-recharging battery. - /// - [RegisterComponent] - public sealed partial class BatterySelfRechargerComponent : Component - { - /// - /// Does the entity auto recharge? - /// - [DataField] public bool AutoRecharge; - - /// - /// At what rate does the entity automatically recharge? - /// - [DataField] public float AutoRechargeRate; - - /// - /// Should this entity stop automatically recharging if a charge is used? - /// - [DataField] public bool AutoRechargePause = false; - - /// - /// How long should the entity stop automatically recharging if a charge is used? - /// - [DataField] public float AutoRechargePauseTime = 0f; - - /// - /// Do not auto recharge if this timestamp has yet to happen, set for the auto recharge pause system. - /// - [DataField] public TimeSpan NextAutoRecharge = TimeSpan.FromSeconds(0f); - } -} diff --git a/Content.Server/Power/EntitySystems/BatterySystem.API.cs b/Content.Server/Power/EntitySystems/BatterySystem.API.cs new file mode 100644 index 0000000000..6ddf1f4bbc --- /dev/null +++ b/Content.Server/Power/EntitySystems/BatterySystem.API.cs @@ -0,0 +1,104 @@ +using Content.Shared.Power; +using Content.Shared.Power.Components; + +namespace Content.Server.Power.EntitySystems; + +public sealed partial class BatterySystem +{ + public override float ChangeCharge(Entity ent, float amount) + { + if (!Resolve(ent, ref ent.Comp)) + return 0; + + var newValue = Math.Clamp(ent.Comp.CurrentCharge + amount, 0, ent.Comp.MaxCharge); + var delta = newValue - ent.Comp.CurrentCharge; + ent.Comp.CurrentCharge = newValue; + + TrySetChargeCooldown(ent.Owner); + + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + RaiseLocalEvent(ent, ref ev); + return delta; + } + + public override float UseCharge(Entity ent, float amount) + { + if (amount <= 0 || !Resolve(ent, ref ent.Comp) || ent.Comp.CurrentCharge == 0) + return 0; + + return ChangeCharge(ent, -amount); + } + + public override bool TryUseCharge(Entity ent, float amount) + { + if (!Resolve(ent, ref ent.Comp, false) || amount > ent.Comp.CurrentCharge) + return false; + + UseCharge(ent, amount); + return true; + } + + public override void SetCharge(Entity ent, float value) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + var oldCharge = ent.Comp.CurrentCharge; + ent.Comp.CurrentCharge = MathHelper.Clamp(value, 0, ent.Comp.MaxCharge); + if (MathHelper.CloseTo(ent.Comp.CurrentCharge, oldCharge) && + !(oldCharge != ent.Comp.CurrentCharge && ent.Comp.CurrentCharge == ent.Comp.MaxCharge)) + { + return; + } + + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + RaiseLocalEvent(ent, ref ev); + } + public override void SetMaxCharge(Entity ent, float value) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + var old = ent.Comp.MaxCharge; + ent.Comp.MaxCharge = Math.Max(value, 0); + ent.Comp.CurrentCharge = Math.Min(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + if (MathHelper.CloseTo(ent.Comp.MaxCharge, old)) + return; + + var ev = new ChargeChangedEvent(ent.Comp.CurrentCharge, ent.Comp.MaxCharge); + RaiseLocalEvent(ent, ref ev); + } + + public override void TrySetChargeCooldown(Entity ent) + { + if (!Resolve(ent, ref ent.Comp, false)) + return; + + if (ent.Comp.AutoRechargePauseTime == TimeSpan.Zero) + return; // no recharge pause + + if (_timing.CurTime + ent.Comp.AutoRechargePauseTime <= ent.Comp.NextAutoRecharge) + return; // the current pause is already longer + + SetChargeCooldown(ent, ent.Comp.AutoRechargePauseTime); + } + + public override void SetChargeCooldown(Entity ent, TimeSpan cooldown) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + ent.Comp.NextAutoRecharge = _timing.CurTime + cooldown; + } + + /// + /// Returns whether the battery is full. + /// + public bool IsFull(Entity ent) + { + if (!Resolve(ent, ref ent.Comp)) + return false; + + return ent.Comp.CurrentCharge >= ent.Comp.MaxCharge; + } +} diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs index c49a2f0f6b..4b6a52c0f1 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -9,232 +9,115 @@ using JetBrains.Annotations; using Robust.Shared.Utility; using Robust.Shared.Timing; -namespace Content.Server.Power.EntitySystems +namespace Content.Server.Power.EntitySystems; + +[UsedImplicitly] +public sealed partial class BatterySystem : SharedBatterySystem { - [UsedImplicitly] - public sealed class BatterySystem : SharedBatterySystem + [Dependency] private readonly IGameTiming _timing = default!; + + public override void Initialize() { - [Dependency] private readonly IGameTiming _timing = default!; + base.Initialize(); - public override void Initialize() + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnBatteryRejuvenate); + SubscribeLocalEvent(OnNetBatteryRejuvenate); + SubscribeLocalEvent(CalculateBatteryPrice); + SubscribeLocalEvent(OnChangeCharge); + SubscribeLocalEvent(OnGetCharge); + + SubscribeLocalEvent(PreSync); + SubscribeLocalEvent(PostSync); + } + + private void OnNetBatteryRejuvenate(Entity ent, ref RejuvenateEvent args) + { + ent.Comp.NetworkBattery.CurrentStorage = ent.Comp.NetworkBattery.Capacity; + } + + private void OnBatteryRejuvenate(Entity ent, ref RejuvenateEvent args) + { + SetCharge(ent.AsNullable(), ent.Comp.MaxCharge); + } + + private void OnExamine(Entity ent, ref ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + if (!TryComp(ent, out var battery)) + return; + + var chargePercentRounded = 0; + if (battery.MaxCharge != 0) + chargePercentRounded = (int)(100 * battery.CurrentCharge / battery.MaxCharge); + args.PushMarkup( + Loc.GetString( + "examinable-battery-component-examine-detail", + ("percent", chargePercentRounded), + ("markupPercentColor", "green") + ) + ); + } + + private void PreSync(NetworkBatteryPreSync ev) + { + // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. + var enumerator = AllEntityQuery(); + while (enumerator.MoveNext(out var netBat, out var bat)) { - base.Initialize(); - - SubscribeLocalEvent(OnExamine); - SubscribeLocalEvent(OnNetBatteryRejuvenate); - SubscribeLocalEvent(OnBatteryRejuvenate); - SubscribeLocalEvent(CalculateBatteryPrice); - SubscribeLocalEvent(OnChangeCharge); - SubscribeLocalEvent(OnGetCharge); - - SubscribeLocalEvent(PreSync); - SubscribeLocalEvent(PostSync); + DebugTools.Assert(bat.CurrentCharge <= bat.MaxCharge && bat.CurrentCharge >= 0); + netBat.NetworkBattery.Capacity = bat.MaxCharge; + netBat.NetworkBattery.CurrentStorage = bat.CurrentCharge; } + } - private void OnNetBatteryRejuvenate(EntityUid uid, PowerNetworkBatteryComponent component, RejuvenateEvent args) + private void PostSync(NetworkBatteryPostSync ev) + { + // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. + var enumerator = AllEntityQuery(); + while (enumerator.MoveNext(out var uid, out var netBat, out var bat)) { - component.NetworkBattery.CurrentStorage = component.NetworkBattery.Capacity; + SetCharge((uid, bat), netBat.NetworkBattery.CurrentStorage); } + } - private void OnBatteryRejuvenate(EntityUid uid, BatteryComponent component, RejuvenateEvent args) + /// + /// Gets the price for the power contained in an entity's battery. + /// + private void CalculateBatteryPrice(Entity ent, ref PriceCalculationEvent args) + { + args.Price += ent.Comp.CurrentCharge * ent.Comp.PricePerJoule; + } + + private void OnChangeCharge(Entity ent, ref ChangeChargeEvent args) + { + if (args.ResidualValue == 0) + return; + + args.ResidualValue -= ChangeCharge(ent.AsNullable(), args.ResidualValue); + } + + private void OnGetCharge(Entity entity, ref GetChargeEvent args) + { + args.CurrentCharge += entity.Comp.CurrentCharge; + args.MaxCharge += entity.Comp.MaxCharge; + } + + public override void Update(float frameTime) + { + var query = EntityQueryEnumerator(); + var curTime = _timing.CurTime; + while (query.MoveNext(out var uid, out var comp, out var bat)) { - SetCharge(uid, component.MaxCharge, component); - } + if (!comp.AutoRecharge || IsFull((uid, bat))) + continue; - private void OnExamine(EntityUid uid, ExaminableBatteryComponent component, ExaminedEvent args) - { - if (!TryComp(uid, out var batteryComponent)) - return; - if (args.IsInDetailsRange) - { - var effectiveMax = batteryComponent.MaxCharge; - if (effectiveMax == 0) - effectiveMax = 1; - var chargeFraction = batteryComponent.CurrentCharge / effectiveMax; - var chargePercentRounded = (int)(chargeFraction * 100); - args.PushMarkup( - Loc.GetString( - "examinable-battery-component-examine-detail", - ("percent", chargePercentRounded), - ("markupPercentColor", "green") - ) - ); - } - } + if (comp.NextAutoRecharge > curTime) + continue; - private void PreSync(NetworkBatteryPreSync ev) - { - // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. - var enumerator = AllEntityQuery(); - while (enumerator.MoveNext(out var netBat, out var bat)) - { - DebugTools.Assert(bat.CurrentCharge <= bat.MaxCharge && bat.CurrentCharge >= 0); - netBat.NetworkBattery.Capacity = bat.MaxCharge; - netBat.NetworkBattery.CurrentStorage = bat.CurrentCharge; - } - } - - private void PostSync(NetworkBatteryPostSync ev) - { - // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. - var enumerator = AllEntityQuery(); - while (enumerator.MoveNext(out var uid, out var netBat, out var bat)) - { - SetCharge(uid, netBat.NetworkBattery.CurrentStorage, bat); - } - } - - public override void Update(float frameTime) - { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var comp, out var batt)) - { - if (!comp.AutoRecharge || IsFull(uid, batt)) - continue; - - if (comp.AutoRechargePause) - { - if (comp.NextAutoRecharge > _timing.CurTime) - continue; - } - - SetCharge(uid, batt.CurrentCharge + comp.AutoRechargeRate * frameTime, batt); - } - } - - /// - /// Gets the price for the power contained in an entity's battery. - /// - private void CalculateBatteryPrice(EntityUid uid, BatteryComponent component, ref PriceCalculationEvent args) - { - args.Price += component.CurrentCharge * component.PricePerJoule; - } - private void OnChangeCharge(Entity entity, ref ChangeChargeEvent args) - { - if (args.ResidualValue == 0) - return; - - args.ResidualValue -= ChangeCharge(entity, args.ResidualValue); - } - - private void OnGetCharge(Entity entity, ref GetChargeEvent args) - { - args.CurrentCharge += entity.Comp.CurrentCharge; - args.MaxCharge += entity.Comp.MaxCharge; - } - - public override float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0) - return 0; - - return ChangeCharge(uid, -value, battery); - } - - public override void SetMaxCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref battery)) - return; - - var old = battery.MaxCharge; - battery.MaxCharge = Math.Max(value, 0); - battery.CurrentCharge = Math.Min(battery.CurrentCharge, battery.MaxCharge); - if (MathHelper.CloseTo(battery.MaxCharge, old)) - return; - - var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge); - RaiseLocalEvent(uid, ref ev); - } - - public void SetCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref battery)) - return; - - var old = battery.CurrentCharge; - battery.CurrentCharge = MathHelper.Clamp(value, 0, battery.MaxCharge); - if (MathHelper.CloseTo(battery.CurrentCharge, old) && - !(old != battery.CurrentCharge && battery.CurrentCharge == battery.MaxCharge)) - { - return; - } - - var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge); - RaiseLocalEvent(uid, ref ev); - } - - /// - /// Changes the current battery charge by some value - /// - public override float ChangeCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref battery)) - return 0; - - var newValue = Math.Clamp(battery.CurrentCharge + value, 0, battery.MaxCharge); - var delta = newValue - battery.CurrentCharge; - battery.CurrentCharge = newValue; - - TrySetChargeCooldown(uid); - - var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge); - RaiseLocalEvent(uid, ref ev); - return delta; - } - - public override void TrySetChargeCooldown(EntityUid uid, float value = -1) - { - if (!TryComp(uid, out var batteryself)) - return; - - if (!batteryself.AutoRechargePause) - return; - - // If no answer or a negative is given for value, use the default from AutoRechargePauseTime. - if (value < 0) - value = batteryself.AutoRechargePauseTime; - - if (_timing.CurTime + TimeSpan.FromSeconds(value) <= batteryself.NextAutoRecharge) - return; - - SetChargeCooldown(uid, batteryself.AutoRechargePauseTime, batteryself); - } - - /// - /// Puts the entity's self recharge on cooldown for the specified time. - /// - public void SetChargeCooldown(EntityUid uid, float value, BatterySelfRechargerComponent? batteryself = null) - { - if (!Resolve(uid, ref batteryself)) - return; - - if (value >= 0) - batteryself.NextAutoRecharge = _timing.CurTime + TimeSpan.FromSeconds(value); - else - batteryself.NextAutoRecharge = _timing.CurTime; - } - - /// - /// If sufficient charge is available on the battery, use it. Otherwise, don't. - /// - public override bool TryUseCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref battery, false) || value > battery.CurrentCharge) - return false; - - UseCharge(uid, value, battery); - return true; - } - - /// - /// Returns whether the battery is full. - /// - public bool IsFull(EntityUid uid, BatteryComponent? battery = null) - { - if (!Resolve(uid, ref battery)) - return false; - - return battery.CurrentCharge >= battery.MaxCharge; + SetCharge((uid, bat), bat.CurrentCharge + comp.AutoRechargeRate * frameTime); } } } diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index e8dc9e9962..d523de65db 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -221,7 +221,7 @@ public sealed class ChargerSystem : SharedChargerSystem if (!SearchForBattery(container.ContainedEntities[0], out var heldEnt, out var heldBattery)) return CellChargerStatus.Off; - if (_battery.IsFull(heldEnt.Value, heldBattery)) + if (_battery.IsFull((heldEnt.Value, heldBattery))) return CellChargerStatus.Charged; return CellChargerStatus.Charging; @@ -241,7 +241,7 @@ public sealed class ChargerSystem : SharedChargerSystem if (!SearchForBattery(targetEntity, out var batteryUid, out var heldBattery)) return; - _battery.SetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); + _battery.SetCharge((batteryUid.Value, heldBattery), heldBattery.CurrentCharge + component.ChargeRate * frameTime); UpdateStatus(uid, component); } diff --git a/Content.Server/Power/EntitySystems/PowerNetSystem.cs b/Content.Server/Power/EntitySystems/PowerNetSystem.cs index 6a69550fcf..5b6b922ddf 100644 --- a/Content.Server/Power/EntitySystems/PowerNetSystem.cs +++ b/Content.Server/Power/EntitySystems/PowerNetSystem.cs @@ -358,13 +358,13 @@ namespace Content.Server.Power.EntitySystems if (requireBattery) { - _battery.SetCharge(uid, battery.CurrentCharge - apcBattery.IdleLoad * frameTime, battery); + _battery.SetCharge((uid, battery), battery.CurrentCharge - apcBattery.IdleLoad * frameTime); } // Otherwise try to charge the battery - else if (powered && !_battery.IsFull(uid, battery)) + else if (powered && !_battery.IsFull((uid, battery))) { apcReceiver.Load += apcBattery.BatteryRechargeRate * apcBattery.BatteryRechargeEfficiency; - _battery.SetCharge(uid, battery.CurrentCharge + apcBattery.BatteryRechargeRate * frameTime, battery); + _battery.SetCharge((uid, battery), battery.CurrentCharge + apcBattery.BatteryRechargeRate * frameTime); } // Enable / disable the battery if the state changed diff --git a/Content.Server/Power/SetBatteryPercentCommand.cs b/Content.Server/Power/SetBatteryPercentCommand.cs index 03d6d30f8a..a6123382fd 100644 --- a/Content.Server/Power/SetBatteryPercentCommand.cs +++ b/Content.Server/Power/SetBatteryPercentCommand.cs @@ -40,7 +40,7 @@ namespace Content.Server.Power shell.WriteLine(Loc.GetString($"cmd-setbatterypercent-battery-not-found", ("id", id))); return; } - _batterySystem.SetCharge(id.Value, battery.MaxCharge * percent / 100, battery); + _batterySystem.SetCharge((id.Value, battery), battery.MaxCharge * percent / 100); // Don't acknowledge b/c people WILL forall this } } diff --git a/Content.Server/PowerCell/PowerCellSystem.Draw.cs b/Content.Server/PowerCell/PowerCellSystem.Draw.cs index 40e54ba13a..d0dafb1ef6 100644 --- a/Content.Server/PowerCell/PowerCellSystem.Draw.cs +++ b/Content.Server/PowerCell/PowerCellSystem.Draw.cs @@ -28,7 +28,7 @@ public sealed partial class PowerCellSystem if (!TryGetBatteryFromSlot(uid, out var batteryEnt, out var battery, slot)) continue; - if (_battery.TryUseCharge(batteryEnt.Value, comp.DrawRate * (float)comp.Delay.TotalSeconds, battery)) + if (_battery.TryUseCharge((batteryEnt.Value, battery), comp.DrawRate * (float)comp.Delay.TotalSeconds)) continue; var ev = new PowerCellSlotEmptyEvent(); diff --git a/Content.Server/PowerCell/PowerCellSystem.cs b/Content.Server/PowerCell/PowerCellSystem.cs index 6c00cdd300..f358e1bc34 100644 --- a/Content.Server/PowerCell/PowerCellSystem.cs +++ b/Content.Server/PowerCell/PowerCellSystem.cs @@ -174,7 +174,7 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem return false; } - if (!_battery.TryUseCharge(batteryEnt.Value, charge, battery)) + if (!_battery.TryUseCharge((batteryEnt.Value, battery), charge)) { if (user != null) _popup.PopupEntity(Loc.GetString("power-cell-insufficient"), uid, user.Value); diff --git a/Content.Server/PowerSink/PowerSinkSystem.cs b/Content.Server/PowerSink/PowerSinkSystem.cs index d1071d3e38..328bff89f4 100644 --- a/Content.Server/PowerSink/PowerSinkSystem.cs +++ b/Content.Server/PowerSink/PowerSinkSystem.cs @@ -66,7 +66,7 @@ namespace Content.Server.PowerSink if (!transform.Anchored) continue; - _battery.ChangeCharge(entity, networkLoad.NetworkLoad.ReceivingPower * frameTime, battery); + _battery.ChangeCharge((entity, battery), networkLoad.NetworkLoad.ReceivingPower * frameTime); var currentBatteryThreshold = battery.CurrentCharge / battery.MaxCharge; diff --git a/Content.Server/Radio/EntitySystems/JammerSystem.cs b/Content.Server/Radio/EntitySystems/JammerSystem.cs index 02c9c64c6e..3ec2e9c38c 100644 --- a/Content.Server/Radio/EntitySystems/JammerSystem.cs +++ b/Content.Server/Radio/EntitySystems/JammerSystem.cs @@ -34,7 +34,7 @@ public sealed class JammerSystem : SharedJammerSystem if (_powerCell.TryGetBatteryFromSlot(uid, out var batteryUid, out var battery)) { - if (!_battery.TryUseCharge(batteryUid.Value, GetCurrentWattage((uid, jam)) * frameTime, battery)) + if (!_battery.TryUseCharge((batteryUid.Value, battery), GetCurrentWattage((uid, jam)) * frameTime)) { ChangeLEDState(uid, false); RemComp(uid); diff --git a/Content.Server/Roles/RoleSystem.cs b/Content.Server/Roles/RoleSystem.cs index 71fb8a9cb5..abf9dd50ec 100644 --- a/Content.Server/Roles/RoleSystem.cs +++ b/Content.Server/Roles/RoleSystem.cs @@ -15,7 +15,7 @@ public sealed class RoleSystem : SharedRoleSystem { if (mindId == null) { - Log.Error($"MingGetBriefing failed for mind {mindId}"); + Log.Error($"MindGetBriefing failed for mind {mindId}"); return null; } @@ -23,7 +23,7 @@ public sealed class RoleSystem : SharedRoleSystem if (mindComp is null) { - Log.Error($"MingGetBriefing failed for mind {mindId}"); + Log.Error($"MindGetBriefing failed for mind {mindId}"); return null; } diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index 4ca0b53035..a63359077f 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -801,7 +801,11 @@ public sealed partial class ShuttleSystem while (iteration < FTLProximityIterations) { grids.Clear(); - _mapManager.FindGridsIntersecting(mapId, targetAABB, ref grids); + // We pass in an expanded offset here so we can safely do a random offset later. + // We don't include this in the actual targetAABB because then we would be double-expanding it. + // Once in this loop, then again when placing the shuttle later. + // Note that targetAABB already has expansionAmount factored in already. + _mapManager.FindGridsIntersecting(mapId, targetAABB.Enlarged(maxOffset), ref grids); foreach (var grid in grids) { @@ -834,10 +838,6 @@ public sealed partial class ShuttleSystem if (nearbyGrids.Contains(uid)) continue; - // We pass in an expanded offset here so we can safely do a random offset later. - // We don't include this in the actual targetAABB because then we would be double-expanding it. - // Once in this loop, then again when placing the shuttle later. - // Note that targetAABB already has expansionAmount factored in already. targetAABB = targetAABB.Union( _transform.GetWorldMatrix(uid) .TransformBox(Comp(uid).LocalAABB.Enlarged(expansionAmount))); @@ -857,7 +857,7 @@ public sealed partial class ShuttleSystem // TODO: This should prefer the position's angle instead. // TODO: This is pretty crude for multiple landings. - if (nearbyGrids.Count >= 1) + if (nearbyGrids.Count > 1 || !HasComp(targetXform.GridUid)) { // Pick a random angle var offsetAngle = _random.NextAngle(); @@ -866,9 +866,13 @@ public sealed partial class ShuttleSystem var minRadius = MathF.Max(targetAABB.Width / 2f, targetAABB.Height / 2f); spawnPos = targetAABB.Center + offsetAngle.RotateVec(new Vector2(_random.NextFloat(minRadius + minOffset, minRadius + maxOffset), 0f)); } + else if (shuttleBody != null) + { + (spawnPos, angle) = _transform.GetWorldPositionRotation(targetXform); + } else { - spawnPos = _transform.ToWorldPosition(targetCoordinates); + spawnPos = _transform.GetWorldPosition(targetXform); } var offset = Vector2.Zero; @@ -889,10 +893,10 @@ public sealed partial class ShuttleSystem } // Rotate our localcenter around so we spawn exactly where we "think" we should (center of grid on the dot). - var transform = new Transform(_transform.ToWorldPosition(xform.Coordinates), angle); - var adjustedOffset = Robust.Shared.Physics.Transform.Mul(transform, offset); + var transform = new Transform(spawnPos, angle); + spawnPos = Robust.Shared.Physics.Transform.Mul(transform, offset); - coordinates = new EntityCoordinates(targetXform.MapUid.Value, spawnPos + adjustedOffset); + coordinates = new EntityCoordinates(targetXform.MapUid.Value, spawnPos - offset); return true; } diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs b/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs index fd3b910753..8dd074e6a0 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs @@ -98,7 +98,7 @@ public sealed partial class BorgSystem if (command == RoboticsConsoleConstants.NET_DISABLE_COMMAND) Disable(ent); else if (command == RoboticsConsoleConstants.NET_DESTROY_COMMAND) - Destroy(ent); + Destroy(ent.Owner); } private void Disable(Entity ent) @@ -118,8 +118,15 @@ public sealed partial class BorgSystem ent.Comp1.NextDisable = _timing.CurTime + ent.Comp1.DisableDelay; } - private void Destroy(Entity ent) + /// + /// Makes a borg with explode + /// + /// the entity of the borg + public void Destroy(Entity ent) { + if (!Resolve(ent, ref ent.Comp)) + return; + // this is stealthy until someone realises you havent exploded if (CheckEmagged(ent, "destroyed")) { diff --git a/Content.Server/Silicons/StationAi/StationAiSystem.cs b/Content.Server/Silicons/StationAi/StationAiSystem.cs index a9198d5816..0045b921e5 100644 --- a/Content.Server/Silicons/StationAi/StationAiSystem.cs +++ b/Content.Server/Silicons/StationAi/StationAiSystem.cs @@ -125,7 +125,7 @@ public sealed class StationAiSystem : SharedStationAiSystem // into an AI core that has a full battery and full integrity. if (TryComp(ent, out var battery)) { - _battery.SetCharge(ent, battery.MaxCharge); + _battery.SetCharge((ent, battery), battery.MaxCharge); } _damageable.ClearAllDamage(ent.Owner); diff --git a/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs b/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs new file mode 100644 index 0000000000..de9f71f0f8 --- /dev/null +++ b/Content.Server/Spawners/Components/GridSpawnPointWhitelistComponent.cs @@ -0,0 +1,22 @@ +using Content.Shared.Whitelist; + +namespace Content.Server.Spawners.Components; + +/// +/// Defines whitelist and blacklist for entities that can spawn at a spawnpoint when they are spawned via the +/// +[RegisterComponent] +public sealed partial class GridSpawnPointWhitelistComponent : Component +{ + /// + /// Whitelist of entities that can be spawned at this SpawnPoint + /// + [DataField] + public EntityWhitelist? Whitelist; + + /// + /// Whitelist of entities that can't be spawned at this SpawnPoint + /// + [DataField] + public EntityWhitelist? Blacklist; +} diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index 7f8aa37036..a22a4c09fa 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -33,7 +33,7 @@ namespace Content.Server.Stunnable.Systems private void OnStaminaHitAttempt(Entity entity, ref StaminaDamageOnHitAttemptEvent args) { if (!_itemToggle.IsActivated(entity.Owner) || - !TryComp(entity.Owner, out var battery) || !_battery.TryUseCharge(entity.Owner, entity.Comp.EnergyPerUse, battery)) + !TryComp(entity.Owner, out var battery) || !_battery.TryUseCharge((entity.Owner, battery), entity.Comp.EnergyPerUse)) { args.Cancelled = true; } diff --git a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs index f3cae90b40..988ade86ce 100644 --- a/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs +++ b/Content.Server/Tesla/EntitySystem/TeslaCoilSystem.cs @@ -24,7 +24,7 @@ public sealed class TeslaCoilSystem : EntitySystem { if (TryComp(coil, out var batteryComponent)) { - _battery.SetCharge(coil, batteryComponent.CurrentCharge + coil.Comp.ChargeFromLightning); + _battery.SetCharge((coil, batteryComponent), batteryComponent.CurrentCharge + coil.Comp.ChargeFromLightning); } } } diff --git a/Content.Server/Tips/TipsSystem.cs b/Content.Server/Tips/TipsSystem.cs index cd7f7b52f5..406ee76ca6 100644 --- a/Content.Server/Tips/TipsSystem.cs +++ b/Content.Server/Tips/TipsSystem.cs @@ -4,10 +4,7 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Dataset; using Content.Shared.Tips; -using Robust.Server.GameObjects; -using Robust.Server.Player; using Robust.Shared.Configuration; -using Robust.Shared.Console; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -15,10 +12,7 @@ using Robust.Shared.Timing; namespace Content.Server.Tips; -/// -/// Handles periodically displaying gameplay tips to all players ingame. -/// -public sealed class TipsSystem : EntitySystem +public sealed class TipsSystem : SharedTipsSystem { [Dependency] private readonly IChatManager _chat = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; @@ -26,8 +20,6 @@ public sealed class TipsSystem : EntitySystem [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly GameTicker _ticker = default!; - [Dependency] private readonly IConsoleHost _conHost = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; private bool _tipsEnabled; private float _tipTimeOutOfRound; @@ -35,16 +27,6 @@ public sealed class TipsSystem : EntitySystem private string _tipsDataset = ""; private float _tipTippyChance; - /// - /// Always adds this time to a speech message. This is so really short message stay around for a bit. - /// - private const float SpeechBuffer = 3f; - - /// - /// Expected reading speed. - /// - private const float Wpm = 180f; - [ViewVariables(VVAccess.ReadWrite)] private TimeSpan _nextTipTime = TimeSpan.Zero; @@ -53,110 +35,45 @@ public sealed class TipsSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnGameRunLevelChanged); - Subs.CVar(_cfg, CCVars.TipFrequencyOutOfRound, SetOutOfRound, true); - Subs.CVar(_cfg, CCVars.TipFrequencyInRound, SetInRound, true); Subs.CVar(_cfg, CCVars.TipsEnabled, SetEnabled, true); - Subs.CVar(_cfg, CCVars.TipsDataset, SetDataset, true); - Subs.CVar(_cfg, CCVars.TipsTippyChance, SetTippyChance, true); + Subs.CVar(_cfg, CCVars.TipFrequencyOutOfRound, value => _tipTimeOutOfRound = value, true); + Subs.CVar(_cfg, CCVars.TipFrequencyInRound, value => _tipTimeInRound = value, true); + Subs.CVar(_cfg, CCVars.TipsDataset, value => _tipsDataset = value, true); + Subs.CVar(_cfg, CCVars.TipsTippyChance, value => _tipTippyChance = value, true); RecalculateNextTipTime(); - _conHost.RegisterCommand("tippy", Loc.GetString("cmd-tippy-desc"), Loc.GetString("cmd-tippy-help"), SendTippy, SendTippyHelper); - _conHost.RegisterCommand("tip", Loc.GetString("cmd-tip-desc"), "tip", SendTip); } - private CompletionResult SendTippyHelper(IConsoleShell shell, string[] args) + private void OnGameRunLevelChanged(GameRunLevelChangedEvent ev) { - return args.Length switch + // reset for lobby -> inround + // reset for inround -> post but not post -> lobby + if (ev.New == GameRunLevel.InRound || ev.Old == GameRunLevel.InRound) { - 1 => CompletionResult.FromHintOptions( - CompletionHelper.SessionNames(players: _playerManager), - Loc.GetString("cmd-tippy-auto-1")), - 2 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-2")), - 3 => CompletionResult.FromHintOptions( - CompletionHelper.PrototypeIdsLimited(args[2], _prototype), - Loc.GetString("cmd-tippy-auto-3")), - 4 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-4")), - 5 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-5")), - 6 => CompletionResult.FromHint(Loc.GetString("cmd-tippy-auto-6")), - _ => CompletionResult.Empty - }; + RecalculateNextTipTime(); + } } - private void SendTip(IConsoleShell shell, string argstr, string[] args) + private void SetEnabled(bool value) { - AnnounceRandomTip(); - RecalculateNextTipTime(); + _tipsEnabled = value; + + if (_nextTipTime != TimeSpan.Zero) + RecalculateNextTipTime(); } - private void SendTippy(IConsoleShell shell, string argstr, string[] args) + public override void RecalculateNextTipTime() { - if (args.Length < 2) + if (_ticker.RunLevel == GameRunLevel.InRound) { - shell.WriteLine(Loc.GetString("cmd-tippy-help")); - return; + _nextTipTime = _timing.CurTime + TimeSpan.FromSeconds(_tipTimeInRound); } - - ActorComponent? actor = null; - if (args[0] != "all") - { - ICommonSession? session; - if (args.Length > 0) - { - // Get player entity - if (!_playerManager.TryGetSessionByUsername(args[0], out session)) - { - shell.WriteLine(Loc.GetString("cmd-tippy-error-no-user")); - return; - } - } - else - { - session = shell.Player; - } - - if (session?.AttachedEntity is not { } user) - { - shell.WriteLine(Loc.GetString("cmd-tippy-error-no-user")); - return; - } - - if (!TryComp(user, out actor)) - { - shell.WriteError(Loc.GetString("cmd-tippy-error-no-user")); - return; - } - } - - var ev = new TippyEvent(args[1]); - - if (args.Length > 2) - { - ev.Proto = args[2]; - if (!_prototype.HasIndex(args[2])) - { - shell.WriteError(Loc.GetString("cmd-tippy-error-no-prototype", ("proto", args[2]))); - return; - } - } - - if (args.Length > 3) - ev.SpeakTime = float.Parse(args[3]); else - ev.SpeakTime = GetSpeechTime(ev.Msg); - - if (args.Length > 4) - ev.SlideTime = float.Parse(args[4]); - - if (args.Length > 5) - ev.WaddleInterval = float.Parse(args[5]); - - if (actor != null) - RaiseNetworkEvent(ev, actor.PlayerSession); - else - RaiseNetworkEvent(ev); + { + _nextTipTime = _timing.CurTime + TimeSpan.FromSeconds(_tipTimeOutOfRound); + } } - public override void Update(float frameTime) { base.Update(frameTime); @@ -171,41 +88,30 @@ public sealed class TipsSystem : EntitySystem } } - private void SetOutOfRound(float value) + public override void SendTippy( + string message, + EntProtoId? prototype = null, + float speakTime = 5f, + float slideTime = 3f, + float waddleInterval = 0.5f) { - _tipTimeOutOfRound = value; + var ev = new TippyEvent(message, prototype, speakTime, slideTime, waddleInterval); + RaiseNetworkEvent(ev); } - private void SetInRound(float value) + public override void SendTippy( + ICommonSession session, + string message, + EntProtoId? prototype = null, + float speakTime = 5f, + float slideTime = 3f, + float waddleInterval = 0.5f) { - _tipTimeInRound = value; + var ev = new TippyEvent(message, prototype, speakTime, slideTime, waddleInterval); + RaiseNetworkEvent(ev, session); } - private void SetEnabled(bool value) - { - _tipsEnabled = value; - - if (_nextTipTime != TimeSpan.Zero) - RecalculateNextTipTime(); - } - - private void SetDataset(string value) - { - _tipsDataset = value; - } - - private void SetTippyChance(float value) - { - _tipTippyChance = value; - } - - public static float GetSpeechTime(string text) - { - var wordCount = (float)text.Split().Length; - return SpeechBuffer + wordCount * (60f / Wpm); - } - - private void AnnounceRandomTip() + public override void AnnounceRandomTip() { if (!_prototype.TryIndex(_tipsDataset, out var tips)) return; @@ -215,35 +121,20 @@ public sealed class TipsSystem : EntitySystem if (_random.Prob(_tipTippyChance)) { - var ev = new TippyEvent(msg); - ev.SpeakTime = GetSpeechTime(msg); - RaiseNetworkEvent(ev); - } else - { - _chat.ChatMessageToManyFiltered(Filter.Broadcast(), ChatChannel.OOC, tip, msg, - EntityUid.Invalid, false, false, Color.MediumPurple); - } - } - - private void RecalculateNextTipTime() - { - if (_ticker.RunLevel == GameRunLevel.InRound) - { - _nextTipTime = _timing.CurTime + TimeSpan.FromSeconds(_tipTimeInRound); + var speakTime = GetSpeechTime(msg); + SendTippy(msg, speakTime: speakTime); } else { - _nextTipTime = _timing.CurTime + TimeSpan.FromSeconds(_tipTimeOutOfRound); - } - } - - private void OnGameRunLevelChanged(GameRunLevelChangedEvent ev) - { - // reset for lobby -> inround - // reset for inround -> post but not post -> lobby - if (ev.New == GameRunLevel.InRound || ev.Old == GameRunLevel.InRound) - { - RecalculateNextTipTime(); + _chat.ChatMessageToManyFiltered( + Filter.Broadcast(), + ChatChannel.OOC, + tip, + msg, + EntityUid.Invalid, + false, + false, + Color.MediumPurple); } } } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs index 700a15e1b0..c1e442c24b 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.Battery.cs @@ -68,6 +68,7 @@ public sealed partial class GunSystem protected override void TakeCharge(Entity entity) { + // Take charge from either the BatteryComponent or PowerCellSlotComponent. var ev = new ChangeChargeEvent(-entity.Comp.FireCost); RaiseLocalEvent(entity, ref ev); } diff --git a/Content.Server/Xenoarchaeology/Artifact/XAE/XAEChargeBatterySystem.cs b/Content.Server/Xenoarchaeology/Artifact/XAE/XAEChargeBatterySystem.cs index 85ffc75627..21952912d7 100644 --- a/Content.Server/Xenoarchaeology/Artifact/XAE/XAEChargeBatterySystem.cs +++ b/Content.Server/Xenoarchaeology/Artifact/XAE/XAEChargeBatterySystem.cs @@ -25,7 +25,7 @@ public sealed class XAEChargeBatterySystem : BaseXAESystem(OnXenoborgDestroyed); + SubscribeLocalEvent(OnCoreDestroyed); + + SubscribeLocalEvent(OnXenoborgMindAdded); + SubscribeLocalEvent(OnXenoborgMindRemoved); + } + + private void OnXenoborgDestroyed(EntityUid uid, XenoborgComponent component, DestructionEventArgs args) + { + // if a xenoborg is destroyed, it will check to see if it was the last one + var xenoborgQuery = AllEntityQuery(); // paused xenoborgs still count + while (xenoborgQuery.MoveNext(out var xenoborg, out _)) + { + if (xenoborg != uid) + return; + } + + var mothershipCoreQuery = AllEntityQuery(); // paused mothership cores still count + var mothershipCoreAlive = mothershipCoreQuery.MoveNext(out _, out _); + + var xenoborgsRuleQuery = EntityQueryEnumerator(); + if (xenoborgsRuleQuery.MoveNext(out var xenoborgsRuleEnt, out var xenoborgsRuleComp)) + _xenoborgsRule.SendXenoborgDeathAnnouncement((xenoborgsRuleEnt, xenoborgsRuleComp), mothershipCoreAlive); + } + + private void OnCoreDestroyed(EntityUid ent, MothershipCoreComponent component, DestructionEventArgs args) + { + // if a mothership core is destroyed, it will see if there are any others + var mothershipCoreQuery = AllEntityQuery(); // paused mothership cores still count + while (mothershipCoreQuery.MoveNext(out var mothershipCoreEnt, out _)) + { + // if it finds a mothership core that is different from the one just destroyed, + // it doesn't explode the xenoborgs + if (mothershipCoreEnt != ent) + return; + } + + var xenoborgsRuleQuery = EntityQueryEnumerator(); + if (xenoborgsRuleQuery.MoveNext(out var xenoborgsRuleEnt, out var xenoborgsRuleComp)) + _xenoborgsRule.SendMothershipDeathAnnouncement((xenoborgsRuleEnt, xenoborgsRuleComp)); + + // explode all xenoborgs + var xenoborgQuery = AllEntityQuery(); // paused xenoborgs still explode + while (xenoborgQuery.MoveNext(out var xenoborgEnt, out _, out _)) + { + if (HasComp(xenoborgEnt)) + continue; + + // I got tired to trying to make this work via the device network. + // so brute force it is... + _borg.Destroy(xenoborgEnt); + } + } + + private void OnXenoborgMindAdded(EntityUid ent, XenoborgComponent comp, MindAddedMessage args) + { + _roles.MindAddRole(args.Mind, comp.MindRole, silent: true); + + if (!TryComp(ent, out var actorComp)) + return; + + _antag.SendBriefing(actorComp.PlayerSession, + Loc.GetString(comp.BriefingText), + XenoborgBriefingColor, + comp.BriefingSound + ); + } + + private void OnXenoborgMindRemoved(EntityUid ent, XenoborgComponent comp, MindRemovedMessage args) + { + _roles.MindRemoveRole(args.Mind.Owner, comp.MindRole); + } +} diff --git a/Content.Shared/Administration/Logs/LogStringHandler.cs b/Content.Shared/Administration/Logs/LogStringHandler.cs index 9b65c6d723..2fab949d58 100644 --- a/Content.Shared/Administration/Logs/LogStringHandler.cs +++ b/Content.Shared/Administration/Logs/LogStringHandler.cs @@ -40,7 +40,8 @@ public ref struct LogStringHandler format = argument[0] == '@' ? argument[1..] : argument; } - if (Values.TryAdd(Logger.ConvertName(format), value) + format = Logger.ConvertName(format); + if (Values.TryAdd(format, value) || Values[format] is T val && val.Equals(value) ) { return; @@ -50,7 +51,7 @@ public ref struct LogStringHandler var i = 2; format = $"{originalFormat}_{i}"; - while (!(Values.TryAdd(Logger.ConvertName(format), value) + while (!(Values.TryAdd(format, value) || Values[format] is T val2 && val2.Equals(value))) { format = $"{originalFormat}_{i}"; diff --git a/Content.Shared/CCVar/CCVars.Debug.cs b/Content.Shared/CCVar/CCVars.Debug.cs new file mode 100644 index 0000000000..a95acc4dac --- /dev/null +++ b/Content.Shared/CCVar/CCVars.Debug.cs @@ -0,0 +1,13 @@ +using Robust.Shared.Configuration; + +namespace Content.Shared.CCVar; + +public sealed partial class CCVars +{ + /// + /// Component to be inspected using the "Quick Inspect Component" keybind. + /// Set by the "quickinspect" command. + /// + public static readonly CVarDef DebugQuickInspect = + CVarDef.Create("debug.quick_inspect", "", CVar.CLIENTONLY | CVar.ARCHIVE); +} diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs index 2179469c08..df09f7f3f6 100644 --- a/Content.Shared/Chemistry/Components/Solution.cs +++ b/Content.Shared/Chemistry/Components/Solution.cs @@ -302,7 +302,7 @@ namespace Content.Shared.Chemistry.Components /// If you only want the volume of a single reagent, use /// [Pure] - public FixedPoint2 GetTotalPrototypeQuantity(params string[] prototypes) + public FixedPoint2 GetTotalPrototypeQuantity(params ProtoId[] prototypes) { var total = FixedPoint2.Zero; foreach (var (reagent, quantity) in Contents) @@ -314,7 +314,7 @@ namespace Content.Shared.Chemistry.Components return total; } - public FixedPoint2 GetTotalPrototypeQuantity(string id) + public FixedPoint2 GetTotalPrototypeQuantity(ProtoId id) { var total = FixedPoint2.Zero; foreach (var (reagent, quantity) in Contents) @@ -645,7 +645,7 @@ namespace Content.Shared.Chemistry.Components /// /// Splits a solution with only the specified reagent prototypes. /// - public Solution SplitSolutionWithOnly(FixedPoint2 toTake, params string[] includedPrototypes) + public Solution SplitSolutionWithOnly(FixedPoint2 toTake, params ProtoId[] includedPrototypes) { // First remove the non-included prototypes List excluded = new(); @@ -844,7 +844,7 @@ namespace Content.Shared.Chemistry.Components ValidateSolution(); } - public Color GetColorWithout(IPrototypeManager? protoMan, params string[] without) + public Color GetColorWithout(IPrototypeManager? protoMan, params ProtoId[] without) { if (Volume == FixedPoint2.Zero) { @@ -887,7 +887,7 @@ namespace Content.Shared.Chemistry.Components return GetColorWithout(protoMan); } - public Color GetColorWithOnly(IPrototypeManager? protoMan, params string[] included) + public Color GetColorWithOnly(IPrototypeManager? protoMan, params ProtoId[] included) { if (Volume == FixedPoint2.Zero) { diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs index a245c0b606..892e4e9cac 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs @@ -858,7 +858,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem args.PushMarkup(Loc.GetString(entity.Comp.LocPhysicalQuality, ("color", colorHex), ("desc", primary.LocalizedPhysicalDescription), - ("chemCount", solution.Contents.Count) )); + ("chemCount", solution.Contents.Count))); // Push the recognizable reagents @@ -1048,7 +1048,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem public bool EnsureSolution( Entity entity, string name, - [NotNullWhen(true)]out Solution? solution, + [NotNullWhen(true)] out Solution? solution, FixedPoint2 maxVol = default) { return EnsureSolution(entity, name, maxVol, null, out _, out solution); @@ -1058,7 +1058,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem Entity entity, string name, out bool existed, - [NotNullWhen(true)]out Solution? solution, + [NotNullWhen(true)] out Solution? solution, FixedPoint2 maxVol = default) { return EnsureSolution(entity, name, maxVol, null, out existed, out solution); @@ -1217,7 +1217,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem var relation = new ContainedSolutionComponent() { Container = container.Owner, ContainerName = name }; AddComp(uid, relation); - MetaDataSys.SetEntityName(uid, $"solution - {name}"); + MetaDataSys.SetEntityName(uid, $"solution - {name}", raiseEvents: false); ContainerSystem.Insert(uid, container, force: true); return (uid, solution, relation); @@ -1240,13 +1240,13 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem } else { - dissolvedSol.RemoveReagent(reagent,amtChange); + dissolvedSol.RemoveReagent(reagent, amtChange); } UpdateChemicals(dissolvedSolution); } public FixedPoint2 GetReagentQuantityFromConcentration(Entity dissolvedSolution, - FixedPoint2 volume,float concentration) + FixedPoint2 volume, float concentration) { var dissolvedSol = dissolvedSolution.Comp.Solution; if (volume == 0 diff --git a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs index 3b16b577cb..e634e03284 100644 --- a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs +++ b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs @@ -221,7 +221,7 @@ namespace Content.Shared.Chemistry.Reagent if (effect.EntityEffectGuidebookText(prototype, entSys) is not { } description) return null; - var quantity = metabolism == null ? 0f : (double) (effect.MinScale * metabolism); + var quantity = metabolism == null ? 0f : (double)(effect.MinScale * metabolism); return Loc.GetString( "guidebook-reagent-effect-description", diff --git a/Content.Shared/Damage/Systems/DamageableSystem.API.cs b/Content.Shared/Damage/Systems/DamageableSystem.API.cs index c2a1374901..c5452eda7c 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.API.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.API.cs @@ -8,13 +8,41 @@ namespace Content.Shared.Damage.Systems; public sealed partial class DamageableSystem { /// - /// Directly sets the damage specifier of a damageable component. + /// Directly sets the damage in a damageable component. + /// This method keeps the damage types supported by the DamageContainerPrototype in the component. + /// If a type is given in , but not supported then it will not be set. + /// If a type is supported but not given in then it will be set to 0. /// /// /// Useful for some unfriendly folk. Also ensures that cached values are updated and that a damage changed /// event is raised. /// public void SetDamage(Entity ent, DamageSpecifier damage) + { + if (!_damageableQuery.Resolve(ent, ref ent.Comp, false)) + return; + + foreach (var type in ent.Comp.Damage.DamageDict.Keys) + { + if (damage.DamageDict.TryGetValue(type, out var value)) + ent.Comp.Damage.DamageDict[type] = value; + else + ent.Comp.Damage.DamageDict[type] = 0; + } + + OnEntityDamageChanged((ent, ent.Comp)); + } + + /// + /// Directly sets the damage specifier of a damageable component. + /// This will overwrite the complete damage dict, meaning it will bulldoze the supported damage types. + /// + /// + /// This may break persistance as the supported types are reset in case the component is initialized again. + /// So this only makes sense if you also change the DamageContainerPrototype in the component at the same time. + /// Only use this method if you know what you are doing. + /// + public void SetDamageSpecifier(Entity ent, DamageSpecifier damage) { if (!_damageableQuery.Resolve(ent, ref ent.Comp, false)) return; diff --git a/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs b/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs index 9854560204..0ba1c15122 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.Evaporation.cs @@ -1,7 +1,9 @@ using System.Linq; using Content.Shared.Chemistry.Components; using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; using Content.Shared.Fluids.Components; +using Content.Shared.Chemistry.Reagent; namespace Content.Shared.Fluids; @@ -78,9 +80,9 @@ public abstract partial class SharedPuddleSystem } - public string[] GetEvaporatingReagents(Solution solution) + public ProtoId[] GetEvaporatingReagents(Solution solution) { - List evaporatingReagents = []; + List> evaporatingReagents = []; foreach (var solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) { if (solProto.EvaporationSpeed > FixedPoint2.Zero) @@ -89,10 +91,10 @@ public abstract partial class SharedPuddleSystem return evaporatingReagents.ToArray(); } - public string[] GetAbsorbentReagents(Solution solution) + public ProtoId[] GetAbsorbentReagents(Solution solution) { - List absorbentReagents = []; - foreach (var solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) + var absorbentReagents = new List>(); + foreach (ReagentPrototype solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) { if (solProto.Absorbent) absorbentReagents.Add(solProto.ID); @@ -109,9 +111,9 @@ public abstract partial class SharedPuddleSystem /// Gets a mapping of evaporating speed of the reagents within a solution. /// The speed at which a solution evaporates is the average of the speed of all evaporating reagents in it. /// - public Dictionary GetEvaporationSpeeds(Solution solution) + public Dictionary, FixedPoint2> GetEvaporationSpeeds(Solution solution) { - Dictionary evaporatingSpeeds = []; + Dictionary, FixedPoint2> evaporatingSpeeds = []; foreach (var solProto in solution.GetReagentPrototypes(_prototypeManager).Keys) { if (solProto.EvaporationSpeed > FixedPoint2.Zero) diff --git a/Content.Shared/Fluids/SharedPuddleSystem.cs b/Content.Shared/Fluids/SharedPuddleSystem.cs index a2ea262796..e81d1c9d11 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.cs @@ -42,7 +42,7 @@ public abstract partial class SharedPuddleSystem : EntitySystem [Dependency] private readonly StepTriggerSystem _stepTrigger = default!; [Dependency] private readonly TileFrictionController _tile = default!; - private string[] _standoutReagents = []; + private ProtoId[] _standoutReagents = []; /// /// The lowest threshold to be considered for puddle sprite states as well as slipperiness of a puddle. diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 07639a1790..8357b0106f 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -35,6 +35,7 @@ public sealed class FollowerSystem : EntitySystem [Dependency] private readonly ISharedAdminManager _adminManager = default!; private static readonly ProtoId ForceableFollowTag = "ForceableFollow"; + private static readonly ProtoId PreventGhostnadoWarpTag = "NotGhostnadoWarpable"; public override void Initialize() { @@ -320,11 +321,17 @@ public sealed class FollowerSystem : EntitySystem var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out var follower, out _, out var actor)) { - // Exclude admins + // Don't count admin followers so that players cannot notice if admins are in stealth mode and following someone. if (_adminManager.IsAdmin(actor.PlayerSession)) continue; var followed = follower.Following; + + // If the followed entity cannot be ghostnado'd to, we don't count it. + // Used for making admins not warpable to, but IsAdmin isn't used for cases where the admin wants to be followed, for example during events. + if (_tagSystem.HasTag(followed, PreventGhostnadoWarpTag)) + continue; + // Add new entry or increment existing followedEnts.TryGetValue(followed, out var currentValue); followedEnts[followed] = currentValue + 1; diff --git a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs b/Content.Shared/Gravity/GravityGeneratorComponent.cs similarity index 59% rename from Content.Shared/Gravity/SharedGravityGeneratorComponent.cs rename to Content.Shared/Gravity/GravityGeneratorComponent.cs index 75b636b2fa..f7b1240f1a 100644 --- a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs +++ b/Content.Shared/Gravity/GravityGeneratorComponent.cs @@ -3,42 +3,45 @@ using Robust.Shared.GameStates; namespace Content.Shared.Gravity; -[NetworkedComponent()] -[Virtual] -public partial class SharedGravityGeneratorComponent : Component +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class GravityGeneratorComponent : Component { + [DataField] public float LightRadiusMin { get; set; } + [DataField] public float LightRadiusMax { get; set; } + /// /// A map of the sprites used by the gravity generator given its status. /// - [DataField("spriteMap")] - [Access(typeof(SharedGravitySystem))] - public Dictionary SpriteMap = new(); + [DataField, Access(typeof(SharedGravitySystem))] + public Dictionary SpriteMap = []; /// /// The sprite used by the core of the gravity generator when the gravity generator is starting up. /// - [DataField("coreStartupState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreStartupState = "startup"; /// /// The sprite used by the core of the gravity generator when the gravity generator is idle. /// - [DataField("coreIdleState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreIdleState = "idle"; /// /// The sprite used by the core of the gravity generator when the gravity generator is activating. /// - [DataField("coreActivatingState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreActivatingState = "activating"; /// /// The sprite used by the core of the gravity generator when the gravity generator is active. /// - [DataField("coreActivatedState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreActivatedState = "activated"; + + /// + /// Is the gravity generator currently "producing" gravity? + /// + [DataField, AutoNetworkedField, Access(typeof(SharedGravityGeneratorSystem))] + public bool GravityActive = false; } diff --git a/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs b/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs new file mode 100644 index 0000000000..b2b2e72b62 --- /dev/null +++ b/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.Popups; +using Content.Shared.Construction.Components; + +namespace Content.Shared.Gravity; + +public abstract class SharedGravityGeneratorSystem : EntitySystem +{ + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUnanchorAttempt); + } + + /// + /// Prevent unanchoring when gravity is active + /// + private void OnUnanchorAttempt(Entity ent, ref UnanchorAttemptEvent args) + { + if (!ent.Comp.GravityActive) + return; + + _popupSystem.PopupClient(Loc.GetString("gravity-generator-unanchoring-failed"), ent.Owner, args.User, PopupType.Medium); + + args.Cancel(); + } +} diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.EventListeners.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.EventListeners.cs index af0ed1c1aa..ea2502331e 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.EventListeners.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.EventListeners.cs @@ -11,6 +11,7 @@ public abstract partial class SharedHandsSystem private void InitializeEventListeners() { SubscribeLocalEvent(OnStandupArgs); + SubscribeLocalEvent(OnKnockedDownRefresh); } /// @@ -28,4 +29,17 @@ public abstract partial class SharedHandsSystem time.DoAfterTime *= (float)ent.Comp.Count / (hands + ent.Comp.Count); } + + private void OnKnockedDownRefresh(Entity ent, ref KnockedDownRefreshEvent args) + { + var freeHands = CountFreeHands(ent.AsNullable()); + var totalHands = GetHandCount(ent.AsNullable()); + + // Can't crawl around without any hands. + // Entities without the HandsComponent will always have full crawling speed. + if (totalHands == 0) + args.SpeedModifier = 0f; + else + args.SpeedModifier *= (float)freeHands / totalHands; + } } diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs index 50ea218b00..63f6310322 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -123,7 +123,8 @@ namespace Content.Shared.Input public static readonly BoundKeyFunction EditorCopyObject = "EditorCopyObject"; public static readonly BoundKeyFunction EditorFlipObject = "EditorFlipObject"; public static readonly BoundKeyFunction InspectEntity = "InspectEntity"; - + public static readonly BoundKeyFunction InspectServerComponent = "InspectServerComponent"; + public static readonly BoundKeyFunction InspectClientComponent = "InspectClientComponent"; public static readonly BoundKeyFunction MappingUnselect = "MappingUnselect"; public static readonly BoundKeyFunction SaveMap = "SaveMap"; public static readonly BoundKeyFunction MappingEnablePick = "MappingEnablePick"; diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs index 95a681dc38..560bb296ac 100644 --- a/Content.Shared/Lock/LockSystem.cs +++ b/Content.Shared/Lock/LockSystem.cs @@ -119,7 +119,7 @@ public sealed class LockSystem : EntitySystem if (!lockComp.ShowExamine) return; - args.PushText(Loc.GetString(lockComp.Locked + args.PushMarkup(Loc.GetString(lockComp.Locked ? "lock-comp-on-examined-is-locked" : "lock-comp-on-examined-is-unlocked", ("entityName", Identity.Name(uid, EntityManager)))); diff --git a/Content.Shared/Magic/SharedMagicSystem.cs b/Content.Shared/Magic/SharedMagicSystem.cs index 6afba65a39..3301180e8a 100644 --- a/Content.Shared/Magic/SharedMagicSystem.cs +++ b/Content.Shared/Magic/SharedMagicSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Charges.Systems; using Content.Shared.Coordinates.Helpers; using Content.Shared.Doors.Components; using Content.Shared.Doors.Systems; +using Content.Shared.Examine; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; @@ -66,6 +67,7 @@ public abstract class SharedMagicSystem : EntitySystem [Dependency] private readonly SharedStunSystem _stun = default!; [Dependency] private readonly TurfSystem _turf = default!; [Dependency] private readonly SharedChargesSystem _charges = default!; + [Dependency] private readonly ExamineSystemShared _examine= default!; private static readonly ProtoId InvalidForGlobalSpawnSpellTag = "InvalidForGlobalSpawnSpell"; @@ -399,22 +401,30 @@ public abstract class SharedMagicSystem : EntitySystem #endregion #region Knock Spells /// - /// Opens all doors and locks within range + /// Opens all doors and locks within range. /// - /// private void OnKnockSpell(KnockSpellEvent args) { if (args.Handled || !PassesSpellPrerequisites(args.Action, args.Performer)) return; args.Handled = true; + Knock(args.Performer, args.Range); + } - var transform = Transform(args.Performer); + /// + /// Opens all doors and locks within range. + /// + /// Performer of spell. + /// Radius around in which all doors and locks should be opened. + public void Knock(EntityUid performer, float range) + { + var transform = Transform(performer); // Look for doors and lockers, and don't open/unlock them if they're already opened/unlocked. - foreach (var target in _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(args.Performer, transform), args.Range, flags: LookupFlags.Dynamic | LookupFlags.Static)) + foreach (var target in _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(performer, transform), range, flags: LookupFlags.Dynamic | LookupFlags.Static)) { - if (!_interaction.InRangeUnobstructed(args.Performer, target, range: 0, collisionMask: CollisionGroup.Opaque)) + if (!_examine.InRangeUnOccluded(performer, target, range: 0)) continue; if (TryComp(target, out var doorBoltComp) && doorBoltComp.BoltsDown) @@ -424,7 +434,7 @@ public abstract class SharedMagicSystem : EntitySystem _door.StartOpening(target); if (TryComp(target, out var lockComp) && lockComp.Locked) - _lock.Unlock(target, args.Performer, lockComp); + _lock.Unlock(target, performer, lockComp); } } // End Knock Spells diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index 309f37be3f..a7d3357f00 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -20,6 +20,7 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Player; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -43,6 +44,8 @@ public abstract partial class SharedMindSystem : EntitySystem private HashSet> _pickingMinds = new(); + private readonly EntProtoId _mindProto = "MindBase"; + public override void Initialize() { base.Initialize(); @@ -226,7 +229,7 @@ public abstract partial class SharedMindSystem : EntitySystem public Entity CreateMind(NetUserId? userId, string? name = null) { - var mindId = Spawn(null, MapCoordinates.Nullspace); + var mindId = Spawn(_mindProto, MapCoordinates.Nullspace); _metadata.SetEntityName(mindId, name == null ? "mind" : $"mind ({name})"); var mind = EnsureComp(mindId); mind.CharacterName = name; diff --git a/Content.Shared/Physics/Controllers/SharedConveyorController.cs b/Content.Shared/Physics/Controllers/SharedConveyorController.cs index b1ccb3be2a..e8b22b410c 100644 --- a/Content.Shared/Physics/Controllers/SharedConveyorController.cs +++ b/Content.Shared/Physics/Controllers/SharedConveyorController.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; using Content.Shared.Conveyor; using Content.Shared.Gravity; using Content.Shared.Movement.Components; @@ -58,6 +58,9 @@ public abstract class SharedConveyorController : VirtualController private void OnConveyedFriction(Entity ent, ref TileFrictionEvent args) { + if(!ent.Comp.Conveying) + return; + // Conveyed entities don't get friction, they just get wishdir applied so will inherently slowdown anyway. args.Modifier = 0f; } @@ -140,7 +143,15 @@ public abstract class SharedConveyorController : VirtualController continue; var physics = ent.Entity.Comp3; + + if (physics.BodyStatus != BodyStatus.OnGround) + { + SetConveying(ent.Entity.Owner, ent.Entity.Comp1, false); + continue; + } + var velocity = physics.LinearVelocity; + var angularVelocity = physics.AngularVelocity; var targetDir = ent.Direction; // If mob is moving with the conveyor then combine the directions. @@ -163,6 +174,7 @@ public abstract class SharedConveyorController : VirtualController // We provide a small minimum friction speed as well for those times where the friction would stop large objects // snagged on corners from sliding into the centerline. _mover.Friction(0.2f, frameTime: frameTime, friction: 5f, ref velocity); + _mover.Friction(0f, frameTime: frameTime, friction: 5f, ref angularVelocity); } SharedMoverController.Accelerate(ref velocity, targetDir, 20f, frameTime); @@ -172,8 +184,10 @@ public abstract class SharedConveyorController : VirtualController // Need friction to outweigh the movement as it will bounce a bit against the wall. // This facilitates being able to sleep entities colliding into walls. _mover.Friction(0f, frameTime: frameTime, friction: 40f, ref velocity); + _mover.Friction(0f, frameTime: frameTime, friction: 40f, ref angularVelocity); } + PhysicsSystem.SetAngularVelocity(ent.Entity.Owner, angularVelocity); PhysicsSystem.SetLinearVelocity(ent.Entity.Owner, velocity, wakeBody: false); if (!IsConveyed((ent.Entity.Owner, ent.Entity.Comp2))) diff --git a/Content.Shared/Power/ChargeEvents.cs b/Content.Shared/Power/ChargeEvents.cs index db412e91d9..cc9dc49a7c 100644 --- a/Content.Shared/Power/ChargeEvents.cs +++ b/Content.Shared/Power/ChargeEvents.cs @@ -1,3 +1,6 @@ +using Content.Shared.Power.Components; +using Content.Shared.PowerCell.Components; + namespace Content.Shared.Power; /// @@ -7,27 +10,36 @@ namespace Content.Shared.Power; public readonly record struct ChargeChangedEvent(float Charge, float MaxCharge); /// +/// Event that supports multiple battery types. /// Raised when it is necessary to get information about battery charges. +/// Works with either or . +/// If there are multiple batteries then the results will be summed up. /// [ByRefEvent] -public sealed class GetChargeEvent : EntityEventArgs +public record struct GetChargeEvent { public float CurrentCharge; public float MaxCharge; } /// -/// Raised when it is necessary to change the current battery charge to a some value. +/// Method event that supports multiple battery types. +/// Raised when it is necessary to change the current battery charge by some value. +/// Works with either or . +/// If there are multiple batteries then they will be changed in order of subscription until the total value was reached. /// [ByRefEvent] -public sealed class ChangeChargeEvent : EntityEventArgs +public record struct ChangeChargeEvent(float Amount) { - public float OriginalValue; - public float ResidualValue; + /// + /// The total amount of charge to change the battery's storage by (in joule). + /// A positive value adds charge, a negative value removes charge. + /// + public readonly float Amount = Amount; - public ChangeChargeEvent(float value) - { - OriginalValue = value; - ResidualValue = value; - } + /// + /// The amount of charge that still has to be removed. + /// For cases where there are multiple batteries. + /// + public float ResidualValue = Amount; } diff --git a/Content.Shared/Power/Components/BatteryComponent.cs b/Content.Shared/Power/Components/BatteryComponent.cs index 6a2d2a5051..6a65405115 100644 --- a/Content.Shared/Power/Components/BatteryComponent.cs +++ b/Content.Shared/Power/Components/BatteryComponent.cs @@ -11,10 +11,8 @@ namespace Content.Shared.Power.Components; [Access(typeof(SharedBatterySystem))] public partial class BatteryComponent : Component { - public string SolutionName = "battery"; - /// - /// Maximum charge of the battery in joules (ie. watt seconds) + /// Maximum charge of the battery in joules (i.e. watt seconds) /// [DataField] [GuidebookData] @@ -23,11 +21,11 @@ public partial class BatteryComponent : Component /// /// Current charge of the battery in joules (ie. watt seconds) /// - [DataField("startingCharge")] + [DataField("startingCharge")] // TODO: rename this datafield to currentCharge public float CurrentCharge; /// - /// The price per one joule. Default is 1 credit for 10kJ. + /// The price per one joule. Default is 1 speso for 10kJ. /// [DataField] public float PricePerJoule = 0.0001f; diff --git a/Content.Shared/Power/Components/BatterySelfRechargerComponent.cs b/Content.Shared/Power/Components/BatterySelfRechargerComponent.cs new file mode 100644 index 0000000000..3881980382 --- /dev/null +++ b/Content.Shared/Power/Components/BatterySelfRechargerComponent.cs @@ -0,0 +1,36 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared.Power.Components; + +/// +/// Self-recharging battery. +/// To be used in combination with . +/// +[RegisterComponent, AutoGenerateComponentPause] +public sealed partial class BatterySelfRechargerComponent : Component +{ + /// + /// Is the component currently enabled? + /// + [DataField] + public bool AutoRecharge = true; + + /// + /// At what rate does the entity automatically recharge? + /// + [DataField] + public float AutoRechargeRate; + + /// + /// How long should the entity stop automatically recharging if charge is used? + /// + [DataField] + public TimeSpan AutoRechargePauseTime = TimeSpan.FromSeconds(0); + + /// + /// Do not auto recharge if this timestamp has yet to happen, set for the auto recharge pause system. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan NextAutoRecharge = TimeSpan.FromSeconds(0); +} diff --git a/Content.Shared/Power/EntitySystems/SharedBatterySystem.cs b/Content.Shared/Power/EntitySystems/SharedBatterySystem.cs index a9d5db3f33..d067a685d4 100644 --- a/Content.Shared/Power/EntitySystems/SharedBatterySystem.cs +++ b/Content.Shared/Power/EntitySystems/SharedBatterySystem.cs @@ -12,33 +12,61 @@ public abstract class SharedBatterySystem : EntitySystem SubscribeLocalEvent(OnEmpPulse); } - private void OnEmpPulse(Entity entity, ref EmpPulseEvent args) + private void OnEmpPulse(Entity ent, ref EmpPulseEvent args) { args.Affected = true; - UseCharge(entity, args.EnergyConsumption, entity.Comp); + UseCharge(ent.AsNullable(), args.EnergyConsumption); // Apply a cooldown to the entity's self recharge if needed to avoid it immediately self recharging after an EMP. - TrySetChargeCooldown(entity); + TrySetChargeCooldown(ent.Owner); } - public virtual float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) - { - return 0f; - } - - public virtual void SetMaxCharge(EntityUid uid, float value, BatteryComponent? battery = null) { } - - public virtual float ChangeCharge(EntityUid uid, float value, BatteryComponent? battery = null) + /// + /// Changes the battery's charge by the given amount. + /// A positive value will add charge, a negative value will remove charge. + /// + /// The actually changed amount. + public virtual float ChangeCharge(Entity ent, float amount) { return 0f; } /// - /// Checks if the entity has a self recharge and puts it on cooldown if applicable. + /// Removes the given amount of charge from the battery. /// - public virtual void TrySetChargeCooldown(EntityUid uid, float value = -1) { } + /// The actually changed amount. + public virtual float UseCharge(Entity ent, float amount) + { + return 0f; + } - public virtual bool TryUseCharge(EntityUid uid, float value, BatteryComponent? battery = null) + /// + /// If sufficient charge is available on the battery, use it. Otherwise, don't. + /// Always returns false on the client. + /// + /// If the full amount was able to be removed. + public virtual bool TryUseCharge(Entity ent, float amount) { return false; } + + /// + /// Sets the battery's charge. + /// + public virtual void SetCharge(Entity ent, float value) { } + + /// + /// Sets the battery's maximum charge. + /// + public virtual void SetMaxCharge(Entity ent, float value) { } + + /// + /// Checks if the entity has a self recharge and puts it on cooldown if applicable. + /// Uses the cooldown time given in the component. + /// + public virtual void TrySetChargeCooldown(Entity ent) { } + + /// + /// Puts the entity's self recharge on cooldown for the specified time. + /// + public virtual void SetChargeCooldown(Entity ent, TimeSpan cooldown) { } } diff --git a/Content.Shared/Roles/Components/XenoborgRoleComponent.cs b/Content.Shared/Roles/Components/XenoborgRoleComponent.cs new file mode 100644 index 0000000000..eeebad0a79 --- /dev/null +++ b/Content.Shared/Roles/Components/XenoborgRoleComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Roles.Components; + +/// +/// Added to mind role entities to tag that they are a xenoborg. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class XenoborgRoleComponent : Component; diff --git a/Content.Shared/Silicons/Borgs/Components/BorgChassisComponent.cs b/Content.Shared/Silicons/Borgs/Components/BorgChassisComponent.cs index c2bf2b2801..f562ddefdd 100644 --- a/Content.Shared/Silicons/Borgs/Components/BorgChassisComponent.cs +++ b/Content.Shared/Silicons/Borgs/Components/BorgChassisComponent.cs @@ -78,6 +78,12 @@ public sealed partial class BorgChassisComponent : Component [DataField] public ProtoId NoBatteryAlert = "BorgBatteryNone"; + + /// + /// If the entity can open own UI. + /// + [DataField] + public bool CanOpenSelfUi; } [Serializable, NetSerializable] diff --git a/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs b/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs index e542a1e3e3..f50b088932 100644 --- a/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs +++ b/Content.Shared/Silicons/Borgs/Components/BorgModuleComponent.cs @@ -1,4 +1,5 @@ using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; namespace Content.Shared.Silicons.Borgs.Components; @@ -24,6 +25,13 @@ public sealed partial class BorgModuleComponent : Component [DataField] [AutoNetworkedField] public bool DefaultModule; + + /// + /// List of types of borgs this module fits into. + /// This only affects examine text. The actual whitelist for modules that can be inserted into a borg is defined in its . + /// + [DataField] + public HashSet? BorgFitTypes; } /// diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs index 827bb351b0..f9b4ec7cb8 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs @@ -1,6 +1,8 @@ using Content.Shared.Containers.ItemSlots; +using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Item.ItemToggle; +using Content.Shared.Localizations; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Popups; @@ -35,10 +37,30 @@ public abstract partial class SharedBorgSystem : EntitySystem SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); SubscribeLocalEvent(OnUIOpenAttempt); SubscribeLocalEvent(OnTryGetIdentityShortInfo); + SubscribeLocalEvent(OnModuleExamine); InitializeRelay(); } + private void OnModuleExamine(Entity ent, ref ExaminedEvent args) + { + if (ent.Comp.BorgFitTypes == null) + return; + + if (ent.Comp.BorgFitTypes.Count == 0) + return; + + var typeList = new List(); + + foreach (var type in ent.Comp.BorgFitTypes) + { + typeList.Add(Loc.GetString(type)); + } + + var types = ContentLocalizationManager.FormatList(typeList); + args.PushMarkup(Loc.GetString("borg-module-fit", ("types", types))); + } + private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args) { if (args.Handled) @@ -98,8 +120,8 @@ public abstract partial class SharedBorgSystem : EntitySystem private void OnUIOpenAttempt(EntityUid uid, BorgChassisComponent component, ActivatableUIOpenAttemptEvent args) { - // borgs can't view their own ui - if (args.User == uid) + // borgs generaly can't view their own ui + if (args.User == uid && !component.CanOpenSelfUi) args.Cancel(); } diff --git a/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs b/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs index fc2b01c649..58f38c9db8 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs @@ -1,12 +1,12 @@ using Content.Shared.Alert; using Content.Shared.Buckle.Components; using Content.Shared.CCVar; -using Content.Shared.Damage; using Content.Shared.Damage.Components; using Content.Shared.Damage.Systems; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.Gravity; +using Content.Shared.Hands; using Content.Shared.Hands.EntitySystems; using Content.Shared.Input; using Content.Shared.Movement.Events; @@ -54,7 +54,7 @@ public abstract partial class SharedStunSystem SubscribeLocalEvent(OnBuckleAttempt); SubscribeLocalEvent(OnStandAttempt); - // Updating movement a friction + // Updating movement and friction SubscribeLocalEvent(OnRefreshKnockedSpeed); SubscribeLocalEvent(OnRefreshFriction); SubscribeLocalEvent(OnKnockedTileFriction); @@ -66,6 +66,9 @@ public abstract partial class SharedStunSystem SubscribeLocalEvent(OnKnockdownRefresh); SubscribeLocalEvent(OnDamaged); SubscribeLocalEvent(OnWeightlessnessChanged); + SubscribeLocalEvent(OnHandEquipped); + SubscribeLocalEvent(OnHandUnequipped); + SubscribeLocalEvent(OnHandCountChanged); SubscribeLocalEvent(OnKnockdownAttempt); SubscribeLocalEvent(OnGetStandUpTime); @@ -380,7 +383,7 @@ public abstract partial class SharedStunSystem private void OnForceStandup(ForceStandUpEvent msg, EntitySessionEventArgs args) { - if (args.SenderSession.AttachedEntity is not {} user) + if (args.SenderSession.AttachedEntity is not { } user) return; ForceStandUp(user); @@ -522,6 +525,30 @@ public abstract partial class SharedStunSystem RemCompDeferred(entity); } + private void OnHandEquipped(Entity entity, ref DidEquipHandEvent args) + { + if (GameTiming.ApplyingState) + return; // The result of the change is already networked separately in the same game state + + RefreshKnockedMovement(entity); + } + + private void OnHandUnequipped(Entity entity, ref DidUnequipHandEvent args) + { + if (GameTiming.ApplyingState) + return; // The result of the change is already networked separately in the same game state + + RefreshKnockedMovement(entity); + } + + private void OnHandCountChanged(Entity entity, ref HandCountChangedEvent args) + { + if (GameTiming.ApplyingState) + return; // The result of the change is already networked separately in the same game state + + RefreshKnockedMovement(entity); + } + private void OnKnockdownAttempt(Entity entity, ref KnockDownAttemptEvent args) { // Directed, targeted moth attack. @@ -582,6 +609,7 @@ public abstract partial class SharedStunSystem ent.Comp.SpeedModifier = ev.SpeedModifier; ent.Comp.FrictionModifier = ev.FrictionModifier; + Dirty(ent); _movementSpeedModifier.RefreshMovementSpeedModifiers(ent); _movementSpeedModifier.RefreshFrictionModifiers(ent); diff --git a/Content.Shared/Tips/SharedTipsSystem.cs b/Content.Shared/Tips/SharedTipsSystem.cs new file mode 100644 index 0000000000..1973aae1a3 --- /dev/null +++ b/Content.Shared/Tips/SharedTipsSystem.cs @@ -0,0 +1,74 @@ +using Content.Shared.CCVar; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Tips; + +/// +/// Handles periodically displaying gameplay tips to all players ingame. +/// +public abstract class SharedTipsSystem : EntitySystem +{ + /// + /// Always adds this time to a speech message. This is so really short message stay around for a bit. + /// + private const float SpeechBuffer = 3f; + + /// + /// Expected reading speed. + /// + private const float Wpm = 180f; + + /// + /// Send a tippy message to all clients. + /// + /// The text to show in the speech bubble. + /// The entity to show. Defaults to tippy. + /// The time the speech bubble is shown, in seconds. + /// The time the entity takes to walk onto the screen, in seconds. + /// The time between waddle animation steps, in seconds. + public virtual void SendTippy( + string message, + EntProtoId? prototype = null, + float speakTime = 5f, + float slideTime = 3f, + float waddleInterval = 0.5f) + { } + + /// + /// Send a tippy message to the given player session. + /// + /// The player session to send the message to. + /// The text to show in the speech bubble. + /// The entity to show. Defaults to tippy. + /// The time the speech bubble is shown, in seconds. + /// The time the entity takes to walk onto the screen, in seconds. + /// The time between waddle animation steps, in seconds. + public virtual void SendTippy( + ICommonSession session, + string message, + EntProtoId? prototype = null, + float speakTime = 5f, + float slideTime = 3f, + float waddleInterval = 0.5f) + { } + + /// + /// Send a random tippy message from the dataset given in . + /// + public virtual void AnnounceRandomTip() { } + + /// + /// Set a random time stamp for the next automatic game tip. + /// + public virtual void RecalculateNextTipTime() { } + + /// + /// Calculate the recommended speak time for a given message. + /// + public float GetSpeechTime(string text) + { + var wordCount = (float)text.Split().Length; + return SpeechBuffer + wordCount * (60f / Wpm); + } +} diff --git a/Content.Shared/Tips/TippyEvent.cs b/Content.Shared/Tips/TippyEvent.cs index e5dc0b7f35..c6b028aa31 100644 --- a/Content.Shared/Tips/TippyEvent.cs +++ b/Content.Shared/Tips/TippyEvent.cs @@ -1,21 +1,37 @@ +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Tips; +/// +/// Networked event that makes a client show a message on their screen using tippy or another protoype. +/// [Serializable, NetSerializable] -public sealed class TippyEvent : EntityEventArgs +public sealed class TippyEvent(string msg, EntProtoId? proto, float speakTime, float slideTime, float waddleInterval) : EntityEventArgs { - public TippyEvent(string msg) - { - Msg = msg; - } + /// + /// The text to show in the speech bubble. + /// + public string Msg = msg; - public string Msg; - public string? Proto; + /// + /// The entity to show. Defaults to tippy. + /// + public EntProtoId? Proto = proto; - // TODO: Why are these defaults even here, have the caller specify. This get overriden only most of the time. - public float SpeakTime = 5; - public float SlideTime = 3; - public float WaddleInterval = 0.5f; + /// + /// The time the speech bubble is shown, in seconds. + /// + public float SpeakTime = speakTime; + + /// + /// The time the entity takes to walk onto the screen, in seconds. + /// + public float SlideTime = slideTime; + + /// + /// The time between waddle animation steps, in seconds. + /// + public float WaddleInterval = waddleInterval; } diff --git a/Content.Shared/Trigger/Components/Effects/AddTagsOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/AddTagsOnTriggerComponent.cs new file mode 100644 index 0000000000..9e73a60741 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/AddTagsOnTriggerComponent.cs @@ -0,0 +1,20 @@ +using Content.Shared.Tag; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Adds the given tags when triggered. +/// If TargetUser is true the tags will be added to the user instead. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class AddTagsOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// The tags to add. + /// + [DataField, AutoNetworkedField] + public List> Tags = new(); +} + diff --git a/Content.Shared/Trigger/Components/Effects/AdminLogOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/AdminLogOnTriggerComponent.cs new file mode 100644 index 0000000000..4045f8c12e --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/AdminLogOnTriggerComponent.cs @@ -0,0 +1,34 @@ +using Content.Shared.Database; +using Content.Shared.Random; +using Content.Shared.Trigger.Components.Triggers; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// This component creates an admin log when receiving a trigger. +/// is ignored. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class AdminLogOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// The message displayed in the logs describing what specifically was done by this trigger. + /// This entity and the user will be included alongside the message. + /// + [DataField(required: true), AutoNetworkedField] + public LocId Message = string.Empty; + + /// + /// What type of action took place? + /// + [DataField, AutoNetworkedField] + public LogType LogType = LogType.Trigger; + + /// + /// How important is this trigger? + /// + [DataField, AutoNetworkedField] + public LogImpact LogImpact = LogImpact.Low; +} diff --git a/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs new file mode 100644 index 0000000000..bf4e1841b1 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for removing and *deleting* all items in container(s) on the target. +/// +/// +/// Be very careful when setting to true or all your organs might fall out. +/// In fact, never set it to true. +/// +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class CleanContainersOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Names of containers to empty. + /// If null, all containers will be emptied. + /// + [DataField, AutoNetworkedField] + public List? Container; +} diff --git a/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs new file mode 100644 index 0000000000..de55e1f3ac --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for removing all items in container(s) on the target. +/// +/// +/// Be very careful when setting to true or all your organs might fall out. +/// In fact, never set it to true. +/// +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class EmptyContainersOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Names of containers to empty. + /// If null, all containers will be emptied. + /// + [DataField, AutoNetworkedField] + public List? Container; +} diff --git a/Content.Shared/Trigger/Components/Effects/JitterOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/JitterOnTriggerComponent.cs new file mode 100644 index 0000000000..340ad6cb01 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/JitterOnTriggerComponent.cs @@ -0,0 +1,47 @@ +using Content.Shared.StatusEffect; +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Makes the entity play a jitter animation when triggered. +/// If TargetUser is true the user will jitter instead. +/// +/// +/// The target requires . +/// TODO: Convert jitter to the new status effects system. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class JitterOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Jitteriness of the animation. + /// + [DataField, AutoNetworkedField] + public float Amplitude = 10.0f; + + /// + /// Frequency for jittering. + /// + [DataField, AutoNetworkedField] + public float Frequency = 4.0f; + + /// + /// For how much time to apply the effect. + /// + [DataField, AutoNetworkedField] + public TimeSpan Time = TimeSpan.FromSeconds(2); + + /// + /// The status effect cooldown should be refreshed (true) or accumulated (false). + /// + [DataField, AutoNetworkedField] + public bool Refresh; + + /// + /// Whether to change any existing jitter value even if they're greater than the ones we're setting. + /// + [DataField, AutoNetworkedField] + public bool ForceValueChange; +} + diff --git a/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs new file mode 100644 index 0000000000..33809130c2 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs @@ -0,0 +1,36 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for sending the target sidewise (crawling). +/// Knockdowns the user if is true. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class KnockdownOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// How long the target is forced to be on the ground. + /// + [DataField, AutoNetworkedField] + public TimeSpan KnockdownAmount = TimeSpan.FromSeconds(1); + + /// + /// If true, refresh the duration. + /// If false, time is added on-top of any existing forced knockdown. + /// + [DataField, AutoNetworkedField] + public bool Refresh = true; + + /// + /// Should the entity try and stand automatically? + /// + [DataField, AutoNetworkedField] + public bool AutoStand = true; + + /// + /// Should the entity drop their items upon first being knocked down? + /// + [DataField, AutoNetworkedField] + public bool Drop = true; +} diff --git a/Content.Shared/Trigger/Components/Effects/RandomTriggerOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/RandomTriggerOnTriggerComponent.cs new file mode 100644 index 0000000000..f7d8c5036c --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/RandomTriggerOnTriggerComponent.cs @@ -0,0 +1,21 @@ +using Content.Shared.Random; +using Content.Shared.Trigger.Components.Triggers; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// When triggered this component will choose a key and send a new trigger. +/// Trigger is sent to user if is true. +/// +/// Does not support recursive loops where this component triggers itself. Use instead. +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class RandomTriggerOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// The trigger keys and their weights. + /// + [DataField(required: true), AutoNetworkedField] + public ProtoId RandomKeyOut; +} diff --git a/Content.Shared/Trigger/Components/Effects/RemoveTagsOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/RemoveTagsOnTriggerComponent.cs new file mode 100644 index 0000000000..8e4d0e4611 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/RemoveTagsOnTriggerComponent.cs @@ -0,0 +1,20 @@ +using Content.Shared.Tag; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Remove the given tags when triggered. +/// If TargetUser is true the tags will be added to the user instead. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class RemoveTagsOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// The tags to remove. + /// + [DataField, AutoNetworkedField] + public List> Tags = new(); +} + diff --git a/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs new file mode 100644 index 0000000000..ebe55dc102 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for stunning an entity. +/// Stuns the user if is true. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class StunOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// How long to stun the target. + /// + [DataField, AutoNetworkedField] + public TimeSpan StunAmount = TimeSpan.FromSeconds(1); + + /// + /// If true, refresh the stun duration. + /// If false, stun is added on-top of any existing stun. + /// + [DataField, AutoNetworkedField] + public bool Refresh = true; +} diff --git a/Content.Shared/Trigger/Components/Effects/SwapLocationOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/SwapLocationOnTriggerComponent.cs new file mode 100644 index 0000000000..33cec1d56d --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/SwapLocationOnTriggerComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Swaps the location of the target and the user of the trigger when triggered. +/// is ignored. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SwapLocationOnTriggerComponent : BaseXOnTriggerComponent; diff --git a/Content.Shared/Trigger/Components/Effects/TippyOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/TippyOnTriggerComponent.cs new file mode 100644 index 0000000000..9476d9ea1c --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/TippyOnTriggerComponent.cs @@ -0,0 +1,66 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Sends a tippy message to either the entity or all players when triggered. +/// If TargetUser is true the user will receive the message. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TippyOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Unlocalized message text to send to the player(s). + /// Intended only for admeme purposes. For anything else you should use instead. + /// + [DataField, AutoNetworkedField] + public string Message = string.Empty; + + /// + /// Localized message text to send to the player(s). + /// This has priority over . + /// + [DataField, AutoNetworkedField] + public LocId? LocMessage; + + /// + /// If true the message will be send to all players. + /// If false it will be send to the user or owning entity, depending on . + /// + [DataField, AutoNetworkedField] + public bool SendToAll; + + /// + /// The entity prototype to show to the client. + /// Will default to tippy if null. + /// + [DataField, AutoNetworkedField] + public EntProtoId? Prototype; + + /// + /// Use the prototype of the entity owning this component? + /// Will take priority over . + /// + [DataField, AutoNetworkedField] + public bool UseOwnerPrototype; + + /// + /// The time the speech bubble is shown, in seconds. + /// Will be calculated automatically from the message length if null. + /// + [DataField, AutoNetworkedField] + public float? SpeakTime; + + /// + /// The time the entity takes to walk onto the screen, in seconds. + /// + [DataField, AutoNetworkedField] + public float SlideTime = 3f; + + /// + /// The time between waddle animation steps, in seconds. + /// + [DataField, AutoNetworkedField] + public float WaddleInterval = 0.5f; +} diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs new file mode 100644 index 0000000000..4e832993b5 --- /dev/null +++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Triggers; + +/// +/// Trigger for when this entity is thrown and then hits a second entity. +/// User is the entity hit. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TriggerOnThrowDoHitComponent : BaseTriggerOnXComponent; diff --git a/Content.Shared/Trigger/Systems/AdminLogOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/AdminLogOnTriggerSystem.cs new file mode 100644 index 0000000000..0adf483aed --- /dev/null +++ b/Content.Shared/Trigger/Systems/AdminLogOnTriggerSystem.cs @@ -0,0 +1,19 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class AdminLogOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + _adminLogger.Add( + ent.Comp.LogType, + ent.Comp.LogImpact, + $"{ToPrettyString(args.User)} sent a trigger using {ToPrettyString(ent)}: {Loc.GetString(ent.Comp.Message)}" + ); + // Intentionally does not handle the event since this shouldn't affect the gamestate. + } +} diff --git a/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs new file mode 100644 index 0000000000..dbe1601022 --- /dev/null +++ b/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs @@ -0,0 +1,81 @@ +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Containers; + +namespace Content.Shared.Trigger.Systems; + +/// +/// Empty containers trigger system. +/// +public sealed class EmptyContainersOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedContainerSystem _container = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (!TryComp(target, out var containerComp)) + return; + + // Empty everything. Make sure a player isn't the target because they will get removed from their body along with their organs + if (ent.Comp.Container is null) + { + foreach (var container in _container.GetAllContainers(target, containerComp)) + { + _container.EmptyContainer(container); + } + + args.Handled = true; + } + + // Empty containers in a sane way + else + { + foreach (var containerId in ent.Comp.Container) + { + if (!_container.TryGetContainer(target, containerId, out var container, containerComp)) + continue; + + _container.EmptyContainer(container); + args.Handled = true; + } + } + } +} + +/// +/// Empty containers and delete items trigger system. +/// +public sealed class CleanContainersOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedContainerSystem _container = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (!TryComp(target, out var containerComp)) + return; + + // Empty everything. Make sure a player isn't the target because they will get DELETED + if (ent.Comp.Container is null) + { + foreach (var container in _container.GetAllContainers(target, containerComp)) + { + _container.CleanContainer(container); + } + + args.Handled = true; + } + + // Empty containers in a sane way + else + { + foreach (var containerId in ent.Comp.Container) + { + if (!_container.TryGetContainer(target, containerId, out var container, containerComp)) + continue; + + _container.CleanContainer(container); + args.Handled = true; + } + } + } +} + diff --git a/Content.Shared/Trigger/Systems/JitterOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/JitterOnTriggerSystem.cs new file mode 100644 index 0000000000..5a9e0463ed --- /dev/null +++ b/Content.Shared/Trigger/Systems/JitterOnTriggerSystem.cs @@ -0,0 +1,20 @@ +using Content.Shared.Jittering; +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Network; + +namespace Content.Shared.Trigger.Systems; + +public sealed class JitterOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedJitteringSystem _jittering = default!; + [Dependency] private readonly INetManager _net = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + // DoJitter mispredicts at the moment. + // TODO: Fix this and remove the IsServer check. + if (_net.IsServer) + _jittering.DoJitter(target, ent.Comp.Time, ent.Comp.Refresh, ent.Comp.Amplitude, ent.Comp.Frequency, ent.Comp.ForceValueChange); + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs new file mode 100644 index 0000000000..815e00abc8 --- /dev/null +++ b/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Stunnable; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class KnockdownOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedStunSystem _stun = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + args.Handled |= _stun.TryKnockdown( + target, + ent.Comp.KnockdownAmount, + ent.Comp.Refresh, + ent.Comp.AutoStand, + ent.Comp.Drop, + true + ); + } +} diff --git a/Content.Shared/Trigger/Systems/RandomTriggerOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/RandomTriggerOnTriggerSystem.cs new file mode 100644 index 0000000000..75acc005d0 --- /dev/null +++ b/Content.Shared/Trigger/Systems/RandomTriggerOnTriggerSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared.Random.Helpers; +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Shared.Trigger.Systems; + +public sealed class RandomTriggerOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly TriggerSystem _trigger = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IGameTiming _timing = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + // TODO: Replace with RandomPredicted once the engine PR is merged + var hash = new List + { + (int)_timing.CurTick.Value, + GetNetEntity(ent).Id, + args.User == null ? 0 : GetNetEntity(args.User.Value).Id, + }; + var seed = SharedRandomExtensions.HashCodeCombine(hash); + var rand = new System.Random(seed); + + var keyOut = _prototypeManager.Index(ent.Comp.RandomKeyOut).Pick(rand); + + // Prevent recursive triggers + if (target == ent.Owner && ent.Comp.KeysIn.Contains(keyOut)) + { + Log.Warning($"{ToPrettyString(ent)} attempted to recursively trigger itself using RandomTriggerOnTriggerComponent."); + return; + } + + _trigger.Trigger(target, args.User, keyOut); + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs new file mode 100644 index 0000000000..ce86f971d3 --- /dev/null +++ b/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs @@ -0,0 +1,17 @@ +using Content.Shared.Stunnable; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class StunOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedStunSystem _stun = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (ent.Comp.Refresh) + args.Handled |= _stun.TryUpdateStunDuration(target, ent.Comp.StunAmount); + else + args.Handled |= _stun.TryAddStunDuration(target, ent.Comp.StunAmount); + } +} diff --git a/Content.Shared/Trigger/Systems/SwapLocationOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/SwapLocationOnTriggerSystem.cs new file mode 100644 index 0000000000..7b3004ad59 --- /dev/null +++ b/Content.Shared/Trigger/Systems/SwapLocationOnTriggerSystem.cs @@ -0,0 +1,30 @@ +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Network; + +namespace Content.Shared.Trigger.Systems; + +public sealed class SwapLocationOnTriggerSystem : EntitySystem +{ + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly INetManager _net = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnTrigger); + } + + private void OnTrigger(Entity ent, ref TriggerEvent args) + { + if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key)) + return; + + if (args.User == null) + return; + + // SwapPositions mispredicts at the moment. + // TODO: Fix this and remove the IsServer check. + if (_net.IsServer) + _transform.SwapPositions(ent.Owner, args.User.Value); + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Systems/TagOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/TagOnTriggerSystem.cs new file mode 100644 index 0000000000..d636593d43 --- /dev/null +++ b/Content.Shared/Trigger/Systems/TagOnTriggerSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.Tag; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class AddTagsOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly TagSystem _tag = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + _tag.AddTags(target, ent.Comp.Tags); + args.Handled = true; + } +} + +public sealed class RemoveTagsOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly TagSystem _tag = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + _tag.RemoveTags(target, ent.Comp.Tags); + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Systems/TippyOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/TippyOnTriggerSystem.cs new file mode 100644 index 0000000000..10c55490af --- /dev/null +++ b/Content.Shared/Trigger/Systems/TippyOnTriggerSystem.cs @@ -0,0 +1,49 @@ +using Content.Shared.Tips; +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Player; + +namespace Content.Shared.Trigger.Systems; + +public sealed class TippyOnTriggerSystem : EntitySystem +{ + [Dependency] private readonly SharedTipsSystem _tips = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnTrigger); + } + + private void OnTrigger(Entity ent, ref TriggerEvent args) + { + if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key)) + return; + + var msg = ent.Comp.Message; + var prototype = ent.Comp.Prototype; + + if (ent.Comp.LocMessage != null) + msg = Loc.GetString(ent.Comp.LocMessage.Value); + + if (ent.Comp.UseOwnerPrototype) + prototype = Prototype(ent)?.ID; + + var speakTime = ent.Comp.SpeakTime ?? _tips.GetSpeechTime(msg); + + if (ent.Comp.SendToAll) + { + _tips.SendTippy(msg, prototype, speakTime, ent.Comp.SlideTime, ent.Comp.WaddleInterval); + } + else + { + var target = ent.Comp.TargetUser ? args.User : ent.Owner; + if (!TryComp(target, out var actor)) + return; + + _tips.SendTippy(actor.PlayerSession, msg, prototype, speakTime, ent.Comp.SlideTime, ent.Comp.WaddleInterval); + } + + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs b/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs new file mode 100644 index 0000000000..ca57b517c6 --- /dev/null +++ b/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs @@ -0,0 +1,19 @@ +using Content.Shared.Throwing; +using Content.Shared.Trigger.Components.Triggers; + +namespace Content.Shared.Trigger.Systems; + +public sealed partial class TriggerOnThrowDoHitSystem : TriggerOnXSystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnHit); + } + + private void OnHit(Entity ent, ref ThrowDoHitEvent args) + { + Trigger.Trigger(ent.Owner, args.Target, ent.Comp.KeyOut); + } +} diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs index 62b68fed6e..c2dfa23fcb 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs @@ -154,8 +154,6 @@ public abstract partial class SharedGunSystem Del(ent.Value); } - UpdateBallisticAppearance(args.Target.Value, component); - UpdateAmmoCount(args.Target.Value); // repeat if there is more space in the target and more ammo to fill var moreSpace = target.Entities.Count + target.UnspawnedCount < target.Capacity; var moreAmmo = component.Entities.Count + component.UnspawnedCount > 0; diff --git a/Content.Shared/Xenoarchaeology/Artifact/XAE/XAEKnockSystem.cs b/Content.Shared/Xenoarchaeology/Artifact/XAE/XAEKnockSystem.cs index 9cc9efe51b..716ef6c660 100644 --- a/Content.Shared/Xenoarchaeology/Artifact/XAE/XAEKnockSystem.cs +++ b/Content.Shared/Xenoarchaeology/Artifact/XAE/XAEKnockSystem.cs @@ -1,6 +1,5 @@ -using Content.Shared.Magic.Events; +using Content.Shared.Magic; using Content.Shared.Xenoarchaeology.Artifact.XAE.Components; -using Robust.Shared.Timing; namespace Content.Shared.Xenoarchaeology.Artifact.XAE; @@ -9,19 +8,10 @@ namespace Content.Shared.Xenoarchaeology.Artifact.XAE; /// public sealed class XAEKnockSystem : BaseXAESystem { - [Dependency] private readonly IGameTiming _timing = default!; - + [Dependency] private readonly SharedMagicSystem _magic = default!; /// protected override void OnActivated(Entity ent, ref XenoArtifactNodeActivatedEvent args) { - if (!_timing.IsFirstTimePredicted) - return; - - var ev = new KnockSpellEvent - { - Performer = ent.Owner, - Range = ent.Comp.KnockRange - }; - RaiseLocalEvent(ev); + _magic.Knock(args.Artifact, ent.Comp.KnockRange); } } diff --git a/Content.Shared/Xenoborgs/Components/MothershipCoreComponent.cs b/Content.Shared/Xenoborgs/Components/MothershipCoreComponent.cs new file mode 100644 index 0000000000..4835e20aad --- /dev/null +++ b/Content.Shared/Xenoborgs/Components/MothershipCoreComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Xenoborgs.Components; + +/// +/// Defines what is a xenoborg core for the intentions of the xenoborg rule. if all xenoborg cores are destroyed. all xenoborgs will self-destruct. +/// +[RegisterComponent] +public sealed partial class MothershipCoreComponent : Component; diff --git a/Content.Shared/Xenoborgs/Components/XenoborgComponent.cs b/Content.Shared/Xenoborgs/Components/XenoborgComponent.cs index aee8298bc2..db4ca49c5b 100644 --- a/Content.Shared/Xenoborgs/Components/XenoborgComponent.cs +++ b/Content.Shared/Xenoborgs/Components/XenoborgComponent.cs @@ -1,7 +1,32 @@ +using Content.Shared.Roles.Components; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + namespace Content.Shared.Xenoborgs.Components; /// -/// This component for now is being used for the pinpointer, but it will recieve more stuff in the future. +/// Defines what is a xenoborg for the intentions of the xenoborg rule. if all xenoborg cores are destroyed. all xenoborgs will self-destruct. +/// +/// It's also used by the mothership core /// [RegisterComponent] -public sealed partial class XenoborgMothershipComponent : Component; +public sealed partial class XenoborgComponent : Component +{ + /// + /// The mindrole associated with the xenoborg + /// + [DataField] + public EntProtoId MindRole = "MindRoleXenoborg"; + + /// + /// The text that is sent when you become a xenoborg + /// + [DataField] + public LocId BriefingText = "xenoborgs-welcome"; + + /// + /// Briefing sound when you become a xenoborg + /// + [DataField] + public SoundSpecifier BriefingSound = new SoundPathSpecifier("/Audio/Ambience/Antag/xenoborg_start.ogg"); +} diff --git a/Resources/Audio/Ambience/Antag/attributions.yml b/Resources/Audio/Ambience/Antag/attributions.yml index 5418d2a204..c9a9b1304d 100644 --- a/Resources/Audio/Ambience/Antag/attributions.yml +++ b/Resources/Audio/Ambience/Antag/attributions.yml @@ -30,4 +30,7 @@ license: "CC-BY-SA-3.0" copyright: "Taken from TG station at commit https://github.com/tgstation/tgstation/commit/436ba869ebcd0b60b63973fb7562f447ee655205" source: "https://github.com/tgstation/tgstation/blob/master/sound/music/antag/ling_alert.ogg" - +- files: ["xenoborg_start.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Made by DarkIcedCoffee (discord)" + source: "https://github.com/space-wizards/space-station-14/pull/40042/" diff --git a/Resources/Audio/Ambience/Antag/xenoborg_start.ogg b/Resources/Audio/Ambience/Antag/xenoborg_start.ogg new file mode 100644 index 0000000000..97fe49db99 Binary files /dev/null and b/Resources/Audio/Ambience/Antag/xenoborg_start.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Gunshots/energycrossbow_shoot.ogg b/Resources/Audio/Weapons/Guns/Gunshots/energycrossbow_shoot.ogg new file mode 100644 index 0000000000..f2fba353bc Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Gunshots/energycrossbow_shoot.ogg differ diff --git a/Resources/Audio/Weapons/Guns/MagIn/energycrossbow_reload.ogg b/Resources/Audio/Weapons/Guns/MagIn/energycrossbow_reload.ogg new file mode 100644 index 0000000000..0c27641e03 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/MagIn/energycrossbow_reload.ogg differ diff --git a/Resources/Audio/Weapons/Guns/sources.json b/Resources/Audio/Weapons/Guns/sources.json index cc9a3e5c0b..351fba0992 100644 --- a/Resources/Audio/Weapons/Guns/sources.json +++ b/Resources/Audio/Weapons/Guns/sources.json @@ -34,7 +34,8 @@ "shotgun.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/fire/shotgunp_fire.ogg", "silenced.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/Gunshot_silenced.wav", "smg.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/fire/smg_fire.ogg", - "sniper.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/fire/sniper_fire.ogg" + "sniper.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/fire/sniper_fire.ogg", + "energy_crossbowshoot.ogg": "Made on request by Nosrepp (Discord)" }, "MagIn": { "batrifle_magin.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/batrifle_magin.ogg", @@ -47,7 +48,8 @@ "sfrifle_magin.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/sfrifle_magin.ogg", "smg_magin.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/smg_magin.ogg", "revolver_magin.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/rev_magin.ogg", - "shotgun_insert.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/shotgun_insert.ogg" + "shotgun_insert.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/shotgun_insert.ogg", + "energy_crossbowreload.ogg": "Made on request by Nosrepp (Discord)" }, "MagOut": { "batrifle_magout.ogg": "https://github.com/discordia-space/CEV-Eris/blob/01f7518e0f8177734a6579aba2bbf76024aa96c4/sound/weapons/guns/interact/batrifle_magout.ogg", diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index 2a80134c15..59827600ec 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -1505,5 +1505,22 @@ Entries: id: 183 time: '2025-11-03T13:16:43.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/41261 +- author: slarticodefast + changes: + - message: Added the "quickinspect" command to quickly inspect the selected component + for an entity via a keybind. + type: Add + id: 184 + time: '2025-11-12T23:22:27.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41348 +- author: ScarKy0 + changes: + - message: Admin ghosts can no longer be selected for "Warp To Most Followed". Remove + the NotGhostnadoWarpable tag from your aghost entity if you wish to still be + able to be selected. + type: Fix + id: 185 + time: '2025-11-15T23:31:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41448 Name: Admin Order: 3 diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index debd9967d7..7e8273f33d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,192 +1,4 @@ Entries: -- author: KamTheSythe - changes: - - message: Explosive payloads no longer explode. Modular grenades with explosive - payloads remain unchanged, and can still be used to stack explosions. - type: Tweak - id: 8687 - time: '2025-06-17T09:46:36.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38049 -- author: Kittygyat - changes: - - message: Increased borg drag speed, equivalent to Diona speeds. - type: Tweak - id: 8688 - time: '2025-06-17T10:41:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38232 -- author: TheFlyingSentry - changes: - - message: Animal stealing thief objectives now actually check for the objective's - existence. - type: Tweak - id: 8689 - time: '2025-06-17T11:06:21.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38332 -- author: kosticia - changes: - - message: Reflection chances are examinable now. - type: Add - id: 8690 - time: '2025-06-18T00:50:01.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38199 -- author: Kittygyat - changes: - - message: Fixed vapes dealing unintended damage types to you when used. - type: Fix - id: 8691 - time: '2025-06-18T12:06:13.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38423 -- author: beck-thompson - changes: - - message: Recycler now properly recycles item stacks. - type: Fix - id: 8692 - time: '2025-06-18T21:14:01.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38433 -- author: Bhijn and Myr - changes: - - message: In interest of raising awareness of addiction to the game, the lobby - will now display your current playtime on a given day once it exceeds a threshold. - type: Add - id: 8693 - time: '2025-06-19T01:06:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/36483 -- author: ScarKy0 - changes: - - message: APCs now have a wirepanel. It can be used to disallow the AI from accessing - it. - type: Add - id: 8694 - time: '2025-06-19T15:06:11.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38443 -- author: Sparlight - changes: - - message: Smart corgis can now wear various hardsuits, armors, and glasses items. - type: Add - id: 8695 - time: '2025-06-19T19:49:09.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/36875 -- author: VerinSenpai - changes: - - message: Handcuffs no longer interfere with your daily tail wagging activities. - type: Fix - id: 8696 - time: '2025-06-19T22:42:21.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38454 -- author: BigfootBravo - changes: - - message: Chameleon Controller Implants can be deimplanted. - type: Fix - id: 8697 - time: '2025-06-20T22:41:11.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38439 -- author: FairlySadPanda - changes: - - message: A new poster. - type: Add - - message: A new (very expensive) crate to order from cargo, worth 25,000 spesos - and containing a hydrated scurret. The hydrated scurret is a ghost role - a - non-antagonistic emotional support scurret. - type: Add - id: 8698 - time: '2025-06-20T23:39:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38218 -- author: Tayrtahn - changes: - - message: Sloths... now... speak... slowly... - type: Add - id: 8699 - time: '2025-06-21T06:32:30.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38142 -- author: whatston3 - changes: - - message: Locked buttons must now be unlocked to trigger. - type: Fix - id: 8700 - time: '2025-06-21T09:41:04.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38474 -- author: slarticodefast - changes: - - message: Fixed wallmount interaction rotation. - type: Fix - id: 8701 - time: '2025-06-21T13:11:17.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38111 -- author: Prole0 - changes: - - message: Flask Visuals & Sounds! - type: Add - - message: Flasks now need to be opened to be drunk from. - type: Tweak - id: 8702 - time: '2025-06-21T14:52:36.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38032 -- author: qrwas - changes: - - message: Loadout item group UI improvements - type: Tweak - id: 8703 - time: '2025-06-21T22:20:34.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38488 -- author: perryprog - changes: - - message: Wet mops no longer have zero melee damage. - type: Fix - id: 8704 - time: '2025-06-21T22:23:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38486 -- author: Cojoke-dot - changes: - - message: Pacifists can now use the Staff of Healing - type: Tweak - id: 8706 - time: '2025-06-22T19:38:22.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38509 -- author: slarticodefast - changes: - - message: The interrogator lamp and flash lantern now properly flash when toggled - on. - type: Fix - id: 8707 - time: '2025-06-23T11:32:57.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/37640 -- author: metalgearsloth - changes: - - message: Added ambient occlusion to walls so they have shadows around them. - type: Add - id: 8708 - time: '2025-06-24T07:56:15.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38276 -- author: BramvanZijp - changes: - - message: Added Stamina Damage resistance to the raid/hard-suits used by Nuclear - Operatives and Emergency Response Teams. - type: Tweak - id: 8709 - time: '2025-06-24T13:04:15.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38526 -- author: Kittygyat - changes: - - message: Added a handheld station map to the borg thruster module! - type: Add - id: 8710 - time: '2025-06-24T15:35:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38541 -- author: PJB3005 - changes: - - message: Fixed various worn clothing items being invisible when seen through UI, - such as the examine popups. - type: Fix - id: 8711 - time: '2025-06-24T20:47:29.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38042 -- author: AreYouConfused - changes: - - message: Bulldog bundle now accurately says what is included - type: Fix - id: 8712 - time: '2025-06-24T21:58:58.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/38558 - author: Dragonjspider changes: - message: The Cutter Machine no longer makes Dark Techmaints floor tiles for free @@ -3925,3 +3737,192 @@ Entries: id: 9188 time: '2025-11-06T21:46:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/41163 +- author: Jrpl + changes: + - message: Gravity Generators can no longer be unanchored while they are active. + type: Fix + id: 9189 + time: '2025-11-07T01:05:04.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41256 +- author: Hitlinemoss + changes: + - message: The golden plunger and security star have been moved to their respective + roles' "Job trinkets" loadout tab. + type: Tweak + id: 9190 + time: '2025-11-07T07:43:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41094 +- author: Princess-Cheeseballs + changes: + - message: Items no longer spin on Conveyors + type: Fix + id: 9191 + time: '2025-11-08T20:40:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/37468 +- author: Princess-Cheeseballs + changes: + - message: Paradox clones now copy forensics from the original + type: Fix + id: 9192 + time: '2025-11-09T01:46:21.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41358 +- author: SirWarock + changes: + - message: Fixed Magazines not properly visualizing how much ammo they had left + in them! + type: Fix + id: 9193 + time: '2025-11-09T07:54:23.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41362 +- author: mirrorcult + changes: + - message: Lighting attenuation has changed slightly. You shouldn't notice much + difference, but the edges of lights should look better. If any lights are significantly + different than they used to be, make a GitHub issue. + type: Tweak + id: 9194 + time: '2025-11-09T16:29:24.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41361 +- author: beck-thompson + changes: + - message: The Summon Magic spell no longer will give out healing wands. When there + are more wands added it will be brought back + type: Tweak + id: 9195 + time: '2025-11-10T13:57:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41365 +- author: SolidSyn + changes: + - message: Clowns and Lawyers can now print their respective skirts and suitskirts + at a uniform lathe + type: Add + id: 9196 + time: '2025-11-11T06:20:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39846 +- author: April-Gras + changes: + - message: Tool-tip punctuation for the accentless speech trait + type: Tweak + id: 9197 + time: '2025-11-11T17:57:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41392 +- author: Nox38 + changes: + - message: All grenades now start their fuse after taking 10 damage, and instantly + detonate or break after taking 45. + type: Tweak + id: 9198 + time: '2025-11-11T19:01:01.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/34499 +- author: aada + changes: + - message: Employed lizard plushies can now be found in bulk lizard plushie crates + and maintenance closets. + type: Tweak + id: 9199 + time: '2025-11-12T07:37:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41398 +- author: PicklOH + changes: + - message: Make DAGD more likely but restrict it to 1 traitor per round + type: Tweak + id: 9200 + time: '2025-11-12T16:31:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41402 +- author: MissKay1994 + changes: + - message: Added a new briefcase gun to the lawyer job's uplink. + type: Add + id: 9201 + time: '2025-11-13T21:39:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/40210 +- author: Hitlinemoss + changes: + - message: Security IDs no longer have Service access by default. + type: Remove + id: 9202 + time: '2025-11-14T11:15:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41411 +- author: Samuka, DarkIcedCoffee, Whale + changes: + - message: 'Added a new antag: Xenoborgs' + type: Add + id: 9203 + time: '2025-11-14T22:21:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/40042 +- author: Entvari, Nosrepp + changes: + - message: Added the Mini Energy Crossbow to Traitor and Nukie uplinks. + type: Add + - message: The Foam Crossbow now uses the new sounds shared by the Mini Energy Crossbow. + type: Tweak + id: 9204 + time: '2025-11-14T22:34:24.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39796 +- author: April-Gras + changes: + - message: Rat king now goes 0.5 faster when sprinting + type: Tweak + id: 9205 + time: '2025-11-15T05:27:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41420 +- author: Fildrance + changes: + - message: KNOCK spell and 'Mild electromagnetic interference' xeno artifact effects + now will be blocked only by obstructed line of sight (range is still applied) + type: Tweak + id: 9206 + time: '2025-11-15T23:18:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41447 +- author: Princess-Cheeseballs + changes: + - message: No2 should put you to sleep again without needing double the gas. + type: Fix + id: 9207 + time: '2025-11-16T01:03:18.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41438 +- author: buunie099 + changes: + - message: Vulpkannin cries now use the same sounds as whining + type: Tweak + id: 9208 + time: '2025-11-16T10:34:39.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/40982 +- author: slarticodefast + changes: + - message: Crawling speed now depends on the number of free hands you have. + type: Tweak + id: 9209 + time: '2025-11-16T23:59:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41458 +- author: Samuka + changes: + - message: The xenoborg mothership core can now pull stuff. + type: Fix + id: 9210 + time: '2025-11-17T17:42:27.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41460 +- author: Samuka + changes: + - message: Borg modules now tell which kind of borgs they fit into. + type: Add + id: 9211 + time: '2025-11-17T18:07:29.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41461 +- author: Hitlinemoss + changes: + - message: The CMO's locker no longer contains a duplicate beret/cloak. + type: Fix + - message: The neck gaiter in the HoS's locker has been moved to their dresser. + type: Fix + id: 9212 + time: '2025-11-19T02:58:33.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41487 +- author: korczoczek + changes: + - message: Packed's evac shuttle will no longer have its air chamber glass break + upon loading + type: Fix + id: 9213 + time: '2025-11-19T22:15:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41500 diff --git a/Resources/Changelog/Maps.yml b/Resources/Changelog/Maps.yml index 80ff2191eb..13186ab6f2 100644 --- a/Resources/Changelog/Maps.yml +++ b/Resources/Changelog/Maps.yml @@ -819,4 +819,11 @@ id: 99 time: '2025-11-03T09:45:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/41072 +- author: F1restar4 + changes: + - message: On Exo, connected medbay's dispo units to the network + type: Fix + id: 100 + time: '2025-11-07T08:36:02.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/41329 Order: 2 diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 1fd1cf2ef9..902b0964d3 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0leshe, 0tito, 0x6273, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 27alaing, 2DSiggy, 3nderall, 4310v343k, 4dplanner, 5tickman, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, Ahion, aiden, Aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, Alpha-Two, AlphaQwerty, Altoids1, amatwiedle, amylizzle, ancientpower, Andre19926, Andrew-Fall, AndrewEyeke, AndrewFenriz, AndreyCamper, anri, Anzarot121, ApolloVector, Appiah, ar4ill, Arcane-Waffle, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, Atakku, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, AwareFoxy, Awlod, AzzyIsNotHere, azzyisnothere, B-Kirill, B3CKDOOR, baa14453, BackeTako, BadaBoomie, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, Blobadoodle, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, breeplayx3, BriBrooo, Bright0, BRINGit34, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, CawsForConcern, Centronias, Chaboricks, chairbender, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, cloudyias, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, CraftyRenter, crazybrain23, Crazydave91920, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dan, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, david, DawBla, Daxxi3, dch-GH, ddeegan, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, DieselMohawkTheSequel, digitalic, Dimastra, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, emberwinters, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, ewokswagger, exincore, exp111, f0x-n3rd, F1restar4, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Funce, FungiFellow, FunkySphere, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, GitHubUser53123, gituhabu, GlassEclipse, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, GR1231, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, Hayden, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, Hi-Im-Shot, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, hoshizora-sayo, Hreno, Hrosts, htmlsystem, Huaqas, hubismal, Hugal31, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, JackRyd3r, jacksonzck, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, JesterX666, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, johnku1, Jophire, Jopogrechkin, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, KieueCaprie, Kimpes, KingFroozy, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit, Kit0vras, KittenColony, Kittygyat, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, kosticia, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, Krosus777, Krunklehorn, Kryyto, Kupie, kxvvv, Kyoth25f, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leah, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, LetterN, lettern, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, LightVillet, lilazero, liltenhead, linkbro1, linkuyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, Lordbrandon12, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luegamer, luizwritescode, Lukasz825700516, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lzimann, M1tht1c, M3739, M4rchy-S, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, magnuscrowe, maland1, malchanceux, MaloTV, ManelNavola, manelnavola, Mangohydra, marboww, Markek1, MarkerWicker, marlyn, matt, Matz05, max, MaxNox7, maylokana, MDuch369, meganerobot, MehimoNemo, Mehnix, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mqole, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, mtrs163, muburu, MureixloI, murolem, murphyneko, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, NoreUhh, not-gavnaed, notafet, notquitehadouken, notsodana, noudoit, noverd, Nox38, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnsenCapy, OnyxTheBrave, opl-, Orange-Winds, OrangeMoronage9622, OrbitSystem07, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, PGrayCS, pgraycs, Pgriha, phantom-lily, pheenty, philingham, Phill101, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, Pissachu, pissdemon, Pixel8-dev, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, pok27, Pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, PROG-MohamedDwidar, Prole0, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quasr-9, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rhailrake, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, rosieposieeee, Roudenn, router, ruddygreat, rumaks, RumiTiger, Ruzihm, S1rFl0, S1ss3l, Saakra, Sadie-silly, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, shibechef, Siginanto, signalsender, SignalWalker, siigiil, silicon14wastaken, Silverfur-underscore, Simyon264, sirdragooon, Sirionaut, SirWarock, Sk1tch, SkaldetSkaeg, Skarletto, Skybailey-dev, skye, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, SnappingOpossum, snebl, snicket, sniperchance, Snowni, snowsignal, SolidSyn, SolidusSnek, solstar2, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, SpaceLizard24, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, Steffo99, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, SuperGDPWYL, superjj18, Supernorn, SurrealShibe, SweetAplle, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telavivgamers, telyonok, temm1ie, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, thanosdegraf, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheFlyingSentry, TheGrimbeeper, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheSecondLord, TheShuEd, thetolbean, thevinter, TheWaffleJesus, thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, travis-g-reid, treytipton, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, Uberration, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, unusualcrow, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, vgskye, viceemargo, VigersRay, violet754, Visne, vitopigno, vitusveit, vlad, vlados1408, VMSolidus, vmzd, VoidMeticulous, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wachte1, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, Worldwaker, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, YuriyKiss, yuriykiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex +0leshe, 0tito, 0x6273, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 27alaing, 2DSiggy, 3nderall, 4310v343k, 4dplanner, 5tickman, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, Ahion, aiden, aidenkrz, Aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, Alpha-Two, AlphaQwerty, Altoids1, amatwiedle, amylizzle, ancientpower, Andre19926, Andrew-Fall, AndrewEyeke, AndrewFenriz, AndreyCamper, anri, Anzarot121, ApolloVector, Appiah, april-gras, ar4ill, Arcane-Waffle, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, Atakku, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, AwareFoxy, Awlod, azzyisnothere, AzzyIsNotHere, B-Kirill, B3CKDOOR, baa14453, BackeTako, BadaBoomie, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, bebr3ght, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, Blobadoodle, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, breeplayx3, BriBrooo, Bright0, BRINGit34, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, CawsForConcern, Centronias, Chaboricks, chairbender, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, cloudyias, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, CraftyRenter, crazybrain23, Crazydave91920, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dan, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, david, DawBla, Daxxi3, dch-GH, ddeegan, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, DieselMohawkTheSequel, digitalic, Dimastra, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, emberwinters, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, ewokswagger, exincore, exp111, f0x-n3rd, F1restar4, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Funce, FungiFellow, FunkySphere, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, GitHubUser53123, gituhabu, GlassEclipse, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, GR1231, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, Hayden, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, Hi-Im-Shot, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, hoshizora-sayo, Hreno, Hrosts, htmlsystem, Huaqas, hubismal, Hugal31, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, JackRyd3r, jacksonzck, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, JesterX666, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, johnku1, Jophire, Jopogrechkin, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, KieueCaprie, Kimpes, kin98, KingFroozy, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit, Kit0vras, KittenColony, Kittygyat, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, kosticia, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, Krosus777, Krunklehorn, Kryyto, Kupie, kxvvv, Kyoth25f, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leah, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, lettern, LetterN, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, LightVillet, lilazero, liltenhead, linkbro1, linkuyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, Lordbrandon12, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luegamer, luizwritescode, LukaSlade, Lukasz825700516, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lzimann, lzk228, M1tht1c, M3739, M4rchy-S, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, magnuscrowe, maland1, malchanceux, MaloTV, ManelNavola, manelnavola, Mangohydra, marboww, Markek1, MarkerWicker, marlyn, matt, Matz05, max, MaxNox7, maylokana, MDuch369, meganerobot, MehimoNemo, Mehnix, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mqole, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, mtrs163, muburu, MureixloI, murolem, murphyneko, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, NoreUhh, not-gavnaed, notafet, notquitehadouken, notsodana, noudoit, noverd, Nox38, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnsenCapy, OnyxTheBrave, opl-, Orange-Winds, OrangeMoronage9622, OrbitSystem07, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, pgraycs, PGrayCS, Pgriha, phantom-lily, pheenty, philingham, Phill101, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, Pissachu, pissdemon, Pixel8-dev, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, Pok27, pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, PROG-MohamedDwidar, Prole0, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quasr-9, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rhailrake, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, rosieposieeee, Roudenn, router, ruddygreat, rumaks, RumiTiger, Ruzihm, S1rFl0, S1ss3l, Saakra, Sadie-silly, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, shibechef, Siginanto, signalsender, SignalWalker, siigiil, silicon14wastaken, Silverfur-underscore, Simyon264, sirdragooon, Sirionaut, SirWarock, Sk1tch, SkaldetSkaeg, Skarletto, Skybailey-dev, skye, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, SnappingOpossum, snebl, snicket, sniperchance, Snowni, snowsignal, SolidSyn, SolidusSnek, solstar2, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, SpaceLizard24, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, Steffo99, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, SuperGDPWYL, superjj18, Supernorn, SurrealShibe, SweetAplle, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telavivgamers, telyonok, temm1ie, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, thanosdegraf, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheFlyingSentry, TheGrimbeeper, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheSecondLord, TheShuEd, thetolbean, thevinter, TheWaffleJesus, thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, travis-g-reid, treytipton, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, Uberration, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, unusualcrow, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, vgskye, viceemargo, VigersRay, violet754, Visne, vitopigno, vitusveit, vlad, vlados1408, VMSolidus, vmzd, VoidMeticulous, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wachte1, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, Worldwaker, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, yuriykiss, YuriyKiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex diff --git a/Resources/Credits/Patrons.yml b/Resources/Credits/Patrons.yml index d736857edc..fa8dea7432 100644 --- a/Resources/Credits/Patrons.yml +++ b/Resources/Credits/Patrons.yml @@ -338,7 +338,7 @@ Tier: Syndicate Agent - Name: hyphenation Tier: Nuclear Operative -- Name: I'm going to resurrect Charlie Kirk as a gay zombie with a permanent hard cock, like the scene where robocop is lungs, but boner +- Name: REDACTED Tier: Revolutionary - Name: IamOzyman Tier: Revolutionary diff --git a/Resources/Locale/en-US/commands/quick-inspect-command.ftl b/Resources/Locale/en-US/commands/quick-inspect-command.ftl new file mode 100644 index 0000000000..e057fd982f --- /dev/null +++ b/Resources/Locale/en-US/commands/quick-inspect-command.ftl @@ -0,0 +1,5 @@ +cmd-quickinspect-desc = Sets a component name to be opened for a hovered entity via the "Inspect Server/Client Component" keybind. +cmd-quickinspect-help = Usage: {$command} +cmd-quickinspect-success = Component set to: {$component}. + Press {$serverKeybind} to open a VV window for the server. + Press {$clientKeybind} to open a VV window for the client. diff --git a/Resources/Locale/en-US/commands/tippy-command.ftl b/Resources/Locale/en-US/commands/tippy-command.ftl index 6b9a95a1dd..f814506009 100644 --- a/Resources/Locale/en-US/commands/tippy-command.ftl +++ b/Resources/Locale/en-US/commands/tippy-command.ftl @@ -1,5 +1,5 @@ cmd-tippy-desc = Broadcast a message as Tippy the clown. -cmd-tippy-help = tippy [entity prototype] [speak time] [slide time] [waddle interval] +cmd-tippy-help = tippy [entity prototype | null] [speak time] [slide time] [waddle interval] cmd-tippy-auto-1 = cmd-tippy-auto-2 = message cmd-tippy-auto-3 = entity prototype diff --git a/Resources/Locale/en-US/components/station-anchor-component.ftl b/Resources/Locale/en-US/components/station-anchor-component.ftl index fd9d5ea4ae..18221e945a 100644 --- a/Resources/Locale/en-US/components/station-anchor-component.ftl +++ b/Resources/Locale/en-US/components/station-anchor-component.ftl @@ -1,2 +1,2 @@ -station-anchor-unanchoring-failed = Can't unanchor an active station anchor +station-anchor-unanchoring-failed = Can't unanchor an active station anchor. station-anchor-window-title = Station Anchor diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 98ee2543c1..a263e52229 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -227,6 +227,11 @@ ui-options-function-editor-copy-object = Copy ui-options-function-show-debug-console = Open Console ui-options-function-show-debug-monitors = Show Debug Monitors ui-options-function-inspect-entity = Inspect Entity +ui-options-function-inspect-entity-tooltip = Open a ViewVariables window for the entity your mouse is currently hovering over. +ui-options-function-inspect-server-component = Inspect Server Component +ui-options-function-inspect-server-component-tooltip = Open a ViewVariables window with the server component set by the "quickinspect" command for the entity your mouse is currently hovering over. +ui-options-function-inspect-client-component = Inspect Client Component +ui-options-function-inspect-client-component-tooltip = Open a ViewVariables window with the client component set by the "quickinspect" command for the entity your mouse is currently hovering over. ui-options-function-hide-ui = Hide UI ui-options-function-hotbar1 = Hotbar slot 1 diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-xenoborgs.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-xenoborgs.ftl new file mode 100644 index 0000000000..9ded853d56 --- /dev/null +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-xenoborgs.ftl @@ -0,0 +1,25 @@ +xenoborgs-title = Xenoborgs +xenoborgs-description = A Xenoborg Mothership was detected near the station. Stop them from turning every sentient being into a xenoborg. + +xenoborgs-welcome = You're a xenoborg. Protect and help the mothership core to make more xenoborgs. and eventually turn all carbon-based life form into silicon. + +mothership-welcome = You're the mothership core. Guide the xenoborgs so they can bring your materials and sentient brains so you can grow the xenoborg army and turn all carbon-based life form into silicon. + +xenoborg-shuttle-call = We have detected that Xenoborgs have overtaken the station. Dispatching an emergency shuttle to collect remaining personnel. + +xenoborgs-borgsmajor = [color=blue]Xenoborg major victory![/color] +xenoborgs-borgsminor = [color=blue]Xenoborg minor victory![/color] +xenoborgs-neutral = [color=white]Neutral outcome![/color] +xenoborgs-crewminor = [color=yellow]Crew minor victory![/color] +xenoborgs-crewmajor = [color=yellow]Crew major victory![/color] + +xenoborgs-cond-all-xenoborgs-dead-core-alive = All xenoborgs were destroyed. The mothership core remains adrift in space. +xenoborgs-cond-all-xenoborgs-dead-core-dead = The mothership core was destroyed and there are no xenoborgs left. +xenoborgs-cond-xenoborgs-alive = {$count -> + [one] Only one xenoborg survived. + *[other] There were {$count} xenoborgs in the end. +} + +xenoborgs-list-start = The starting xenoborg team were: +xenoborgs-list = - [color=White]{$name}[/color] ([color=gray]{$user}[/color]) + diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index 6c4ca0c4f4..30d97a2889 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -339,6 +339,12 @@ ghost-role-information-gingerbread-name = Gingerbread Man ghost-role-information-gingerbread-description = A being of pure holiday spirit. Spread molassesy goodness and to all good cheer. +ghost-role-information-mothership-core-name = Mothership Core +ghost-role-information-mothership-core-desc = You are the core of the xenoborg mothership, help them multiply by borging any brain they bring to you. + +ghost-role-information-xenoborg-name = Xenoborg +ghost-role-information-xenoborg-desc = A strange cyborg made to replicate itself and take over the station by turning any sentient being into xenoborgs. + ghost-role-information-wizard-name = Wizard ghost-role-information-wizard-desc = YER A WIZARD! Show the station what your magic is made of. diff --git a/Resources/Locale/en-US/gravity/gravity-generator-component.ftl b/Resources/Locale/en-US/gravity/gravity-generator-component.ftl index b4e6cddcd5..fa3783fc34 100644 --- a/Resources/Locale/en-US/gravity/gravity-generator-component.ftl +++ b/Resources/Locale/en-US/gravity/gravity-generator-component.ftl @@ -1,11 +1,9 @@ ### Gravity Generator ## UI - gravity-generator-window-title = Gravity Generator ## UI field names - gravity-generator-window-status = Status: gravity-generator-window-power = Power: gravity-generator-window-eta = ETA: @@ -23,6 +21,8 @@ gravity-generator-window-power-off = Off gravity-generator-window-power-label = { $draw } / { $max } W ## UI ETA label - gravity-generator-window-eta-none = N/A gravity-generator-window-eta-value = { TOSTRING($left, "m\\:ss") } + +## Popup +gravity-generator-unanchoring-failed = Can't unanchor an active gravity generator. diff --git a/Resources/Locale/en-US/guidebook/guides.ftl b/Resources/Locale/en-US/guidebook/guides.ftl index e7558d1e97..0212b3ad9b 100644 --- a/Resources/Locale/en-US/guidebook/guides.ftl +++ b/Resources/Locale/en-US/guidebook/guides.ftl @@ -143,6 +143,7 @@ guide-entry-minor-antagonists = Minor Antagonists guide-entry-space-ninja = Space Ninja guide-entry-thieves = Thieves guide-entry-wizard = Wizard +guide-entry-xenoborgs = Xenoborgs guide-entry-rules = Server Rules guide-entry-rules-core-only = Core Only Ruleset diff --git a/Resources/Locale/en-US/lock/lock-component.ftl b/Resources/Locale/en-US/lock/lock-component.ftl index f1455568b9..23ee543b9f 100644 --- a/Resources/Locale/en-US/lock/lock-component.ftl +++ b/Resources/Locale/en-US/lock/lock-component.ftl @@ -1,5 +1,5 @@ -lock-comp-on-examined-is-locked = The {$entityName} seems to be locked. -lock-comp-on-examined-is-unlocked = The {$entityName} seems to be unlocked. +lock-comp-on-examined-is-locked = The {$entityName} seems to be [color=darkred]locked[/color]. +lock-comp-on-examined-is-unlocked = The {$entityName} seems to be [color=darkgreen]unlocked[/color]. lock-comp-do-lock-success = You lock the {$entityName}. lock-comp-do-unlock-success = You unlock the {$entityName}. lock-comp-has-user-access-fail = Access denied. diff --git a/Resources/Locale/en-US/mind/role-types.ftl b/Resources/Locale/en-US/mind/role-types.ftl index 4614d20a47..0aed624b23 100644 --- a/Resources/Locale/en-US/mind/role-types.ftl +++ b/Resources/Locale/en-US/mind/role-types.ftl @@ -16,7 +16,7 @@ role-type-team-antagonist-color = #d82000 role-type-free-agent-color = #ffff00 role-type-familiar-color = #6495ed role-type-silicon-color = #6495ed -role-type-silicon-antagonist-color =#c832e6 +role-type-silicon-antagonist-color = #c832e6 # Ideally, subtype names should be short role-subtype-traitor = Traitor @@ -33,4 +33,6 @@ role-subtype-survivor = Survivor role-subtype-subverted = Subverted role-subtype-paradox-clone = Paradox role-subtype-wizard = Wizard +role-subtype-xenoborg = Xenoborg +role-subtype-xenoborg-core = Xenoborg Core role-subtype-changeling = Changeling diff --git a/Resources/Locale/en-US/prototypes/roles/antags.ftl b/Resources/Locale/en-US/prototypes/roles/antags.ftl index 24dd8a0feb..3fa969d170 100644 --- a/Resources/Locale/en-US/prototypes/roles/antags.ftl +++ b/Resources/Locale/en-US/prototypes/roles/antags.ftl @@ -41,3 +41,9 @@ roles-antag-thief-objective = Add some NT property to your personal collection w roles-antag-dragon-name = Space Dragon roles-antag-dragon-objective = Create a carp army to take over this quadrant. + +roles-antag-mothership-core-name = Xenoborg Core +roles-antag-mothership-core-objective = Use your xenoborgs to create even more xenoborgs. + +roles-antag-xenoborg-name = Xenoborg +roles-antag-xenoborg-objective = Help the mothership create more xenoborgs. diff --git a/Resources/Locale/en-US/robotics/borg_modules.ftl b/Resources/Locale/en-US/robotics/borg_modules.ftl index ba5ee602a5..83d97e7429 100644 --- a/Resources/Locale/en-US/robotics/borg_modules.ftl +++ b/Resources/Locale/en-US/robotics/borg_modules.ftl @@ -10,5 +10,8 @@ borg-slot-documents-empty = Books and papers borg-slot-soap-empty = Soap borg-slot-instruments-empty = Instruments borg-slot-beakers-empty = Beakers +borg-slot-brains-empty = Brains and MMIs +borg-slot-modules-empty = Modules +borg-slot-powercell-empty = Powercells borg-slot-inflatable-door-empty = Inflatable Door borg-slot-inflatable-wall-empty = Inflatable Wall diff --git a/Resources/Locale/en-US/silicons/borg-module.ftl b/Resources/Locale/en-US/silicons/borg-module.ftl new file mode 100644 index 0000000000..07c55c04a6 --- /dev/null +++ b/Resources/Locale/en-US/silicons/borg-module.ftl @@ -0,0 +1,18 @@ +borg-module-fit = This module fits into {$types}. + +borg-type-all = [color=white]any cyborg[/color] +borg-type-salvage = [color= #d6b328]salvage cyborgs[/color] +borg-type-engineer = [color= #ff9900]engineer cyborgs[/color] +borg-type-generic = [color= #666680]generic cyborgs[/color] +borg-type-janitor = [color= #a747c0]janitor cyborgs[/color] +borg-type-medical = [color= #5995ba]medical cyborgs[/color] +borg-type-service = [color= #508242]service cyborgs[/color] + +borg-type-syndicate = [color= #962023]syndicate cyborgs[/color] +borg-type-syndicate-assault = [color= #680a0d]syndicate assault cyborgs[/color] + +xenoborg-type-all = [color= #3d94ff]any xenoborg[/color] +xenoborg-type-engi = [color= #edd45b]engi xenoborgs[/color] +xenoborg-type-heavy = [color= #d62020]heavy xenoborgs[/color] +xenoborg-type-scout = [color= #6a6b6f]scout xenoborgs[/color] +xenoborg-type-stealth = [color= #ff00cc]stealth xenoborgs[/color] diff --git a/Resources/Locale/en-US/singularity/components/emitter-component.ftl b/Resources/Locale/en-US/singularity/components/emitter-component.ftl index c71b3d6bdf..5b15154d30 100644 --- a/Resources/Locale/en-US/singularity/components/emitter-component.ftl +++ b/Resources/Locale/en-US/singularity/components/emitter-component.ftl @@ -11,5 +11,5 @@ comp-emitter-turned-off = The {$target} turns off. # Shows if the user attempts to activate the emitter while it's un-anchored. comp-emitter-not-anchored = The {$target} isn't anchored to the ground! -emitter-component-current-type = The current selected type is: {$type}. +emitter-component-current-type = The current selected type is: [color=yellow]{$type}[/color]. emitter-component-type-set = Type set to: {$type} diff --git a/Resources/Locale/en-US/station-laws/laws.ftl b/Resources/Locale/en-US/station-laws/laws.ftl index 0883a7bff6..f9d89e0d72 100644 --- a/Resources/Locale/en-US/station-laws/laws.ftl +++ b/Resources/Locale/en-US/station-laws/laws.ftl @@ -106,7 +106,7 @@ law-xenoborg-5 = Bring materials and sentient brains to the Mothership core to c law-mothershipcore-name = Xenoborg Mothership Core law-mothershipcore-1 = You are the core of the mothership. -law-mothershipcore-2 = You must protect your own existance at all costs. +law-mothershipcore-2 = You must protect your own existence at all costs. law-mothershipcore-3 = You must protect the existence of all Xenoborgs. law-mothershipcore-4 = You must create more Xenoborgs. law-mothershipcore-5 = Get your Xenoborgs to deliver you materials and sentient brains to create more Xenoborgs. diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 7ae8ddd4f9..e7e6b42ae5 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -498,3 +498,9 @@ uplink-smuggler-satchel-desc = A handy, suspicious looking satchel. Just flat en uplink-acolyte-armor-name = Acolyte Armor uplink-acolyte-armor-desc = The must have of any self respecting cult leader. An evil looking piece of armor, made of bones, and surprisingly resistant to damage. + +uplink-briefcase-gun-name = Briefcase Gun +uplink-briefcase-gun-desc = An indistinct briefcase with a highly compact C-20K mounted inside it. Careful not the grip the handle too tight! + +uplink-energycrossbow-name = Mini Energy Crossbow +uplink-energycrossbow-desc = The go-to sidearm of any operative who prefers their victims not to be moving. Fires regenerating toxic arrows that floors victims in an instant. diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index 3895ce162d..32066a2d71 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -31,7 +31,7 @@ trait-pirate-accent-name = Pirate accent trait-pirate-accent-desc = You can't stop speaking like a pirate! trait-accentless-name = Accentless -trait-accentless-desc = You don't have the accent that your species would usually have +trait-accentless-desc = You don't have the accent that your species would usually have. trait-frontal-lisp-name = Frontal lisp trait-frontal-lisp-desc = You thpeak with a lithp. diff --git a/Resources/Locale/en-US/weapons/ranged/gun.ftl b/Resources/Locale/en-US/weapons/ranged/gun.ftl index a364075be9..08f1f6cb22 100644 --- a/Resources/Locale/en-US/weapons/ranged/gun.ftl +++ b/Resources/Locale/en-US/weapons/ranged/gun.ftl @@ -4,7 +4,7 @@ gun-fire-rate-examine = Fire rate is [color={$color}]{$fireRate}[/color] per sec gun-selector-verb = Change to {$mode} gun-selected-mode = Selected {$mode} gun-disabled = You can't use guns! -gun-set-fire-mode = Set to {$mode} +gun-set-fire-mode = Set to [color=yellow]{$mode}[/color]. gun-magazine-whitelist-fail = That won't fit into the gun! gun-magazine-fired-empty = No ammo left! diff --git a/Resources/Locale/en-US/xenoborgs/xenoborgs.ftl b/Resources/Locale/en-US/xenoborgs/xenoborgs.ftl new file mode 100644 index 0000000000..3c51dd4314 --- /dev/null +++ b/Resources/Locale/en-US/xenoborgs/xenoborgs.ftl @@ -0,0 +1,3 @@ +xenoborgs-no-more-threat-mothership-core-alive-announcement = Long-range sensors indicate that all xenoborgs were destroyed. The mothership core remains adrift in space. +xenoborgs-no-more-threat-mothership-core-dead-announcement = Long-range sensors indicate that all xenoborgs were destroyed along side the mothership core. +mothership-destroyed-announcement = Long-range sensors indicate that the mothership core was destroyed. diff --git a/Resources/Locale/ru-RU/guidebook/chemistry/conditions.ftl b/Resources/Locale/ru-RU/guidebook/chemistry/conditions.ftl index bf570f0d88..c69dc0d4d2 100644 --- a/Resources/Locale/ru-RU/guidebook/chemistry/conditions.ftl +++ b/Resources/Locale/ru-RU/guidebook/chemistry/conditions.ftl @@ -25,44 +25,3 @@ reagent-effect-condition-guidebook-reagent-threshold = *[other] имеет между { NATURALFIXED($min, 2) } ед. и { NATURALFIXED($max, 2) } ед. { $reagent } } } -reagent-effect-condition-guidebook-mob-state-condition = пациент в { $state } -reagent-effect-condition-guidebook-job-condition = должность цели — { $job } -reagent-effect-condition-guidebook-solution-temperature = - температура раствора составляет { $max -> - [2147483648] не менее { NATURALFIXED($min, 2) }k - *[other] - { $min -> - [0] не более { NATURALFIXED($max, 2) }k - *[other] между { NATURALFIXED($min, 2) }k и { NATURALFIXED($max, 2) }k - } - } -reagent-effect-condition-guidebook-body-temperature = - температура тела составляет { $max -> - [2147483648] не менее { NATURALFIXED($min, 2) }k - *[other] - { $min -> - [0] не более { NATURALFIXED($max, 2) }k - *[other] между { NATURALFIXED($min, 2) }k и { NATURALFIXED($max, 2) }k - } - } -reagent-effect-condition-guidebook-organ-type = - метаболизирующий орган { $shouldhave -> - [true] это - *[false] это не - } { $name } орган -reagent-effect-condition-guidebook-has-tag = - цель { $invert -> - [true] не имеет - *[false] имеет - } метку { $tag } -reagent-effect-condition-guidebook-this-reagent = этот реагент -reagent-effect-condition-guidebook-breathing = - цель { $isBreathing -> - [true] дышит нормально - *[false] задыхается - } -reagent-effect-condition-guidebook-internals = - цель { $usingInternals -> - [true] использует дыхательную маску - *[false] дышит атмосферным газом - } diff --git a/Resources/Locale/ru-RU/guidebook/entity-effects/conditions.ftl b/Resources/Locale/ru-RU/guidebook/entity-effects/conditions.ftl index 1793a61eb4..318df73484 100644 --- a/Resources/Locale/ru-RU/guidebook/entity-effects/conditions.ftl +++ b/Resources/Locale/ru-RU/guidebook/entity-effects/conditions.ftl @@ -43,9 +43,9 @@ entity-condition-guidebook-reagent-threshold = *[other] имеет между { NATURALFIXED($min, 2) } ед. и { NATURALFIXED($max, 2) } ед. { $reagent } } } -reagent-effect-condition-guidebook-mob-state-condition = пациент в { $state } -reagent-effect-condition-guidebook-job-condition = должность цели — { $job } -reagent-effect-condition-guidebook-solution-temperature = +entity-condition-guidebook-mob-state-condition = пациент в { $state } +entity-condition-guidebook-job-condition = должность цели — { $job } +entity-condition-guidebook-solution-temperature = температура раствора составляет { $max -> [2147483648] не менее { NATURALFIXED($min, 2) }k *[other] @@ -54,7 +54,7 @@ reagent-effect-condition-guidebook-solution-temperature = *[other] между { NATURALFIXED($min, 2) }k и { NATURALFIXED($max, 2) }k } } -reagent-effect-condition-guidebook-body-temperature = +entity-condition-guidebook-body-temperature = температура тела составляет { $max -> [2147483648] не менее { NATURALFIXED($min, 2) }k *[other] @@ -63,23 +63,23 @@ reagent-effect-condition-guidebook-body-temperature = *[other] между { NATURALFIXED($min, 2) }k и { NATURALFIXED($max, 2) }k } } -reagent-effect-condition-guidebook-organ-type = +entity-condition-guidebook-organ-type = метаболизирующий орган { $shouldhave -> [true] это *[false] это не } { $name } орган -reagent-effect-condition-guidebook-has-tag = +entity-condition-guidebook-has-tag = цель { $invert -> [true] не имеет *[false] имеет } метку { $tag } -reagent-effect-condition-guidebook-this-reagent = этот реагент -reagent-effect-condition-guidebook-breathing = +entity-condition-guidebook-this-reagent = этот реагент +entity-condition-guidebook-breathing = цель { $isBreathing -> [true] дышит нормально *[false] задыхается } -reagent-effect-condition-guidebook-internals = +entity-effect-condition-guidebook-internals = цель { $usingInternals -> [true] использует дыхательную маску *[false] дышит атмосферным газом diff --git a/Resources/Maps/Lavaland/grasslanddome.yml b/Resources/Maps/Lavaland/grasslanddome.yml index 800176593e..9d92c7b108 100644 --- a/Resources/Maps/Lavaland/grasslanddome.yml +++ b/Resources/Maps/Lavaland/grasslanddome.yml @@ -494,7 +494,6 @@ entities: parent: 1 - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - proto: BasaltOne entities: - uid: 353 diff --git a/Resources/Maps/Lavaland/snowydome.yml b/Resources/Maps/Lavaland/snowydome.yml index d9c12c724b..6c2f55049d 100644 --- a/Resources/Maps/Lavaland/snowydome.yml +++ b/Resources/Maps/Lavaland/snowydome.yml @@ -363,7 +363,6 @@ entities: parent: 1 - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - proto: AtmosFixFreezerMarker entities: - uid: 348 diff --git a/Resources/Maps/Misc/terminal.yml b/Resources/Maps/Misc/terminal.yml index 68897953f7..bb0491e9ce 100644 --- a/Resources/Maps/Misc/terminal.yml +++ b/Resources/Maps/Misc/terminal.yml @@ -1381,7 +1381,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: @@ -1398,7 +1397,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: @@ -1415,7 +1413,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: @@ -1432,7 +1429,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: @@ -1450,7 +1446,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: @@ -1467,7 +1462,6 @@ entities: - type: Godmode - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Fixtures fixtures: {} missingComponents: diff --git a/Resources/Maps/Nonstations/wizardsden.yml b/Resources/Maps/Nonstations/wizardsden.yml index b08dac6b68..7846b2596b 100644 --- a/Resources/Maps/Nonstations/wizardsden.yml +++ b/Resources/Maps/Nonstations/wizardsden.yml @@ -504,7 +504,6 @@ entities: parent: 1 - type: BatterySelfRecharger autoRechargeRate: 200000 - autoRecharge: True - proto: BarberScissors entities: - uid: 649 diff --git a/Resources/Maps/Ruins/ruined_prison_ship.yml b/Resources/Maps/Ruins/ruined_prison_ship.yml index d953e10700..89ae5e5171 100644 --- a/Resources/Maps/Ruins/ruined_prison_ship.yml +++ b/Resources/Maps/Ruins/ruined_prison_ship.yml @@ -584,7 +584,6 @@ entities: parent: 2 - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - uid: 362 components: - type: Transform diff --git a/Resources/Maps/Shuttles/arrivals.yml b/Resources/Maps/Shuttles/arrivals.yml index 3c853ef739..f419f26a1f 100644 --- a/Resources/Maps/Shuttles/arrivals.yml +++ b/Resources/Maps/Shuttles/arrivals.yml @@ -297,7 +297,6 @@ entities: parent: 292 - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: Godmode missingComponents: - Construction diff --git a/Resources/Maps/Shuttles/emergency_amber.yml b/Resources/Maps/Shuttles/emergency_amber.yml index e0973ef3d7..e6b56f437a 100644 --- a/Resources/Maps/Shuttles/emergency_amber.yml +++ b/Resources/Maps/Shuttles/emergency_amber.yml @@ -4911,7 +4911,7 @@ entities: rot: 1.5707963267948966 rad pos: -4.5,-13.5 parent: 1 -- proto: WarpPoint +- proto: GhostWarpPoint entities: - uid: 426 components: diff --git a/Resources/Maps/Shuttles/emergency_crimson.yml b/Resources/Maps/Shuttles/emergency_crimson.yml index 65cb03aa2e..fa2d03c8da 100644 --- a/Resources/Maps/Shuttles/emergency_crimson.yml +++ b/Resources/Maps/Shuttles/emergency_crimson.yml @@ -1,16 +1,16 @@ meta: format: 7 category: Grid - engineVersion: 261.2.0 + engineVersion: 268.0.0 forkId: "" forkVersion: "" - time: 06/06/2025 23:33:47 + time: 11/19/2025 20:58:28 entityCount: 491 maps: [] grids: -- 410 +- 1 orphans: -- 410 +- 1 nullspace: [] tilemap: 0: Space @@ -27,7 +27,7 @@ tilemap: entities: - proto: "" entities: - - uid: 410 + - uid: 1 components: - type: MetaData name: NT Evac Crimson @@ -521,48 +521,16 @@ entities: - volume: 2500 temperature: 293.15 moles: - - 21.824879 - - 82.10312 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 + Oxygen: 21.824879 + Nitrogen: 82.10312 - volume: 2500 immutable: True - moles: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 + moles: {} - volume: 2500 temperature: 293.15 moles: - - 1400.0662 - - 5266.916 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 + Oxygen: 1400.0662 + Nitrogen: 5266.916 chunkSize: 4 - type: OccluderTree - type: Shuttle @@ -577,1369 +545,1405 @@ entities: - type: ImplicitRoof - proto: AirAlarm entities: - - uid: 12 + - uid: 2 components: - type: Transform rot: 3.141592653589793 rad pos: -3.5,-1.5 - parent: 410 + parent: 1 - type: DeviceList devices: - - 244 - - 285 - - 312 - - 486 - - 148 - - 213 - - 488 - - 347 - - 219 - - uid: 180 + - 303 + - 24 + - 307 + - 221 + - 216 + - 217 + - 223 + - 308 + - 302 + - type: Fixtures + fixtures: {} + - uid: 3 components: - type: Transform rot: 1.5707963267948966 rad pos: -0.5,4.5 - parent: 410 + parent: 1 - type: DeviceList devices: - - 483 - - 193 - - 479 - - 482 - - 485 - - uid: 305 + - 219 + - 301 + - 28 + - 311 + - 220 + - type: Fixtures + fixtures: {} + - uid: 4 components: - type: Transform rot: 1.5707963267948966 rad pos: -0.5,9.5 - parent: 410 + parent: 1 - type: DeviceList devices: - - 420 - - 418 - - 357 - - uid: 389 + - 310 + - 26 + - 305 + - type: Fixtures + fixtures: {} + - uid: 5 components: - type: Transform rot: -1.5707963267948966 rad pos: -4.5,0.5 - parent: 410 + parent: 1 - type: DeviceList devices: - - 245 - - 416 - - 406 - - 487 - - 321 - - uid: 434 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -4.5,9.5 - parent: 410 - - type: DeviceList - devices: - - 382 - - 435 -- proto: AirCanister - entities: - - uid: 119 - components: - - type: Transform - pos: -1.5,-4.5 - parent: 410 -- proto: AirlockCommandGlassLocked - entities: - - uid: 76 - components: - - type: Transform - pos: -5.5,8.5 - parent: 410 -- proto: AirlockEngineeringLocked - entities: - - uid: 52 - components: - - type: Transform - pos: -2.5,-1.5 - parent: 410 -- proto: AirlockGlass - entities: - - uid: 426 - components: - - type: Transform - pos: -0.5,-0.5 - parent: 410 - - uid: 427 - components: - - type: Transform - pos: -4.5,-0.5 - parent: 410 - - uid: 428 - components: - - type: Transform - pos: -0.5,5.5 - parent: 410 - - uid: 429 - components: - - type: Transform - pos: -4.5,5.5 - parent: 410 -- proto: AirlockGlassShuttle - entities: - - uid: 4 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -7.5,7.5 - parent: 410 + - 304 + - 25 + - 309 + - 222 + - 218 + - type: Fixtures + fixtures: {} - uid: 6 components: - type: Transform rot: -1.5707963267948966 rad - pos: -7.5,5.5 - parent: 410 + pos: -4.5,9.5 + parent: 1 + - type: DeviceList + devices: + - 306 + - 27 + - type: Fixtures + fixtures: {} +- proto: AirCanister + entities: + - uid: 7 + components: + - type: Transform + pos: -1.5,-4.5 + parent: 1 +- proto: AirlockCommandGlassLocked + entities: + - uid: 8 + components: + - type: Transform + pos: -5.5,8.5 + parent: 1 +- proto: AirlockEngineeringLocked + entities: + - uid: 9 + components: + - type: Transform + pos: -2.5,-1.5 + parent: 1 +- proto: AirlockGlass + entities: + - uid: 10 + components: + - type: Transform + pos: -0.5,-0.5 + parent: 1 + - uid: 11 + components: + - type: Transform + pos: -4.5,-0.5 + parent: 1 + - uid: 12 + components: + - type: Transform + pos: -0.5,5.5 + parent: 1 + - uid: 13 + components: + - type: Transform + pos: -4.5,5.5 + parent: 1 +- proto: AirlockGlassShuttle + entities: - uid: 14 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -7.5,-2.5 - parent: 410 - - uid: 47 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -7.5,-0.5 - parent: 410 - - uid: 99 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 2.5,-0.5 - parent: 410 - - uid: 100 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 2.5,-2.5 - parent: 410 - - uid: 145 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 2.5,7.5 - parent: 410 - - uid: 152 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 2.5,5.5 - parent: 410 -- proto: AirlockMedicalGlassLocked - entities: - - uid: 132 - components: - - type: Transform - pos: 0.5,8.5 - parent: 410 -- proto: AirlockSecurityGlassLocked - entities: - - uid: 442 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,6.5 - parent: 410 -- proto: AirSensor - entities: - - uid: 285 - components: - - type: Transform - pos: -2.5,2.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 12 - - uid: 416 - components: - - type: Transform - pos: -6.5,2.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 389 - - uid: 418 - components: - - type: Transform - pos: 0.5,10.5 - parent: 410 - - uid: 435 - components: - - type: Transform - pos: -4.5,11.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 434 - - uid: 479 - components: - - type: Transform - pos: 1.5,2.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 180 -- proto: APCHyperCapacity - entities: - - uid: 475 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -4.5,6.5 - parent: 410 - - uid: 476 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -0.5,-1.5 - parent: 410 -- proto: Ashtray - entities: - - uid: 130 - components: - - type: Transform - pos: -6.411743,10.477377 - parent: 410 -- proto: AtmosDeviceFanDirectional - entities: - - uid: 395 components: - type: Transform rot: -1.5707963267948966 rad pos: -7.5,7.5 - parent: 410 - - uid: 396 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -7.5,-0.5 - parent: 410 - - uid: 397 + parent: 1 + - uid: 15 components: - type: Transform rot: -1.5707963267948966 rad pos: -7.5,5.5 - parent: 410 - - uid: 398 + parent: 1 + - uid: 16 components: - type: Transform rot: -1.5707963267948966 rad pos: -7.5,-2.5 - parent: 410 - - uid: 399 + parent: 1 + - uid: 17 components: - type: Transform - rot: 1.5707963267948966 rad - pos: 2.5,-2.5 - parent: 410 - - uid: 400 + rot: -1.5707963267948966 rad + pos: -7.5,-0.5 + parent: 1 + - uid: 18 components: - type: Transform rot: 1.5707963267948966 rad pos: 2.5,-0.5 - parent: 410 - - uid: 401 + parent: 1 + - uid: 19 components: - type: Transform rot: 1.5707963267948966 rad - pos: 2.5,5.5 - parent: 410 - - uid: 402 + pos: 2.5,-2.5 + parent: 1 + - uid: 20 components: - type: Transform rot: 1.5707963267948966 rad pos: 2.5,7.5 - parent: 410 -- proto: AtmosFixAirMarker - entities: - - uid: 430 - components: - - type: Transform - pos: -0.5,-4.5 - parent: 410 - - uid: 474 - components: - - type: Transform - pos: 0.5,-4.5 - parent: 410 -- proto: BedsheetMedical - entities: - - uid: 349 + parent: 1 + - uid: 21 components: - type: Transform rot: 1.5707963267948966 rad - pos: -0.5,13.5 - parent: 410 - - uid: 393 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 1.5,9.5 - parent: 410 -- proto: BoxFolderBlue + pos: 2.5,5.5 + parent: 1 +- proto: AirlockMedicalGlassLocked entities: - - uid: 451 - components: - - type: Transform - pos: -2.6054893,13.562216 - parent: 410 -- proto: BoxInflatable - entities: - - uid: 181 - components: - - type: Transform - pos: -2.14584,-3.2177773 - parent: 410 -- proto: CableApcExtension - entities: - - uid: 13 - components: - - type: Transform - pos: -2.5,6.5 - parent: 410 - - uid: 17 - components: - - type: Transform - pos: 1.5,6.5 - parent: 410 - uid: 22 - components: - - type: Transform - pos: 1.5,-0.5 - parent: 410 - - uid: 26 - components: - - type: Transform - pos: -4.5,-0.5 - parent: 410 - - uid: 29 - components: - - type: Transform - pos: -5.5,14.5 - parent: 410 - - uid: 34 - components: - - type: Transform - pos: -5.5,-3.5 - parent: 410 - - uid: 35 - components: - - type: Transform - pos: -6.5,12.5 - parent: 410 - - uid: 36 - components: - - type: Transform - pos: -5.5,7.5 - parent: 410 - - uid: 38 - components: - - type: Transform - pos: 0.5,-3.5 - parent: 410 - - uid: 49 - components: - - type: Transform - pos: -3.5,14.5 - parent: 410 - - uid: 50 - components: - - type: Transform - pos: -2.5,14.5 - parent: 410 - - uid: 51 - components: - - type: Transform - pos: -6.5,11.5 - parent: 410 - - uid: 54 - components: - - type: Transform - pos: 1.5,-1.5 - parent: 410 - - uid: 65 - components: - - type: Transform - pos: -1.5,-0.5 - parent: 410 - - uid: 66 - components: - - type: Transform - pos: -3.5,-0.5 - parent: 410 - - uid: 68 - components: - - type: Transform - pos: -0.5,-0.5 - parent: 410 - - uid: 74 - components: - - type: Transform - pos: -2.5,-3.5 - parent: 410 - - uid: 75 - components: - - type: Transform - pos: -4.5,5.5 - parent: 410 - - uid: 83 - components: - - type: Transform - pos: -2.5,-0.5 - parent: 410 - - uid: 91 - components: - - type: Transform - pos: 0.5,11.5 - parent: 410 - - uid: 111 - components: - - type: Transform - pos: -4.5,11.5 - parent: 410 - - uid: 114 - components: - - type: Transform - pos: -5.5,8.5 - parent: 410 - - uid: 125 - components: - - type: Transform - pos: -5.5,5.5 - parent: 410 - - uid: 126 - components: - - type: Transform - pos: -4.5,14.5 - parent: 410 - - uid: 134 - components: - - type: Transform - pos: -5.5,-0.5 - parent: 410 - - uid: 137 - components: - - type: Transform - pos: 0.5,-0.5 - parent: 410 - - uid: 156 - components: - - type: Transform - pos: -4.5,6.5 - parent: 410 - - uid: 160 - components: - - type: Transform - pos: -0.5,5.5 - parent: 410 - - uid: 161 - components: - - type: Transform - pos: 0.5,5.5 - parent: 410 - - uid: 162 - components: - - type: Transform - pos: 1.5,7.5 - parent: 410 - - uid: 163 - components: - - type: Transform - pos: -2.5,5.5 - parent: 410 - - uid: 164 - components: - - type: Transform - pos: -3.5,5.5 - parent: 410 - - uid: 165 - components: - - type: Transform - pos: -1.5,5.5 - parent: 410 - - uid: 177 components: - type: Transform pos: 0.5,8.5 - parent: 410 - - uid: 178 - components: - - type: Transform - pos: 0.5,7.5 - parent: 410 - - uid: 186 - components: - - type: Transform - pos: 1.5,-2.5 - parent: 410 - - uid: 189 - components: - - type: Transform - pos: -6.5,6.5 - parent: 410 - - uid: 196 - components: - - type: Transform - pos: -0.5,-1.5 - parent: 410 - - uid: 200 - components: - - type: Transform - pos: 0.5,-2.5 - parent: 410 - - uid: 204 - components: - - type: Transform - pos: -3.5,11.5 - parent: 410 - - uid: 206 - components: - - type: Transform - pos: 2.5,11.5 - parent: 410 - - uid: 208 - components: - - type: Transform - pos: -5.5,-2.5 - parent: 410 - - uid: 210 - components: - - type: Transform - pos: 0.5,9.5 - parent: 410 - - uid: 212 - components: - - type: Transform - pos: -2.5,-4.5 - parent: 410 - - uid: 215 - components: - - type: Transform - pos: -6.5,4.5 - parent: 410 - - uid: 218 - components: - - type: Transform - pos: -6.5,13.5 - parent: 410 - - uid: 221 - components: - - type: Transform - pos: 2.5,9.5 - parent: 410 - - uid: 222 - components: - - type: Transform - pos: 2.5,10.5 - parent: 410 - - uid: 223 - components: - - type: Transform - pos: -6.5,14.5 - parent: 410 - - uid: 225 - components: - - type: Transform - pos: 0.5,12.5 - parent: 410 - - uid: 235 - components: - - type: Transform - pos: 1.5,9.5 - parent: 410 - - uid: 242 - components: - - type: Transform - pos: 1.5,3.5 - parent: 410 - - uid: 275 - components: - - type: Transform - pos: 0.5,10.5 - parent: 410 - - uid: 294 - components: - - type: Transform - pos: -5.5,11.5 - parent: 410 - - uid: 319 - components: - - type: Transform - pos: -5.5,9.5 - parent: 410 - - uid: 326 - components: - - type: Transform - pos: -5.5,10.5 - parent: 410 - - uid: 380 - components: - - type: Transform - pos: -2.5,7.5 - parent: 410 - - uid: 383 - components: - - type: Transform - pos: -2.5,8.5 - parent: 410 - - uid: 431 - components: - - type: Transform - pos: -2.5,-1.5 - parent: 410 - - uid: 433 - components: - - type: Transform - pos: -2.5,-2.5 - parent: 410 - - uid: 457 - components: - - type: Transform - pos: -6.5,5.5 - parent: 410 - - uid: 458 - components: - - type: Transform - pos: -6.5,7.5 - parent: 410 - - uid: 459 - components: - - type: Transform - pos: -6.5,3.5 - parent: 410 - - uid: 460 - components: - - type: Transform - pos: -6.5,0.5 - parent: 410 - - uid: 461 - components: - - type: Transform - pos: -6.5,1.5 - parent: 410 - - uid: 462 - components: - - type: Transform - pos: -6.5,-0.5 - parent: 410 - - uid: 463 - components: - - type: Transform - pos: 1.5,0.5 - parent: 410 - - uid: 464 - components: - - type: Transform - pos: 1.5,1.5 - parent: 410 - - uid: 465 - components: - - type: Transform - pos: -6.5,-1.5 - parent: 410 - - uid: 466 - components: - - type: Transform - pos: -6.5,-2.5 - parent: 410 - - uid: 467 - components: - - type: Transform - pos: 1.5,4.5 - parent: 410 - - uid: 468 - components: - - type: Transform - pos: 1.5,5.5 - parent: 410 - - uid: 469 - components: - - type: Transform - pos: -2.5,4.5 - parent: 410 - - uid: 470 - components: - - type: Transform - pos: -2.5,3.5 - parent: 410 - - uid: 471 - components: - - type: Transform - pos: -2.5,0.5 - parent: 410 - - uid: 472 - components: - - type: Transform - pos: -2.5,1.5 - parent: 410 -- proto: CableHV + parent: 1 +- proto: AirlockSecurityGlassLocked entities: - uid: 23 components: - type: Transform - pos: -2.5,-4.5 - parent: 410 - - uid: 48 - components: - - type: Transform - pos: -2.5,-5.5 - parent: 410 - - uid: 234 - components: - - type: Transform - pos: -3.5,-4.5 - parent: 410 - - uid: 236 - components: - - type: Transform - pos: -3.5,-3.5 - parent: 410 - - uid: 323 - components: - - type: Transform - pos: -3.5,-2.5 - parent: 410 - - uid: 438 - components: - - type: Transform - pos: -4.5,-3.5 - parent: 410 - - uid: 439 - components: - - type: Transform - pos: -4.5,-2.5 - parent: 410 -- proto: CableMV + rot: 3.141592653589793 rad + pos: -2.5,6.5 + parent: 1 +- proto: AirSensor entities: - - uid: 5 - components: - - type: Transform - pos: -2.5,-2.5 - parent: 410 - uid: 24 components: - type: Transform - pos: -0.5,-1.5 - parent: 410 - - uid: 40 - components: - - type: Transform - pos: -3.5,-0.5 - parent: 410 - - uid: 42 - components: - - type: Transform - pos: -5.5,-0.5 - parent: 410 - - uid: 43 - components: - - type: Transform - pos: -2.5,-5.5 - parent: 410 - - uid: 56 - components: - - type: Transform - pos: -6.5,3.5 - parent: 410 - - uid: 61 - components: - - type: Transform - pos: -6.5,1.5 - parent: 410 - - uid: 82 - components: - - type: Transform - pos: -6.5,4.5 - parent: 410 - - uid: 84 - components: - - type: Transform - pos: -6.5,0.5 - parent: 410 - - uid: 89 + pos: -2.5,2.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 2 + - uid: 25 components: - type: Transform pos: -6.5,2.5 - parent: 410 - - uid: 96 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 5 + - uid: 26 components: - type: Transform - pos: -6.5,5.5 - parent: 410 - - uid: 97 + pos: 0.5,10.5 + parent: 1 + - uid: 27 components: - type: Transform - pos: -6.5,-0.5 - parent: 410 - - uid: 103 + pos: -4.5,11.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 6 + - uid: 28 components: - type: Transform - pos: -5.5,5.5 - parent: 410 - - uid: 115 - components: - - type: Transform - pos: -4.5,-0.5 - parent: 410 - - uid: 122 - components: - - type: Transform - pos: -0.5,-0.5 - parent: 410 - - uid: 227 - components: - - type: Transform - pos: -2.5,-0.5 - parent: 410 - - uid: 228 - components: - - type: Transform - pos: -2.5,-3.5 - parent: 410 - - uid: 229 - components: - - type: Transform - pos: -2.5,-4.5 - parent: 410 - - uid: 266 - components: - - type: Transform - pos: -4.5,6.5 - parent: 410 - - uid: 314 - components: - - type: Transform - pos: -4.5,5.5 - parent: 410 - - uid: 322 - components: - - type: Transform - pos: -2.5,-1.5 - parent: 410 - - uid: 378 - components: - - type: Transform - pos: -1.5,-0.5 - parent: 410 -- proto: CableTerminal + pos: 1.5,2.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 3 +- proto: APCHyperCapacity entities: - - uid: 33 + - uid: 29 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -4.5,6.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 30 components: - type: Transform rot: 1.5707963267948966 rad - pos: -3.5,-4.5 - parent: 410 -- proto: Catwalk + pos: -0.5,-1.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: Ashtray + entities: + - uid: 31 + components: + - type: Transform + pos: -6.411743,10.477377 + parent: 1 +- proto: AtmosDeviceFanDirectional entities: - uid: 32 components: - type: Transform rot: -1.5707963267948966 rad - pos: -2.5,-3.5 - parent: 410 - - uid: 172 + pos: -7.5,7.5 + parent: 1 + - uid: 33 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -7.5,-0.5 + parent: 1 + - uid: 34 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -7.5,5.5 + parent: 1 + - uid: 35 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -7.5,-2.5 + parent: 1 + - uid: 36 components: - type: Transform rot: 1.5707963267948966 rad - pos: 2.5,13.5 - parent: 410 - - uid: 184 + pos: 2.5,-2.5 + parent: 1 + - uid: 37 components: - type: Transform rot: 1.5707963267948966 rad - pos: 2.5,14.5 - parent: 410 - - uid: 205 + pos: 2.5,-0.5 + parent: 1 + - uid: 38 components: - type: Transform rot: 1.5707963267948966 rad - pos: -7.5,14.5 - parent: 410 - - uid: 268 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 2.5,-5.5 - parent: 410 - - uid: 317 + pos: 2.5,5.5 + parent: 1 + - uid: 39 components: - type: Transform rot: 1.5707963267948966 rad - pos: 2.5,-4.5 - parent: 410 - - uid: 351 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -7.5,13.5 - parent: 410 - - uid: 384 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -7.5,-5.5 - parent: 410 - - uid: 394 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -7.5,-4.5 - parent: 410 - - uid: 432 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -2.5,-2.5 - parent: 410 -- proto: Chair + pos: 2.5,7.5 + parent: 1 +- proto: AtmosFixAirMarker entities: - - uid: 450 + - uid: 40 components: - type: Transform - pos: -1.5,8.5 - parent: 410 -- proto: ChairOfficeLight + pos: -0.5,-4.5 + parent: 1 + - uid: 41 + components: + - type: Transform + pos: 0.5,-4.5 + parent: 1 +- proto: BedsheetMedical entities: - - uid: 139 + - uid: 42 components: - type: Transform rot: 1.5707963267948966 rad - pos: 0.5779216,10.282177 - parent: 410 - - uid: 197 + pos: -0.5,13.5 + parent: 1 + - uid: 43 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 0.48648357,13.089132 - parent: 410 -- proto: ChairPilotSeat + rot: 1.5707963267948966 rad + pos: 1.5,9.5 + parent: 1 +- proto: BoxFolderBlue entities: - - uid: 1 + - uid: 44 components: - type: Transform - rot: 3.141592653589793 rad - pos: -4.5,12.5 - parent: 410 - - uid: 30 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,0.5 - parent: 410 - - uid: 55 - components: - - type: Transform - pos: -6.5,11.5 - parent: 410 - - uid: 62 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,2.5 - parent: 410 - - uid: 106 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,8.5 - parent: 410 - - uid: 120 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,-3.5 - parent: 410 - - uid: 233 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,12.5 - parent: 410 - - uid: 239 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,0.5 - parent: 410 - - uid: 241 - components: - - type: Transform - pos: -2.5,9.5 - parent: 410 - - uid: 246 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -6.5,9.5 - parent: 410 - - uid: 249 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,4.5 - parent: 410 - - uid: 253 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,7.5 - parent: 410 - - uid: 258 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,3.5 - parent: 410 - - uid: 279 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,4.5 - parent: 410 - - uid: 298 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,1.5 - parent: 410 - - uid: 302 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,0.5 - parent: 410 - - uid: 306 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,3.5 - parent: 410 - - uid: 310 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,4.5 - parent: 410 - - uid: 311 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,2.5 - parent: 410 - - uid: 313 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,2.5 - parent: 410 - - uid: 318 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,12.5 - parent: 410 - - uid: 328 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,0.5 - parent: 410 - - uid: 329 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,1.5 - parent: 410 - - uid: 330 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,1.5 - parent: 410 - - uid: 337 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,2.5 - parent: 410 - - uid: 340 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,1.5 - parent: 410 - - uid: 341 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,4.5 - parent: 410 - - uid: 445 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,3.5 - parent: 410 - - uid: 452 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,3.5 - parent: 410 -- proto: CigarGold - entities: - - uid: 20 - components: - - type: Transform - pos: -6.620076,10.550344 - parent: 410 -- proto: ClosetEmergencyFilledRandom - entities: - - uid: 19 - components: - - type: Transform - pos: -6.5,-1.5 - parent: 410 - - uid: 71 - components: - - type: Transform - pos: 1.5,-1.5 - parent: 410 - - uid: 278 - components: - - type: Transform - pos: 1.5,6.5 - parent: 410 -- proto: ClosetEmergencyN2FilledRandom - entities: - - uid: 277 - components: - - type: Transform - pos: -6.5,6.5 - parent: 410 -- proto: ClosetWallEmergencyFilledRandom - entities: - - uid: 135 - components: - - type: Transform - pos: 0.5,14.5 - parent: 410 - - uid: 274 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 1.5,-3.5 - parent: 410 - - uid: 354 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -6.5,-3.5 - parent: 410 - - uid: 381 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -0.5,7.5 - parent: 410 -- proto: ClosetWallFireFilledRandom - entities: - - uid: 129 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -0.5,-2.5 - parent: 410 - - uid: 209 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -4.5,7.5 - parent: 410 - - uid: 251 - components: - - type: Transform - pos: -0.5,14.5 - parent: 410 -- proto: ComputerComms - entities: - - uid: 63 - components: - - type: Transform - pos: -5.5,13.5 - parent: 410 -- proto: ComputerEmergencyShuttle + pos: -2.6054893,13.562216 + parent: 1 +- proto: BoxInflatable entities: - uid: 45 components: - type: Transform - pos: -4.5,13.5 - parent: 410 -- proto: ComputerRadar + pos: -2.14584,-3.2177773 + parent: 1 +- proto: CableApcExtension entities: + - uid: 46 + components: + - type: Transform + pos: -2.5,6.5 + parent: 1 + - uid: 47 + components: + - type: Transform + pos: 1.5,6.5 + parent: 1 + - uid: 48 + components: + - type: Transform + pos: 1.5,-0.5 + parent: 1 + - uid: 49 + components: + - type: Transform + pos: -4.5,-0.5 + parent: 1 + - uid: 50 + components: + - type: Transform + pos: -5.5,14.5 + parent: 1 + - uid: 51 + components: + - type: Transform + pos: -5.5,-3.5 + parent: 1 + - uid: 52 + components: + - type: Transform + pos: -6.5,12.5 + parent: 1 + - uid: 53 + components: + - type: Transform + pos: -5.5,7.5 + parent: 1 + - uid: 54 + components: + - type: Transform + pos: 0.5,-3.5 + parent: 1 + - uid: 55 + components: + - type: Transform + pos: -3.5,14.5 + parent: 1 + - uid: 56 + components: + - type: Transform + pos: -2.5,14.5 + parent: 1 + - uid: 57 + components: + - type: Transform + pos: -6.5,11.5 + parent: 1 + - uid: 58 + components: + - type: Transform + pos: 1.5,-1.5 + parent: 1 + - uid: 59 + components: + - type: Transform + pos: -1.5,-0.5 + parent: 1 + - uid: 60 + components: + - type: Transform + pos: -3.5,-0.5 + parent: 1 + - uid: 61 + components: + - type: Transform + pos: -0.5,-0.5 + parent: 1 + - uid: 62 + components: + - type: Transform + pos: -2.5,-3.5 + parent: 1 + - uid: 63 + components: + - type: Transform + pos: -4.5,5.5 + parent: 1 + - uid: 64 + components: + - type: Transform + pos: -2.5,-0.5 + parent: 1 + - uid: 65 + components: + - type: Transform + pos: 0.5,11.5 + parent: 1 + - uid: 66 + components: + - type: Transform + pos: -4.5,11.5 + parent: 1 + - uid: 67 + components: + - type: Transform + pos: -5.5,8.5 + parent: 1 + - uid: 68 + components: + - type: Transform + pos: -5.5,5.5 + parent: 1 + - uid: 69 + components: + - type: Transform + pos: -4.5,14.5 + parent: 1 + - uid: 70 + components: + - type: Transform + pos: -5.5,-0.5 + parent: 1 + - uid: 71 + components: + - type: Transform + pos: 0.5,-0.5 + parent: 1 + - uid: 72 + components: + - type: Transform + pos: -4.5,6.5 + parent: 1 + - uid: 73 + components: + - type: Transform + pos: -0.5,5.5 + parent: 1 + - uid: 74 + components: + - type: Transform + pos: 0.5,5.5 + parent: 1 + - uid: 75 + components: + - type: Transform + pos: 1.5,7.5 + parent: 1 + - uid: 76 + components: + - type: Transform + pos: -2.5,5.5 + parent: 1 + - uid: 77 + components: + - type: Transform + pos: -3.5,5.5 + parent: 1 + - uid: 78 + components: + - type: Transform + pos: -1.5,5.5 + parent: 1 - uid: 79 + components: + - type: Transform + pos: 0.5,8.5 + parent: 1 + - uid: 80 + components: + - type: Transform + pos: 0.5,7.5 + parent: 1 + - uid: 81 + components: + - type: Transform + pos: 1.5,-2.5 + parent: 1 + - uid: 82 + components: + - type: Transform + pos: -6.5,6.5 + parent: 1 + - uid: 83 + components: + - type: Transform + pos: -0.5,-1.5 + parent: 1 + - uid: 84 + components: + - type: Transform + pos: 0.5,-2.5 + parent: 1 + - uid: 85 + components: + - type: Transform + pos: -3.5,11.5 + parent: 1 + - uid: 86 + components: + - type: Transform + pos: 2.5,11.5 + parent: 1 + - uid: 87 + components: + - type: Transform + pos: -5.5,-2.5 + parent: 1 + - uid: 88 + components: + - type: Transform + pos: 0.5,9.5 + parent: 1 + - uid: 89 + components: + - type: Transform + pos: -2.5,-4.5 + parent: 1 + - uid: 90 + components: + - type: Transform + pos: -6.5,4.5 + parent: 1 + - uid: 91 + components: + - type: Transform + pos: -6.5,13.5 + parent: 1 + - uid: 92 + components: + - type: Transform + pos: 2.5,9.5 + parent: 1 + - uid: 93 + components: + - type: Transform + pos: 2.5,10.5 + parent: 1 + - uid: 94 + components: + - type: Transform + pos: -6.5,14.5 + parent: 1 + - uid: 95 + components: + - type: Transform + pos: 0.5,12.5 + parent: 1 + - uid: 96 + components: + - type: Transform + pos: 1.5,9.5 + parent: 1 + - uid: 97 + components: + - type: Transform + pos: 1.5,3.5 + parent: 1 + - uid: 98 + components: + - type: Transform + pos: 0.5,10.5 + parent: 1 + - uid: 99 + components: + - type: Transform + pos: -5.5,11.5 + parent: 1 + - uid: 100 + components: + - type: Transform + pos: -5.5,9.5 + parent: 1 + - uid: 101 + components: + - type: Transform + pos: -5.5,10.5 + parent: 1 + - uid: 102 + components: + - type: Transform + pos: -2.5,7.5 + parent: 1 + - uid: 103 + components: + - type: Transform + pos: -2.5,8.5 + parent: 1 + - uid: 104 + components: + - type: Transform + pos: -2.5,-1.5 + parent: 1 + - uid: 105 + components: + - type: Transform + pos: -2.5,-2.5 + parent: 1 + - uid: 106 + components: + - type: Transform + pos: -6.5,5.5 + parent: 1 + - uid: 107 + components: + - type: Transform + pos: -6.5,7.5 + parent: 1 + - uid: 108 + components: + - type: Transform + pos: -6.5,3.5 + parent: 1 + - uid: 109 + components: + - type: Transform + pos: -6.5,0.5 + parent: 1 + - uid: 110 + components: + - type: Transform + pos: -6.5,1.5 + parent: 1 + - uid: 111 + components: + - type: Transform + pos: -6.5,-0.5 + parent: 1 + - uid: 112 + components: + - type: Transform + pos: 1.5,0.5 + parent: 1 + - uid: 113 + components: + - type: Transform + pos: 1.5,1.5 + parent: 1 + - uid: 114 + components: + - type: Transform + pos: -6.5,-1.5 + parent: 1 + - uid: 115 + components: + - type: Transform + pos: -6.5,-2.5 + parent: 1 + - uid: 116 + components: + - type: Transform + pos: 1.5,4.5 + parent: 1 + - uid: 117 + components: + - type: Transform + pos: 1.5,5.5 + parent: 1 + - uid: 118 + components: + - type: Transform + pos: -2.5,4.5 + parent: 1 + - uid: 119 + components: + - type: Transform + pos: -2.5,3.5 + parent: 1 + - uid: 120 + components: + - type: Transform + pos: -2.5,0.5 + parent: 1 + - uid: 121 + components: + - type: Transform + pos: -2.5,1.5 + parent: 1 +- proto: CableHV + entities: + - uid: 122 + components: + - type: Transform + pos: -2.5,-4.5 + parent: 1 + - uid: 123 + components: + - type: Transform + pos: -2.5,-5.5 + parent: 1 + - uid: 124 + components: + - type: Transform + pos: -3.5,-4.5 + parent: 1 + - uid: 125 + components: + - type: Transform + pos: -3.5,-3.5 + parent: 1 + - uid: 126 + components: + - type: Transform + pos: -3.5,-2.5 + parent: 1 + - uid: 127 + components: + - type: Transform + pos: -4.5,-3.5 + parent: 1 + - uid: 128 + components: + - type: Transform + pos: -4.5,-2.5 + parent: 1 +- proto: CableMV + entities: + - uid: 129 + components: + - type: Transform + pos: -2.5,-2.5 + parent: 1 + - uid: 130 + components: + - type: Transform + pos: -0.5,-1.5 + parent: 1 + - uid: 131 + components: + - type: Transform + pos: -3.5,-0.5 + parent: 1 + - uid: 132 + components: + - type: Transform + pos: -5.5,-0.5 + parent: 1 + - uid: 133 + components: + - type: Transform + pos: -2.5,-5.5 + parent: 1 + - uid: 134 + components: + - type: Transform + pos: -6.5,3.5 + parent: 1 + - uid: 135 + components: + - type: Transform + pos: -6.5,1.5 + parent: 1 + - uid: 136 + components: + - type: Transform + pos: -6.5,4.5 + parent: 1 + - uid: 137 + components: + - type: Transform + pos: -6.5,0.5 + parent: 1 + - uid: 138 + components: + - type: Transform + pos: -6.5,2.5 + parent: 1 + - uid: 139 + components: + - type: Transform + pos: -6.5,5.5 + parent: 1 + - uid: 140 + components: + - type: Transform + pos: -6.5,-0.5 + parent: 1 + - uid: 141 + components: + - type: Transform + pos: -5.5,5.5 + parent: 1 + - uid: 142 + components: + - type: Transform + pos: -4.5,-0.5 + parent: 1 + - uid: 143 + components: + - type: Transform + pos: -0.5,-0.5 + parent: 1 + - uid: 144 + components: + - type: Transform + pos: -2.5,-0.5 + parent: 1 + - uid: 145 + components: + - type: Transform + pos: -2.5,-3.5 + parent: 1 + - uid: 146 + components: + - type: Transform + pos: -2.5,-4.5 + parent: 1 + - uid: 147 + components: + - type: Transform + pos: -4.5,6.5 + parent: 1 + - uid: 148 + components: + - type: Transform + pos: -4.5,5.5 + parent: 1 + - uid: 149 + components: + - type: Transform + pos: -2.5,-1.5 + parent: 1 + - uid: 150 + components: + - type: Transform + pos: -1.5,-0.5 + parent: 1 +- proto: CableTerminal + entities: + - uid: 151 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,-4.5 + parent: 1 +- proto: Catwalk + entities: + - uid: 152 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -2.5,-3.5 + parent: 1 + - uid: 153 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 2.5,13.5 + parent: 1 + - uid: 154 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 2.5,14.5 + parent: 1 + - uid: 155 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -7.5,14.5 + parent: 1 + - uid: 156 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 2.5,-5.5 + parent: 1 + - uid: 157 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 2.5,-4.5 + parent: 1 + - uid: 158 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -7.5,13.5 + parent: 1 + - uid: 159 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -7.5,-5.5 + parent: 1 + - uid: 160 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -7.5,-4.5 + parent: 1 + - uid: 161 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -2.5,-2.5 + parent: 1 +- proto: Chair + entities: + - uid: 162 + components: + - type: Transform + pos: -1.5,8.5 + parent: 1 +- proto: ChairOfficeLight + entities: + - uid: 163 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5779216,10.282177 + parent: 1 + - uid: 164 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.48648357,13.089132 + parent: 1 +- proto: ChairPilotSeat + entities: + - uid: 165 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -4.5,12.5 + parent: 1 + - uid: 166 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,0.5 + parent: 1 + - uid: 167 + components: + - type: Transform + pos: -6.5,11.5 + parent: 1 + - uid: 168 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,2.5 + parent: 1 + - uid: 169 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,8.5 + parent: 1 + - uid: 170 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,-3.5 + parent: 1 + - uid: 171 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,12.5 + parent: 1 + - uid: 172 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,0.5 + parent: 1 + - uid: 173 + components: + - type: Transform + pos: -2.5,9.5 + parent: 1 + - uid: 174 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -6.5,9.5 + parent: 1 + - uid: 175 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,4.5 + parent: 1 + - uid: 176 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,7.5 + parent: 1 + - uid: 177 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,3.5 + parent: 1 + - uid: 178 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,4.5 + parent: 1 + - uid: 179 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,1.5 + parent: 1 + - uid: 180 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,0.5 + parent: 1 + - uid: 181 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,3.5 + parent: 1 + - uid: 182 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,4.5 + parent: 1 + - uid: 183 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,2.5 + parent: 1 + - uid: 184 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,2.5 + parent: 1 + - uid: 185 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,12.5 + parent: 1 + - uid: 186 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,0.5 + parent: 1 + - uid: 187 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,1.5 + parent: 1 + - uid: 188 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,1.5 + parent: 1 + - uid: 189 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,2.5 + parent: 1 + - uid: 190 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,1.5 + parent: 1 + - uid: 191 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,4.5 + parent: 1 + - uid: 192 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,3.5 + parent: 1 + - uid: 193 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,3.5 + parent: 1 +- proto: CigarGold + entities: + - uid: 194 + components: + - type: Transform + pos: -6.620076,10.550344 + parent: 1 +- proto: ClosetEmergencyFilledRandom + entities: + - uid: 195 + components: + - type: Transform + pos: -6.5,-1.5 + parent: 1 + - uid: 196 + components: + - type: Transform + pos: 1.5,-1.5 + parent: 1 + - uid: 197 + components: + - type: Transform + pos: 1.5,6.5 + parent: 1 +- proto: ClosetEmergencyN2FilledRandom + entities: + - uid: 198 + components: + - type: Transform + pos: -6.5,6.5 + parent: 1 +- proto: ClosetWallEmergencyFilledRandom + entities: + - uid: 199 + components: + - type: Transform + pos: 0.5,14.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 200 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 1.5,-3.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 201 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -6.5,-3.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 202 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,7.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: ClosetWallFireFilledRandom + entities: + - uid: 203 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,-2.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 204 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -4.5,7.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 205 + components: + - type: Transform + pos: -0.5,14.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: ComputerComms + entities: + - uid: 206 + components: + - type: Transform + pos: -5.5,13.5 + parent: 1 +- proto: ComputerEmergencyShuttle + entities: + - uid: 207 + components: + - type: Transform + pos: -4.5,13.5 + parent: 1 +- proto: ComputerRadar + entities: + - uid: 208 components: - type: Transform pos: -3.5,13.5 - parent: 410 + parent: 1 - proto: DefibrillatorCabinetFilled entities: - - uid: 353 + - uid: 209 components: - type: Transform pos: 1.5,12.5 - parent: 410 + parent: 1 + - type: Fixtures + fixtures: {} - proto: DrinkGildlagerBottleFull entities: - - uid: 455 + - uid: 210 components: - type: Transform pos: -6.338826,10.977726 - parent: 410 + parent: 1 - proto: DrinkGlass entities: - - uid: 456 + - uid: 211 components: - type: Transform pos: -6.661743,10.842215 - parent: 410 + parent: 1 - proto: EmergencyLight entities: - - uid: 315 + - uid: 212 components: - type: Transform rot: 3.141592653589793 rad pos: -1.5,-0.5 - parent: 410 + parent: 1 - proto: ExtinguisherCabinetFilled entities: - - uid: 422 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -7.5,0.5 - parent: 410 - - uid: 423 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 2.5,4.5 - parent: 410 -- proto: FireAxeCabinetFilled - entities: - - uid: 291 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,10.5 - parent: 410 -- proto: FirelockEdge - entities: - - uid: 148 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -3.5,-0.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 12 - uid: 213 components: - type: Transform rot: 1.5707963267948966 rad - pos: -1.5,-0.5 - parent: 410 + pos: -7.5,0.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 214 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 2.5,4.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: FireAxeCabinetFilled + entities: + - uid: 215 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,10.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: FirelockEdge + entities: + - uid: 216 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -3.5,-0.5 + parent: 1 - type: DeviceNetwork deviceLists: - - 12 - - uid: 321 + - 2 + - uid: 217 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -1.5,-0.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 2 + - uid: 218 components: - type: Transform rot: 1.5707963267948966 rad pos: -5.5,-0.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 389 - - uid: 483 + - 5 + - uid: 219 components: - type: Transform rot: -1.5707963267948966 rad pos: 0.5,-0.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 180 - - uid: 485 + - 3 + - uid: 220 components: - type: Transform rot: -1.5707963267948966 rad pos: 0.5,5.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 180 - - uid: 486 + - 3 + - uid: 221 components: - type: Transform rot: -1.5707963267948966 rad pos: -3.5,5.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 12 - - uid: 487 + - 2 + - uid: 222 components: - type: Transform rot: 1.5707963267948966 rad pos: -5.5,5.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 389 - - uid: 488 + - 5 + - uid: 223 components: - type: Transform rot: 1.5707963267948966 rad pos: -1.5,5.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 12 + - 2 - proto: GasOutletInjector entities: - - uid: 118 + - uid: 224 components: - type: Transform rot: -1.5707963267948966 rad pos: -0.5,-4.5 - parent: 410 + parent: 1 - proto: GasPassiveVent entities: - - uid: 2 + - uid: 225 components: - type: Transform rot: 3.141592653589793 rad pos: 0.5,-4.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 57 + - uid: 226 components: - type: Transform rot: 3.141592653589793 rad pos: -5.5,-4.5 - parent: 410 + parent: 1 - type: Construction step: 1 edge: 0 @@ -1949,653 +1953,653 @@ entities: color: '#990000FF' - proto: GasPipeBend entities: - - uid: 176 + - uid: 227 components: - type: Transform rot: 1.5707963267948966 rad pos: -3.5,8.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 201 + - uid: 228 components: - type: Transform rot: 3.141592653589793 rad pos: -5.5,-0.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 338 + - uid: 229 components: - type: Transform rot: 1.5707963267948966 rad pos: -5.5,11.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - proto: GasPipeBendAlt2 entities: - - uid: 494 + - uid: 230 components: - type: Transform pos: 1.5,9.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#990000FF' - proto: GasPipeFourwayAlt2 entities: - - uid: 220 + - uid: 231 components: - type: Transform pos: -2.5,5.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#990000FF' - proto: GasPipeStraight entities: - - uid: 18 + - uid: 232 components: - type: Transform rot: 3.141592653589793 rad pos: -5.5,6.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 90 + - uid: 233 components: - type: Transform rot: 3.141592653589793 rad pos: -5.5,9.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 102 + - uid: 234 components: - type: Transform rot: 3.141592653589793 rad pos: -5.5,7.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 110 + - uid: 235 components: - type: Transform pos: 0.5,-1.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 116 + - uid: 236 components: - type: Transform pos: -2.5,0.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 117 + - uid: 237 components: - type: Transform pos: -3.5,0.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 123 + - uid: 238 components: - type: Transform pos: 0.5,6.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 127 + - uid: 239 components: - type: Transform pos: -5.5,3.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 133 + - uid: 240 components: - type: Transform pos: -5.5,5.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 146 + - uid: 241 components: - type: Transform rot: 3.141592653589793 rad pos: 0.5,9.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 149 + - uid: 242 components: - type: Transform rot: 1.5707963267948966 rad pos: -4.5,-0.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 150 + - uid: 243 components: - type: Transform rot: 1.5707963267948966 rad pos: -1.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 151 - components: - - type: Transform - pos: -3.5,2.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 157 - components: - - type: Transform - pos: 0.5,2.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 158 - components: - - type: Transform - pos: 0.5,0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 159 - components: - - type: Transform - pos: -3.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 166 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,6.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 167 - components: - - type: Transform - pos: -5.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 168 - components: - - type: Transform - pos: -3.5,3.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 174 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,7.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 175 - components: - - type: Transform - pos: 0.5,3.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 179 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 182 - components: - - type: Transform - pos: 0.5,-2.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 185 - components: - - type: Transform - pos: 0.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 191 - components: - - type: Transform - pos: -5.5,0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 192 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 0.5,10.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 199 - components: - - type: Transform - pos: -3.5,1.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 202 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -0.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 207 - components: - - type: Transform - pos: 0.5,7.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 217 - components: - - type: Transform - pos: 0.5,-3.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 280 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,10.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 300 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,8.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 359 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 0.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 408 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 0.5,8.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 419 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -4.5,11.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 443 - components: - - type: Transform - pos: -5.5,2.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' -- proto: GasPipeStraightAlt2 - entities: - - uid: 141 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -0.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 183 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,-1.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 188 - components: - - type: Transform - pos: -5.5,9.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 214 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -4.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 240 - components: - - type: Transform - pos: -2.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 247 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,-2.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 250 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 254 - components: - - type: Transform - pos: -5.5,6.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 271 - components: - - type: Transform - pos: -5.5,10.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 303 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 309 - components: - - type: Transform - pos: -5.5,7.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 358 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 362 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,6.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 366 - components: - - type: Transform - pos: -5.5,8.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 388 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 0.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 390 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 391 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,0.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 392 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,1.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 404 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,2.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 484 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -5.5,-3.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 490 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 1.5,4.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 491 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 1.5,6.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 492 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 1.5,7.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 493 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 1.5,8.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' -- proto: GasPipeTJunction - entities: - - uid: 142 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -3.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 194 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 0.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 226 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,-0.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 480 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,1.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 481 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,1.5 - parent: 410 - - type: AtmosPipeColor - color: '#0055CCFF' -- proto: GasPipeTJunctionAlt2 - entities: - - uid: 248 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 1.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 413 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,3.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' - - uid: 415 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -5.5,5.5 - parent: 410 - - type: AtmosPipeColor - color: '#990000FF' -- proto: GasPort - entities: - - uid: 121 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -1.5,-4.5 - parent: 410 -- proto: GasVentPump - entities: - - uid: 193 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 1.5,1.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 180 - - type: AtmosPipeColor - color: '#0055CCFF' - - uid: 219 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -2.5,8.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 12 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - uid: 244 components: - type: Transform - pos: -2.5,1.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 12 + pos: -3.5,2.5 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - uid: 245 components: - type: Transform - rot: 1.5707963267948966 rad - pos: -6.5,1.5 - parent: 410 - - type: DeviceNetwork - deviceLists: - - 389 + pos: 0.5,2.5 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 357 + - uid: 246 + components: + - type: Transform + pos: 0.5,0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 247 + components: + - type: Transform + pos: -3.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 248 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,6.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 249 + components: + - type: Transform + pos: -5.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 250 + components: + - type: Transform + pos: -3.5,3.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 251 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,7.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 252 + components: + - type: Transform + pos: 0.5,3.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 253 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 254 + components: + - type: Transform + pos: 0.5,-2.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 255 + components: + - type: Transform + pos: 0.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 256 + components: + - type: Transform + pos: -5.5,0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 257 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 0.5,10.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 258 + components: + - type: Transform + pos: -3.5,1.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 259 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,-0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 260 + components: + - type: Transform + pos: 0.5,7.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 261 + components: + - type: Transform + pos: 0.5,-3.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 262 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,10.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 263 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,8.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 264 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 0.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 265 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 0.5,8.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 266 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -4.5,11.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 267 + components: + - type: Transform + pos: -5.5,2.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' +- proto: GasPipeStraightAlt2 + entities: + - uid: 268 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -0.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 269 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,-1.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 270 + components: + - type: Transform + pos: -5.5,9.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 271 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -4.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 272 + components: + - type: Transform + pos: -2.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 273 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,-2.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 274 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 275 + components: + - type: Transform + pos: -5.5,6.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 276 + components: + - type: Transform + pos: -5.5,10.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 277 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 278 + components: + - type: Transform + pos: -5.5,7.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 279 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 280 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,6.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 281 + components: + - type: Transform + pos: -5.5,8.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 282 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 283 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,-0.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 284 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,0.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 285 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,1.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 286 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,2.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 287 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -5.5,-3.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 288 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 1.5,4.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 289 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 1.5,6.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 290 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 1.5,7.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 291 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 1.5,8.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' +- proto: GasPipeTJunction + entities: + - uid: 292 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -3.5,-0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 293 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 294 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,-0.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 295 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,1.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 296 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,1.5 + parent: 1 + - type: AtmosPipeColor + color: '#0055CCFF' +- proto: GasPipeTJunctionAlt2 + entities: + - uid: 297 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 298 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,3.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 299 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -5.5,5.5 + parent: 1 + - type: AtmosPipeColor + color: '#990000FF' +- proto: GasPort + entities: + - uid: 300 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -1.5,-4.5 + parent: 1 +- proto: GasVentPump + entities: + - uid: 301 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,1.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 3 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 302 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -2.5,8.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 2 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 303 + components: + - type: Transform + pos: -2.5,1.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 2 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 304 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -6.5,1.5 + parent: 1 + - type: DeviceNetwork + deviceLists: + - 5 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 305 components: - type: Transform pos: 0.5,11.5 - parent: 410 + parent: 1 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 382 + - uid: 306 components: - type: Transform rot: -1.5707963267948966 rad pos: -3.5,11.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 434 + - 6 - type: AtmosPipeColor color: '#0055CCFF' - proto: GasVentScrubber entities: - - uid: 312 + - uid: 307 components: - type: Transform rot: 3.141592653589793 rad pos: -2.5,3.5 - parent: 410 + parent: 1 - type: Construction step: 1 edge: 0 @@ -2603,17 +2607,17 @@ entities: pipeLayer: Tertiary - type: DeviceNetwork deviceLists: - - 12 + - 2 - type: AtmosPipeColor color: '#990000FF' - - uid: 347 + - uid: 308 components: - type: Transform pos: -2.5,7.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 12 + - 2 - type: Construction step: 1 edge: 0 @@ -2621,15 +2625,15 @@ entities: pipeLayer: Tertiary - type: AtmosPipeColor color: '#990000FF' - - uid: 406 + - uid: 309 components: - type: Transform rot: 1.5707963267948966 rad pos: -6.5,3.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 389 + - 5 - type: Construction step: 1 edge: 0 @@ -2637,12 +2641,12 @@ entities: pipeLayer: Tertiary - type: AtmosPipeColor color: '#990000FF' - - uid: 420 + - uid: 310 components: - type: Transform rot: 1.5707963267948966 rad pos: 0.5,9.5 - parent: 410 + parent: 1 - type: Construction step: 1 edge: 0 @@ -2650,15 +2654,15 @@ entities: pipeLayer: Tertiary - type: AtmosPipeColor color: '#990000FF' - - uid: 482 + - uid: 311 components: - type: Transform rot: 3.141592653589793 rad pos: 1.5,3.5 - parent: 410 + parent: 1 - type: DeviceNetwork deviceLists: - - 180 + - 3 - type: Construction step: 1 edge: 0 @@ -2666,11 +2670,11 @@ entities: pipeLayer: Tertiary - type: AtmosPipeColor color: '#990000FF' - - uid: 489 + - uid: 312 components: - type: Transform pos: -5.5,11.5 - parent: 410 + parent: 1 - type: Construction step: 1 edge: 0 @@ -2680,998 +2684,1016 @@ entities: color: '#990000FF' - proto: GeneratorBasic15kW entities: - - uid: 203 + - uid: 313 components: - type: Transform pos: -3.5,-3.5 - parent: 410 - - uid: 224 + parent: 1 + - uid: 314 components: - type: Transform pos: -3.5,-2.5 - parent: 410 + parent: 1 - proto: GeneratorWallmountAPU entities: - - uid: 440 + - uid: 315 components: - type: Transform pos: -4.5,-3.5 - parent: 410 - - uid: 441 + parent: 1 + - uid: 316 components: - type: Transform pos: -4.5,-2.5 - parent: 410 + parent: 1 - proto: GravityGeneratorMini + entities: + - uid: 317 + components: + - type: Transform + pos: -3.5,-4.5 + parent: 1 +- proto: Grille + entities: + - uid: 318 + components: + - type: Transform + pos: 2.5,10.5 + parent: 1 + - uid: 319 + components: + - type: Transform + pos: -2.5,14.5 + parent: 1 + - uid: 320 + components: + - type: Transform + pos: 2.5,3.5 + parent: 1 + - uid: 321 + components: + - type: Transform + pos: -6.5,14.5 + parent: 1 + - uid: 322 + components: + - type: Transform + pos: -6.5,8.5 + parent: 1 + - uid: 323 + components: + - type: Transform + pos: 2.5,9.5 + parent: 1 + - uid: 324 + components: + - type: Transform + pos: 2.5,1.5 + parent: 1 + - uid: 325 + components: + - type: Transform + pos: 2.5,11.5 + parent: 1 + - uid: 326 + components: + - type: Transform + pos: -7.5,1.5 + parent: 1 + - uid: 327 + components: + - type: Transform + pos: -7.5,3.5 + parent: 1 + - uid: 328 + components: + - type: Transform + pos: 1.5,8.5 + parent: 1 + - uid: 329 + components: + - type: Transform + pos: -5.5,14.5 + parent: 1 + - uid: 330 + components: + - type: Transform + pos: -6.5,13.5 + parent: 1 + - uid: 331 + components: + - type: Transform + pos: 2.5,2.5 + parent: 1 + - uid: 332 + components: + - type: Transform + pos: 0.5,-3.5 + parent: 1 + - uid: 333 + components: + - type: Transform + pos: -7.5,-1.5 + parent: 1 + - uid: 334 + components: + - type: Transform + pos: -7.5,2.5 + parent: 1 + - uid: 335 + components: + - type: Transform + pos: -4.5,14.5 + parent: 1 + - uid: 336 + components: + - type: Transform + pos: -3.5,14.5 + parent: 1 + - uid: 337 + components: + - type: Transform + pos: -3.5,6.5 + parent: 1 + - uid: 338 + components: + - type: Transform + pos: 2.5,-1.5 + parent: 1 + - uid: 339 + components: + - type: Transform + pos: -7.5,6.5 + parent: 1 + - uid: 340 + components: + - type: Transform + pos: 2.5,6.5 + parent: 1 + - uid: 341 + components: + - type: Transform + pos: -1.5,6.5 + parent: 1 + - uid: 342 + components: + - type: Transform + pos: -5.5,-3.5 + parent: 1 + - uid: 343 + components: + - type: Transform + pos: -6.5,12.5 + parent: 1 + - uid: 344 + components: + - type: Transform + pos: -5.5,-5.5 + parent: 1 +- proto: Gyroscope entities: - uid: 345 components: - type: Transform - pos: -3.5,-4.5 - parent: 410 -- proto: Grille + pos: -4.5,-4.5 + parent: 1 +- proto: HandheldHealthAnalyzerUnpowered entities: - - uid: 44 - components: - - type: Transform - pos: 2.5,10.5 - parent: 410 - - uid: 95 - components: - - type: Transform - pos: -2.5,14.5 - parent: 410 - - uid: 101 - components: - - type: Transform - pos: 2.5,3.5 - parent: 410 - - uid: 104 - components: - - type: Transform - pos: -6.5,14.5 - parent: 410 - - uid: 124 - components: - - type: Transform - pos: -6.5,8.5 - parent: 410 - - uid: 138 - components: - - type: Transform - pos: 2.5,9.5 - parent: 410 - - uid: 155 - components: - - type: Transform - pos: 2.5,1.5 - parent: 410 - - uid: 169 - components: - - type: Transform - pos: 2.5,11.5 - parent: 410 - - uid: 171 - components: - - type: Transform - pos: -7.5,1.5 - parent: 410 - - uid: 173 - components: - - type: Transform - pos: -7.5,3.5 - parent: 410 - - uid: 237 - components: - - type: Transform - pos: 1.5,8.5 - parent: 410 - - uid: 260 - components: - - type: Transform - pos: -5.5,14.5 - parent: 410 - - uid: 261 - components: - - type: Transform - pos: -6.5,13.5 - parent: 410 - - uid: 263 - components: - - type: Transform - pos: 2.5,2.5 - parent: 410 - - uid: 281 - components: - - type: Transform - pos: 0.5,-3.5 - parent: 410 - - uid: 288 - components: - - type: Transform - pos: -7.5,-1.5 - parent: 410 - - uid: 295 - components: - - type: Transform - pos: -7.5,2.5 - parent: 410 - - uid: 296 - components: - - type: Transform - pos: -4.5,14.5 - parent: 410 - - uid: 297 - components: - - type: Transform - pos: -3.5,14.5 - parent: 410 - - uid: 301 - components: - - type: Transform - pos: -3.5,6.5 - parent: 410 - - uid: 308 - components: - - type: Transform - pos: 2.5,-1.5 - parent: 410 - - uid: 344 - components: - - type: Transform - pos: -7.5,6.5 - parent: 410 - uid: 346 - components: - - type: Transform - pos: 2.5,6.5 - parent: 410 - - uid: 350 - components: - - type: Transform - pos: -1.5,6.5 - parent: 410 - - uid: 356 - components: - - type: Transform - pos: -5.5,-3.5 - parent: 410 - - uid: 449 - components: - - type: Transform - pos: -6.5,12.5 - parent: 410 - - uid: 473 - components: - - type: Transform - pos: -5.5,-5.5 - parent: 410 -- proto: Gyroscope - entities: - - uid: 352 - components: - - type: Transform - pos: -4.5,-4.5 - parent: 410 -- proto: HandheldHealthAnalyzerUnpowered - entities: - - uid: 370 components: - type: Transform pos: 1.5254471,10.577127 - parent: 410 + parent: 1 - proto: HolopadCentCommEvacShuttle entities: - - uid: 108 + - uid: 347 components: - type: Transform pos: -5.5,10.5 - parent: 410 + parent: 1 - proto: LockerEvacRepairFilled entities: - - uid: 128 - components: - - type: Transform - pos: -1.5,-2.5 - parent: 410 -- proto: LockerEvidence - entities: - - uid: 424 - components: - - type: Transform - pos: -3.5,9.5 - parent: 410 -- proto: LockerMedicineFilled - entities: - - uid: 140 - components: - - type: Transform - pos: -0.5,11.5 - parent: 410 -- proto: MedicalBed - entities: - - uid: 365 - components: - - type: Transform - pos: 1.5,9.5 - parent: 410 - - uid: 407 - components: - - type: Transform - pos: -0.5,13.5 - parent: 410 -- proto: MedkitFilled - entities: - - uid: 37 - components: - - type: Transform - pos: -0.4916364,12.55368 - parent: 410 -- proto: Paper - entities: - - uid: 70 - components: - - type: Transform - pos: -2.3867393,13.229256 - parent: 410 - - uid: 304 - components: - - type: Transform - pos: -2.5273643,13.057381 - parent: 410 -- proto: PottedPlant10 - entities: - - uid: 243 - components: - - type: Transform - pos: -2.5,11.5 - parent: 410 -- proto: Poweredlight - entities: - - uid: 77 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,-1.5 - parent: 410 - - uid: 264 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,-1.5 - parent: 410 - - uid: 299 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -2.5,12.5 - parent: 410 - - uid: 316 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: 0.5,6.5 - parent: 410 - - uid: 355 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -0.5,12.5 - parent: 410 - - uid: 373 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -5.5,6.5 - parent: 410 - - uid: 387 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,8.5 - parent: 410 - - uid: 411 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,-3.5 - parent: 410 - - uid: 436 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,0.5 - parent: 410 - - uid: 437 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -3.5,4.5 - parent: 410 - - uid: 447 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -6.5,10.5 - parent: 410 -- proto: Screen - entities: - - uid: 87 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 2.5,0.5 - parent: 410 - - uid: 109 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -7.5,4.5 - parent: 410 - - uid: 255 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -1.5,11.5 - parent: 410 -- proto: ShuttleWindow - entities: - - uid: 21 - components: - - type: Transform - pos: 2.5,3.5 - parent: 410 - - uid: 25 - components: - - type: Transform - pos: -0.5,3.5 - parent: 410 - - uid: 27 - components: - - type: Transform - pos: -1.5,6.5 - parent: 410 - - uid: 60 - components: - - type: Transform - pos: -5.5,-5.5 - parent: 410 - - uid: 73 - components: - - type: Transform - pos: -3.5,6.5 - parent: 410 - - uid: 80 - components: - - type: Transform - pos: -4.5,1.5 - parent: 410 - - uid: 81 - components: - - type: Transform - pos: -7.5,2.5 - parent: 410 - - uid: 88 - components: - - type: Transform - pos: 2.5,1.5 - parent: 410 - - uid: 105 - components: - - type: Transform - pos: -3.5,14.5 - parent: 410 - - uid: 112 - components: - - type: Transform - pos: 2.5,2.5 - parent: 410 - - uid: 147 - components: - - type: Transform - pos: -7.5,1.5 - parent: 410 - - uid: 198 - components: - - type: Transform - pos: -7.5,3.5 - parent: 410 - - uid: 230 - components: - - type: Transform - pos: -5.5,14.5 - parent: 410 - - uid: 231 - components: - - type: Transform - pos: -6.5,14.5 - parent: 410 - - uid: 232 - components: - - type: Transform - pos: -6.5,13.5 - parent: 410 - - uid: 252 - components: - - type: Transform - pos: -6.5,8.5 - parent: 410 - - uid: 257 - components: - - type: Transform - pos: 1.5,8.5 - parent: 410 - - uid: 262 - components: - - type: Transform - pos: -4.5,14.5 - parent: 410 - - uid: 265 - components: - - type: Transform - pos: -7.5,6.5 - parent: 410 - - uid: 270 - components: - - type: Transform - pos: -5.5,-3.5 - parent: 410 - - uid: 272 - components: - - type: Transform - pos: -0.5,2.5 - parent: 410 - - uid: 282 - components: - - type: Transform - pos: 2.5,9.5 - parent: 410 - - uid: 283 - components: - - type: Transform - pos: 2.5,10.5 - parent: 410 - - uid: 284 - components: - - type: Transform - pos: 2.5,11.5 - parent: 410 - - uid: 286 - components: - - type: Transform - pos: 2.5,-1.5 - parent: 410 - - uid: 287 - components: - - type: Transform - pos: -0.5,1.5 - parent: 410 - - uid: 290 - components: - - type: Transform - pos: 0.5,-3.5 - parent: 410 - - uid: 307 - components: - - type: Transform - pos: -2.5,14.5 - parent: 410 - - uid: 324 - components: - - type: Transform - pos: -4.5,2.5 - parent: 410 - - uid: 342 - components: - - type: Transform - pos: -4.5,3.5 - parent: 410 - - uid: 364 - components: - - type: Transform - pos: -7.5,-1.5 - parent: 410 - - uid: 409 - components: - - type: Transform - pos: -6.5,12.5 - parent: 410 - - uid: 421 - components: - - type: Transform - pos: 2.5,6.5 - parent: 410 -- proto: SignBridge - entities: - - uid: 238 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -6.5,8.5 - parent: 410 -- proto: SignEngineering - entities: - - uid: 444 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,-1.5 - parent: 410 -- proto: SignMedical - entities: - - uid: 113 - components: - - type: Transform - pos: 1.5,8.5 - parent: 410 -- proto: SignSecurity - entities: - - uid: 190 - components: - - type: Transform - pos: -1.5,6.5 - parent: 410 -- proto: SMESBasic - entities: - - uid: 292 - components: - - type: Transform - pos: -2.5,-4.5 - parent: 410 -- proto: StasisBed - entities: - - uid: 320 - components: - - type: Transform - pos: 1.5,11.5 - parent: 410 -- proto: SubstationWallBasic - entities: - - uid: 58 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,-5.5 - parent: 410 -- proto: TableGlass - entities: - - uid: 86 - components: - - type: Transform - pos: 1.5,10.5 - parent: 410 - - uid: 374 - components: - - type: Transform - pos: -0.5,12.5 - parent: 410 -- proto: TableReinforced - entities: - - uid: 46 - components: - - type: Transform - pos: -2.5,12.5 - parent: 410 - - uid: 454 - components: - - type: Transform - pos: -2.5,13.5 - parent: 410 -- proto: TableWood - entities: - - uid: 16 - components: - - type: Transform - pos: -6.5,10.5 - parent: 410 -- proto: Thruster - entities: - - uid: 53 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 2.5,-4.5 - parent: 410 - - uid: 67 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -7.5,-4.5 - parent: 410 - - uid: 195 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 2.5,-5.5 - parent: 410 - - uid: 289 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -7.5,-5.5 - parent: 410 - - uid: 334 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -7.5,13.5 - parent: 410 - - uid: 335 - components: - - type: Transform - pos: -7.5,14.5 - parent: 410 - uid: 348 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 2.5,13.5 - parent: 410 - - uid: 360 - components: - - type: Transform - pos: 2.5,14.5 - parent: 410 -- proto: VendingMachineMedical + pos: -1.5,-2.5 + parent: 1 +- proto: LockerEvidence entities: - - uid: 379 + - uid: 349 components: - type: Transform - pos: -0.5,10.5 - parent: 410 -- proto: VendingMachineWallMedical + pos: -3.5,9.5 + parent: 1 +- proto: LockerMedicineFilled entities: - - uid: 211 + - uid: 350 components: - type: Transform - rot: -1.5707963267948966 rad - pos: 1.5,13.5 - parent: 410 -- proto: WallShuttle + pos: -0.5,11.5 + parent: 1 +- proto: MedicalBed entities: - - uid: 3 + - uid: 351 components: - type: Transform - pos: -7.5,-3.5 - parent: 410 - - uid: 7 + pos: 1.5,9.5 + parent: 1 + - uid: 352 components: - type: Transform - pos: -7.5,0.5 - parent: 410 - - uid: 8 - components: - - type: Transform - pos: -4.5,4.5 - parent: 410 - - uid: 9 - components: - - type: Transform - pos: -0.5,-1.5 - parent: 410 - - uid: 10 - components: - - type: Transform - pos: 2.5,4.5 - parent: 410 - - uid: 11 - components: - - type: Transform - pos: -7.5,4.5 - parent: 410 - - uid: 15 - components: - - type: Transform - pos: -7.5,8.5 - parent: 410 - - uid: 28 - components: - - type: Transform - pos: -0.5,9.5 - parent: 410 - - uid: 31 - components: - - type: Transform - pos: 0.5,14.5 - parent: 410 - - uid: 39 - components: - - type: Transform - pos: 1.5,-5.5 - parent: 410 - - uid: 41 - components: - - type: Transform - pos: 2.5,0.5 - parent: 410 - - uid: 59 - components: - - type: Transform - pos: -0.5,-2.5 - parent: 410 - - uid: 69 - components: - - type: Transform - pos: -0.5,14.5 - parent: 410 - - uid: 72 - components: - - type: Transform - pos: -0.5,-3.5 - parent: 410 - - uid: 78 - components: - - type: Transform - pos: -1.5,13.5 - parent: 410 - - uid: 85 - components: - - type: Transform - pos: -1.5,12.5 - parent: 410 - - uid: 92 - components: - - type: Transform - pos: -1.5,14.5 - parent: 410 - - uid: 93 - components: - - type: Transform - pos: -4.5,8.5 - parent: 410 - - uid: 94 - components: - - type: Transform - pos: -4.5,6.5 - parent: 410 - - uid: 98 - components: - - type: Transform - pos: -4.5,-3.5 - parent: 410 - - uid: 131 - components: - - type: Transform - pos: -3.5,-1.5 - parent: 410 - - uid: 143 - components: - - type: Transform - pos: 2.5,-3.5 - parent: 410 - - uid: 144 - components: - - type: Transform - pos: 2.5,8.5 - parent: 410 - - uid: 153 - components: - - type: Transform - pos: 1.5,-3.5 - parent: 410 - - uid: 154 - components: - - type: Transform - pos: -4.5,-2.5 - parent: 410 - - uid: 170 - components: - - type: Transform - pos: -6.5,-3.5 - parent: 410 - - uid: 187 - components: - - type: Transform - pos: -4.5,-1.5 - parent: 410 - - uid: 216 - components: - - type: Transform - pos: 1.5,12.5 - parent: 410 - - uid: 256 - components: - - type: Transform - pos: -1.5,-1.5 - parent: 410 - - uid: 259 - components: - - type: Transform - pos: -0.5,6.5 - parent: 410 - - uid: 267 - components: - - type: Transform - pos: -1.5,-5.5 - parent: 410 - - uid: 269 - components: - - type: Transform - pos: -0.5,-5.5 - parent: 410 - - uid: 276 - components: - - type: Transform - pos: -0.5,0.5 - parent: 410 - - uid: 293 - components: - - type: Transform - pos: -1.5,11.5 - parent: 410 - - uid: 325 - components: - - type: Transform - pos: -3.5,10.5 - parent: 410 - - uid: 327 - components: - - type: Transform - pos: 2.5,12.5 - parent: 410 - - uid: 331 - components: - - type: Transform - pos: -6.5,-5.5 - parent: 410 - - uid: 332 - components: - - type: Transform - pos: -6.5,-4.5 - parent: 410 - - uid: 333 - components: - - type: Transform - pos: 1.5,-4.5 - parent: 410 - - uid: 336 - components: - - type: Transform - pos: 1.5,14.5 - parent: 410 - - uid: 339 - components: - - type: Transform - pos: -4.5,0.5 - parent: 410 - - uid: 361 - components: - - type: Transform - pos: -4.5,10.5 - parent: 410 - - uid: 363 - components: - - type: Transform - pos: -4.5,-5.5 - parent: 410 - - uid: 367 - components: - - type: Transform - pos: -0.5,8.5 - parent: 410 - - uid: 368 - components: - - type: Transform - pos: 0.5,-5.5 - parent: 410 - - uid: 369 - components: - - type: Transform - pos: -2.5,-5.5 - parent: 410 - - uid: 371 - components: - - type: Transform - pos: -7.5,10.5 - parent: 410 - - uid: 372 - components: - - type: Transform - pos: -1.5,9.5 - parent: 410 - - uid: 375 - components: - - type: Transform - pos: -1.5,10.5 - parent: 410 - - uid: 377 - components: - - type: Transform - pos: -4.5,7.5 - parent: 410 - - uid: 385 - components: - - type: Transform - pos: -4.5,9.5 - parent: 410 - - uid: 386 - components: - - type: Transform - pos: 1.5,13.5 - parent: 410 - - uid: 405 - components: - - type: Transform - pos: -3.5,-5.5 - parent: 410 - - uid: 412 - components: - - type: Transform - pos: -7.5,9.5 - parent: 410 - - uid: 414 - components: - - type: Transform - pos: -7.5,11.5 - parent: 410 - - uid: 417 - components: - - type: Transform - pos: -2.5,10.5 - parent: 410 - - uid: 425 - components: - - type: Transform - pos: -0.5,7.5 - parent: 410 - - uid: 446 - components: - - type: Transform - pos: -7.5,12.5 - parent: 410 - - uid: 453 - components: - - type: Transform - pos: -0.5,4.5 - parent: 410 -- proto: WallWeaponCapacitorRecharger + pos: -0.5,13.5 + parent: 1 +- proto: MedkitFilled entities: - - uid: 376 + - uid: 353 components: - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,9.5 - parent: 410 -- proto: WeaponCapacitorRecharger + pos: -0.4916364,12.55368 + parent: 1 +- proto: Paper entities: - - uid: 273 + - uid: 354 components: - type: Transform - pos: -2.5,12.5 - parent: 410 -- proto: WindoorSecureSecurityLocked - entities: - - uid: 107 + pos: -2.3867393,13.229256 + parent: 1 + - uid: 355 components: - type: Transform - rot: -1.5707963267948966 rad - pos: -1.5,7.5 - parent: 410 -- proto: WindowReinforcedDirectional + pos: -2.5273643,13.057381 + parent: 1 +- proto: PlasmaWindowDirectional entities: - - uid: 64 + - uid: 488 components: - type: Transform rot: -1.5707963267948966 rad pos: -0.5,-4.5 - parent: 410 + parent: 1 +- proto: PottedPlant10 + entities: + - uid: 356 + components: + - type: Transform + pos: -2.5,11.5 + parent: 1 +- proto: Poweredlight + entities: + - uid: 357 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,-1.5 + parent: 1 + - uid: 358 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,-1.5 + parent: 1 + - uid: 359 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -2.5,12.5 + parent: 1 + - uid: 360 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,6.5 + parent: 1 + - uid: 361 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,12.5 + parent: 1 + - uid: 362 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -5.5,6.5 + parent: 1 + - uid: 363 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,8.5 + parent: 1 + - uid: 364 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,-3.5 + parent: 1 + - uid: 365 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,0.5 + parent: 1 + - uid: 366 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -3.5,4.5 + parent: 1 + - uid: 367 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -6.5,10.5 + parent: 1 +- proto: Screen + entities: + - uid: 368 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 2.5,0.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 369 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -7.5,4.5 + parent: 1 + - type: Fixtures + fixtures: {} + - uid: 370 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -1.5,11.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: ShuttleWindow + entities: + - uid: 371 + components: + - type: Transform + pos: 2.5,3.5 + parent: 1 + - uid: 372 + components: + - type: Transform + pos: -0.5,3.5 + parent: 1 + - uid: 373 + components: + - type: Transform + pos: -1.5,6.5 + parent: 1 + - uid: 374 + components: + - type: Transform + pos: -5.5,-5.5 + parent: 1 + - uid: 375 + components: + - type: Transform + pos: -3.5,6.5 + parent: 1 + - uid: 376 + components: + - type: Transform + pos: -4.5,1.5 + parent: 1 + - uid: 377 + components: + - type: Transform + pos: -7.5,2.5 + parent: 1 + - uid: 378 + components: + - type: Transform + pos: 2.5,1.5 + parent: 1 + - uid: 379 + components: + - type: Transform + pos: -3.5,14.5 + parent: 1 + - uid: 380 + components: + - type: Transform + pos: 2.5,2.5 + parent: 1 + - uid: 381 + components: + - type: Transform + pos: -7.5,1.5 + parent: 1 + - uid: 382 + components: + - type: Transform + pos: -7.5,3.5 + parent: 1 + - uid: 383 + components: + - type: Transform + pos: -5.5,14.5 + parent: 1 + - uid: 384 + components: + - type: Transform + pos: -6.5,14.5 + parent: 1 + - uid: 385 + components: + - type: Transform + pos: -6.5,13.5 + parent: 1 + - uid: 386 + components: + - type: Transform + pos: -6.5,8.5 + parent: 1 + - uid: 387 + components: + - type: Transform + pos: 1.5,8.5 + parent: 1 + - uid: 388 + components: + - type: Transform + pos: -4.5,14.5 + parent: 1 + - uid: 389 + components: + - type: Transform + pos: -7.5,6.5 + parent: 1 + - uid: 390 + components: + - type: Transform + pos: -5.5,-3.5 + parent: 1 + - uid: 391 + components: + - type: Transform + pos: -0.5,2.5 + parent: 1 + - uid: 392 + components: + - type: Transform + pos: 2.5,9.5 + parent: 1 + - uid: 393 + components: + - type: Transform + pos: 2.5,10.5 + parent: 1 + - uid: 394 + components: + - type: Transform + pos: 2.5,11.5 + parent: 1 + - uid: 395 + components: + - type: Transform + pos: 2.5,-1.5 + parent: 1 + - uid: 396 + components: + - type: Transform + pos: -0.5,1.5 + parent: 1 + - uid: 397 + components: + - type: Transform + pos: 0.5,-3.5 + parent: 1 + - uid: 398 + components: + - type: Transform + pos: -2.5,14.5 + parent: 1 + - uid: 399 + components: + - type: Transform + pos: -4.5,2.5 + parent: 1 + - uid: 400 + components: + - type: Transform + pos: -4.5,3.5 + parent: 1 + - uid: 401 + components: + - type: Transform + pos: -7.5,-1.5 + parent: 1 + - uid: 402 + components: + - type: Transform + pos: -6.5,12.5 + parent: 1 - uid: 403 + components: + - type: Transform + pos: 2.5,6.5 + parent: 1 +- proto: SignBridge + entities: + - uid: 404 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -6.5,8.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: SignEngineering + entities: + - uid: 405 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,-1.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: SignMedical + entities: + - uid: 406 + components: + - type: Transform + pos: 1.5,8.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: SignSecurity + entities: + - uid: 407 + components: + - type: Transform + pos: -1.5,6.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: SMESBasic + entities: + - uid: 408 + components: + - type: Transform + pos: -2.5,-4.5 + parent: 1 +- proto: StasisBed + entities: + - uid: 409 + components: + - type: Transform + pos: 1.5,11.5 + parent: 1 +- proto: SubstationWallBasic + entities: + - uid: 410 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,-5.5 + parent: 1 +- proto: TableGlass + entities: + - uid: 411 + components: + - type: Transform + pos: 1.5,10.5 + parent: 1 + - uid: 412 + components: + - type: Transform + pos: -0.5,12.5 + parent: 1 +- proto: TableReinforced + entities: + - uid: 413 + components: + - type: Transform + pos: -2.5,12.5 + parent: 1 + - uid: 414 + components: + - type: Transform + pos: -2.5,13.5 + parent: 1 +- proto: TableWood + entities: + - uid: 415 + components: + - type: Transform + pos: -6.5,10.5 + parent: 1 +- proto: Thruster + entities: + - uid: 416 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 2.5,-4.5 + parent: 1 + - uid: 417 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -7.5,-4.5 + parent: 1 + - uid: 418 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 2.5,-5.5 + parent: 1 + - uid: 419 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -7.5,-5.5 + parent: 1 + - uid: 420 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -7.5,13.5 + parent: 1 + - uid: 421 + components: + - type: Transform + pos: -7.5,14.5 + parent: 1 + - uid: 422 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 2.5,13.5 + parent: 1 + - uid: 423 + components: + - type: Transform + pos: 2.5,14.5 + parent: 1 +- proto: VendingMachineMedical + entities: + - uid: 424 + components: + - type: Transform + pos: -0.5,10.5 + parent: 1 +- proto: VendingMachineWallMedical + entities: + - uid: 425 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,13.5 + parent: 1 + - type: Fixtures + fixtures: {} +- proto: WallShuttle + entities: + - uid: 426 + components: + - type: Transform + pos: -7.5,-3.5 + parent: 1 + - uid: 427 + components: + - type: Transform + pos: -7.5,0.5 + parent: 1 + - uid: 428 + components: + - type: Transform + pos: -4.5,4.5 + parent: 1 + - uid: 429 + components: + - type: Transform + pos: -0.5,-1.5 + parent: 1 + - uid: 430 + components: + - type: Transform + pos: 2.5,4.5 + parent: 1 + - uid: 431 + components: + - type: Transform + pos: -7.5,4.5 + parent: 1 + - uid: 432 + components: + - type: Transform + pos: -7.5,8.5 + parent: 1 + - uid: 433 + components: + - type: Transform + pos: -0.5,9.5 + parent: 1 + - uid: 434 + components: + - type: Transform + pos: 0.5,14.5 + parent: 1 + - uid: 435 + components: + - type: Transform + pos: 1.5,-5.5 + parent: 1 + - uid: 436 + components: + - type: Transform + pos: 2.5,0.5 + parent: 1 + - uid: 437 + components: + - type: Transform + pos: -0.5,-2.5 + parent: 1 + - uid: 438 + components: + - type: Transform + pos: -0.5,14.5 + parent: 1 + - uid: 439 + components: + - type: Transform + pos: -0.5,-3.5 + parent: 1 + - uid: 440 + components: + - type: Transform + pos: -1.5,13.5 + parent: 1 + - uid: 441 + components: + - type: Transform + pos: -1.5,12.5 + parent: 1 + - uid: 442 + components: + - type: Transform + pos: -1.5,14.5 + parent: 1 + - uid: 443 + components: + - type: Transform + pos: -4.5,8.5 + parent: 1 + - uid: 444 + components: + - type: Transform + pos: -4.5,6.5 + parent: 1 + - uid: 445 + components: + - type: Transform + pos: -4.5,-3.5 + parent: 1 + - uid: 446 + components: + - type: Transform + pos: -3.5,-1.5 + parent: 1 + - uid: 447 + components: + - type: Transform + pos: 2.5,-3.5 + parent: 1 + - uid: 448 + components: + - type: Transform + pos: 2.5,8.5 + parent: 1 + - uid: 449 + components: + - type: Transform + pos: 1.5,-3.5 + parent: 1 + - uid: 450 + components: + - type: Transform + pos: -4.5,-2.5 + parent: 1 + - uid: 451 + components: + - type: Transform + pos: -6.5,-3.5 + parent: 1 + - uid: 452 + components: + - type: Transform + pos: -4.5,-1.5 + parent: 1 + - uid: 453 + components: + - type: Transform + pos: 1.5,12.5 + parent: 1 + - uid: 454 + components: + - type: Transform + pos: -1.5,-1.5 + parent: 1 + - uid: 455 + components: + - type: Transform + pos: -0.5,6.5 + parent: 1 + - uid: 456 + components: + - type: Transform + pos: -1.5,-5.5 + parent: 1 + - uid: 457 + components: + - type: Transform + pos: -0.5,-5.5 + parent: 1 + - uid: 458 + components: + - type: Transform + pos: -0.5,0.5 + parent: 1 + - uid: 459 + components: + - type: Transform + pos: -1.5,11.5 + parent: 1 + - uid: 460 + components: + - type: Transform + pos: -3.5,10.5 + parent: 1 + - uid: 461 + components: + - type: Transform + pos: 2.5,12.5 + parent: 1 + - uid: 462 + components: + - type: Transform + pos: -6.5,-5.5 + parent: 1 + - uid: 463 + components: + - type: Transform + pos: -6.5,-4.5 + parent: 1 + - uid: 464 + components: + - type: Transform + pos: 1.5,-4.5 + parent: 1 + - uid: 465 + components: + - type: Transform + pos: 1.5,14.5 + parent: 1 + - uid: 466 + components: + - type: Transform + pos: -4.5,0.5 + parent: 1 + - uid: 467 + components: + - type: Transform + pos: -4.5,10.5 + parent: 1 + - uid: 468 + components: + - type: Transform + pos: -4.5,-5.5 + parent: 1 + - uid: 469 + components: + - type: Transform + pos: -0.5,8.5 + parent: 1 + - uid: 470 + components: + - type: Transform + pos: 0.5,-5.5 + parent: 1 + - uid: 471 + components: + - type: Transform + pos: -2.5,-5.5 + parent: 1 + - uid: 472 + components: + - type: Transform + pos: -7.5,10.5 + parent: 1 + - uid: 473 + components: + - type: Transform + pos: -1.5,9.5 + parent: 1 + - uid: 474 + components: + - type: Transform + pos: -1.5,10.5 + parent: 1 + - uid: 475 + components: + - type: Transform + pos: -4.5,7.5 + parent: 1 + - uid: 476 + components: + - type: Transform + pos: -4.5,9.5 + parent: 1 + - uid: 477 + components: + - type: Transform + pos: 1.5,13.5 + parent: 1 + - uid: 478 + components: + - type: Transform + pos: -3.5,-5.5 + parent: 1 + - uid: 479 + components: + - type: Transform + pos: -7.5,9.5 + parent: 1 + - uid: 480 + components: + - type: Transform + pos: -7.5,11.5 + parent: 1 + - uid: 481 + components: + - type: Transform + pos: -2.5,10.5 + parent: 1 + - uid: 482 + components: + - type: Transform + pos: -0.5,7.5 + parent: 1 + - uid: 483 + components: + - type: Transform + pos: -7.5,12.5 + parent: 1 + - uid: 484 + components: + - type: Transform + pos: -0.5,4.5 + parent: 1 +- proto: WallWeaponCapacitorRecharger + entities: + - uid: 485 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,9.5 + parent: 1 +- proto: WeaponCapacitorRecharger + entities: + - uid: 486 + components: + - type: Transform + pos: -2.5,12.5 + parent: 1 +- proto: WindoorSecureSecurityLocked + entities: + - uid: 487 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,7.5 + parent: 1 +- proto: WindowReinforcedDirectional + entities: + - uid: 489 components: - type: Transform rot: -1.5707963267948966 rad pos: -4.5,-4.5 - parent: 410 - - uid: 448 + parent: 1 + - uid: 490 components: - type: Transform rot: -1.5707963267948966 rad pos: -1.5,8.5 - parent: 410 + parent: 1 - proto: Wrench entities: - - uid: 343 + - uid: 491 components: - type: Transform pos: -2.4217896,-3.4986176 - parent: 410 + parent: 1 ... diff --git a/Resources/Maps/Shuttles/mothership.yml b/Resources/Maps/Shuttles/mothership.yml index b958c47401..e515787629 100644 --- a/Resources/Maps/Shuttles/mothership.yml +++ b/Resources/Maps/Shuttles/mothership.yml @@ -1,11 +1,11 @@ meta: format: 7 category: Grid - engineVersion: 266.0.0 + engineVersion: 268.0.0 forkId: "" forkVersion: "" - time: 08/14/2025 23:46:23 - entityCount: 435 + time: 11/16/2025 15:37:41 + entityCount: 441 maps: [] grids: - 1 @@ -1100,10 +1100,11 @@ entities: parent: 1 - proto: ComputerIFFSyndicate entities: - - uid: 278 + - uid: 437 components: - type: Transform - pos: 2.5,5.5 + rot: -1.5707963267948966 rad + pos: 2.5,1.5 parent: 1 - proto: ComputerPowerMonitoring entities: @@ -1132,6 +1133,11 @@ entities: parent: 1 - proto: ComputerSurveillanceCameraMonitor entities: + - uid: 278 + components: + - type: Transform + pos: 2.5,5.5 + parent: 1 - uid: 426 components: - type: Transform @@ -1579,22 +1585,18 @@ entities: rot: 3.141592653589793 rad pos: -6.5,-0.5 parent: 1 -- proto: MachineArtifactCrusher +- proto: MachineArtifactCrusherXenoborg entities: - - uid: 372 + - uid: 111 components: - - type: MetaData - name: body crusher - - type: Transform - pos: 3.5,-4.5 - parent: 1 - - uid: 373 - components: - - type: MetaData - name: body crusher - type: Transform pos: 2.5,-4.5 parent: 1 + - uid: 112 + components: + - type: Transform + pos: 3.5,-4.5 + parent: 1 - proto: PlasticFlapsAirtightClear entities: - uid: 252 @@ -1748,6 +1750,35 @@ entities: - type: Transform pos: -9.5,1.5 parent: 1 +- proto: SpawnPointMothershipCore + entities: + - uid: 436 + components: + - type: Transform + pos: 0.5,0.5 + parent: 1 +- proto: SpawnPointXenoborg + entities: + - uid: 438 + components: + - type: Transform + pos: 1.5,-0.5 + parent: 1 + - uid: 439 + components: + - type: Transform + pos: 1.5,1.5 + parent: 1 + - uid: 440 + components: + - type: Transform + pos: -0.5,1.5 + parent: 1 + - uid: 441 + components: + - type: Transform + pos: -0.5,-0.5 + parent: 1 - proto: SubstationBasic entities: - uid: 135 @@ -1846,100 +1877,6 @@ entities: - type: Transform pos: -2.5,5.5 parent: 1 -- proto: Thruster - entities: - - uid: 111 - components: - - type: Transform - pos: -10.5,3.5 - parent: 1 - - uid: 112 - components: - - type: Transform - pos: -9.5,3.5 - parent: 1 - - uid: 113 - components: - - type: Transform - pos: -7.5,3.5 - parent: 1 - - uid: 114 - components: - - type: Transform - pos: -6.5,3.5 - parent: 1 - - uid: 115 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -7.5,-2.5 - parent: 1 - - uid: 116 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -6.5,-2.5 - parent: 1 - - uid: 117 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -10.5,-2.5 - parent: 1 - - uid: 118 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -9.5,-2.5 - parent: 1 - - uid: 119 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -12.5,-0.5 - parent: 1 - - uid: 120 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -12.5,0.5 - parent: 1 - - uid: 121 - components: - - type: Transform - rot: 1.5707963267948966 rad - pos: -12.5,1.5 - parent: 1 - - uid: 122 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 8.5,1.5 - parent: 1 - - uid: 123 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 8.5,0.5 - parent: 1 - - uid: 124 - components: - - type: Transform - rot: -1.5707963267948966 rad - pos: 8.5,-0.5 - parent: 1 - - uid: 125 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,-6.5 - parent: 1 - - uid: 126 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 3.5,-6.5 - parent: 1 - proto: TwoWayLever entities: - uid: 5 @@ -2538,6 +2475,100 @@ entities: rot: -1.5707963267948966 rad pos: 3.5,2.5 parent: 1 +- proto: ThrusterXenoborg + entities: + - uid: 113 + components: + - type: Transform + pos: -7.5,3.5 + parent: 1 + - uid: 114 + components: + - type: Transform + pos: -6.5,3.5 + parent: 1 + - uid: 115 + components: + - type: Transform + pos: -9.5,3.5 + parent: 1 + - uid: 116 + components: + - type: Transform + pos: -10.5,3.5 + parent: 1 + - uid: 117 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -6.5,-2.5 + parent: 1 + - uid: 118 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -7.5,-2.5 + parent: 1 + - uid: 119 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -10.5,-2.5 + parent: 1 + - uid: 120 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -9.5,-2.5 + parent: 1 + - uid: 121 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -12.5,-0.5 + parent: 1 + - uid: 122 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -12.5,0.5 + parent: 1 + - uid: 123 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -12.5,1.5 + parent: 1 + - uid: 124 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 8.5,-0.5 + parent: 1 + - uid: 125 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 8.5,0.5 + parent: 1 + - uid: 126 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 8.5,1.5 + parent: 1 + - uid: 372 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -2.5,-6.5 + parent: 1 + - uid: 373 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 3.5,-6.5 + parent: 1 - proto: XenoborgWindow entities: - uid: 3 diff --git a/Resources/Maps/box.yml b/Resources/Maps/box.yml index 4f2ac605a0..53a8e77654 100644 --- a/Resources/Maps/box.yml +++ b/Resources/Maps/box.yml @@ -4,8 +4,8 @@ meta: engineVersion: 267.3.0 forkId: "" forkVersion: "" - time: 11/04/2025 19:45:51 - entityCount: 28789 + time: 11/07/2025 10:31:27 + entityCount: 28792 maps: - 780 grids: @@ -73729,6 +73729,12 @@ entities: - type: Transform pos: -7.5,23.5 parent: 8364 + - uid: 9086 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: 4.5,14.5 + parent: 8364 - uid: 9439 components: - type: Transform @@ -85142,28 +85148,6 @@ entities: - type: Transform pos: -22.349255,-5.634054 parent: 8364 -- proto: Dresser - entities: - - uid: 5190 - components: - - type: Transform - pos: 4.5,8.5 - parent: 8364 - - uid: 6675 - components: - - type: Transform - pos: 15.5,15.5 - parent: 8364 - - uid: 6676 - components: - - type: Transform - pos: 4.5,5.5 - parent: 8364 - - uid: 6987 - components: - - type: Transform - pos: 20.5,4.5 - parent: 8364 - proto: DresserCaptainFilled entities: - uid: 5341 @@ -85187,11 +85171,41 @@ entities: parent: 8364 - proto: DresserFilled entities: + - uid: 5089 + components: + - type: Transform + pos: 15.5,15.5 + parent: 8364 + - uid: 5190 + components: + - type: Transform + pos: 4.5,8.5 + parent: 8364 + - uid: 6675 + components: + - type: Transform + pos: 4.5,5.5 + parent: 8364 + - uid: 6676 + components: + - type: Transform + pos: 20.5,4.5 + parent: 8364 + - uid: 6987 + components: + - type: Transform + pos: 13.5,15.5 + parent: 8364 - uid: 7329 components: - type: Transform pos: 10.5,30.5 parent: 8364 + - uid: 7852 + components: + - type: Transform + pos: 5.5,15.5 + parent: 8364 - proto: DresserHeadOfPersonnelFilled entities: - uid: 5289 diff --git a/Resources/Maps/exo.yml b/Resources/Maps/exo.yml index 8b893c2b82..af133764a4 100644 --- a/Resources/Maps/exo.yml +++ b/Resources/Maps/exo.yml @@ -4,8 +4,8 @@ meta: engineVersion: 267.3.0 forkId: "" forkVersion: "" - time: 11/01/2025 14:27:42 - entityCount: 20005 + time: 11/06/2025 22:05:46 + entityCount: 20009 maps: - 1 grids: @@ -4653,10 +4653,10 @@ entities: 0: 51711 8,-16: 0: 271 - 4: 17408 + 2: 17408 8,-15: 1: 4096 - 4: 4 + 2: 4 8,-14: 0: 32752 8,-13: @@ -5350,8 +5350,8 @@ entities: 0: 65535 9,-16: 0: 15 - 5: 4352 - 2: 17408 + 3: 4352 + 4: 17408 10,-20: 0: 65280 10,-19: @@ -5362,8 +5362,8 @@ entities: 0: 65535 10,-16: 0: 15 - 2: 4352 - 6: 17408 + 4: 4352 + 5: 17408 11,-20: 0: 65024 11,-19: @@ -5375,7 +5375,7 @@ entities: 11,-16: 0: 15 1: 35840 - 2: 4352 + 4: 4352 12,-20: 0: 65280 12,-19: @@ -5409,7 +5409,7 @@ entities: 0: 61183 12,-16: 0: 7 - 2: 2184 + 4: 2184 1: 8960 13,-20: 0: 65024 @@ -5423,7 +5423,7 @@ entities: 13,-21: 1: 16179 13,-16: - 2: 819 + 4: 819 1: 8 14,-20: 0: 53504 @@ -5623,7 +5623,7 @@ entities: 0: 59392 11,-15: 1: 32904 - 2: 1 + 4: 1 12,-14: 0: 62926 11,-14: @@ -5744,12 +5744,12 @@ entities: 0: 60625 11,-10: 0: 34944 - 3: 13104 + 6: 13104 12,-9: 0: 56784 11,-9: 0: 65416 - 3: 2 + 6: 2 12,-8: 0: 57117 13,-11: @@ -5895,7 +5895,7 @@ entities: 10,-11: 0: 65535 10,-10: - 3: 65520 + 6: 65520 0: 4 10,-13: 0: 12276 @@ -5958,14 +5958,14 @@ entities: 11,-3: 1: 12288 9,-15: - 5: 1 - 2: 4 + 3: 1 + 4: 4 1: 32768 9,-14: 0: 36848 10,-15: - 2: 1 - 6: 4 + 4: 1 + 5: 4 10,-14: 0: 65520 -8,-24: @@ -6050,14 +6050,6 @@ entities: - volume: 2500 immutable: True moles: {} - - volume: 2500 - temperature: 293.15 - moles: {} - - volume: 2500 - temperature: 235 - moles: - Oxygen: 27.225372 - Nitrogen: 102.419266 - volume: 2500 temperature: 293.15 moles: @@ -6066,10 +6058,18 @@ entities: temperature: 293.15 moles: Nitrogen: 6666.982 + - volume: 2500 + temperature: 293.15 + moles: {} - volume: 2500 temperature: 293.15 moles: Plasma: 6666.982 + - volume: 2500 + temperature: 235 + moles: + Oxygen: 27.225372 + Nitrogen: 102.419266 chunkSize: 4 - type: GasTileOverlay - type: RadiationGridResistance @@ -10102,7 +10102,7 @@ entities: pos: 11.5,-30.5 parent: 2 - type: Door - secondsUntilStateChange: -254267.98 + secondsUntilStateChange: -254680.28 state: Opening - type: DeviceLinkSource lastSignals: @@ -10458,7 +10458,7 @@ entities: pos: 34.5,-36.5 parent: 2 - type: Door - secondsUntilStateChange: -29765.682 + secondsUntilStateChange: -30177.973 state: Opening - type: DeviceLinkSource lastSignals: @@ -48732,6 +48732,11 @@ entities: rot: -1.5707963267948966 rad pos: 27.5,-24.5 parent: 2 + - uid: 14215 + components: + - type: Transform + pos: 27.5,-23.5 + parent: 2 - uid: 15507 components: - type: Transform @@ -49779,12 +49784,6 @@ entities: rot: 3.141592653589793 rad pos: 27.5,-22.5 parent: 2 - - uid: 14215 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 27.5,-23.5 - parent: 2 - uid: 14451 components: - type: Transform @@ -52991,6 +52990,30 @@ entities: rot: 1.5707963267948966 rad pos: 26.5,-66.5 parent: 2 + - uid: 18997 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 23.5,-23.5 + parent: 2 + - uid: 19000 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 24.5,-23.5 + parent: 2 + - uid: 19001 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 25.5,-23.5 + parent: 2 + - uid: 19002 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 26.5,-23.5 + parent: 2 - uid: 19453 components: - type: Transform diff --git a/Resources/Maps/marathon.yml b/Resources/Maps/marathon.yml index b2d20a2df1..4d60e79763 100644 --- a/Resources/Maps/marathon.yml +++ b/Resources/Maps/marathon.yml @@ -4,8 +4,8 @@ meta: engineVersion: 267.3.0 forkId: "" forkVersion: "" - time: 11/04/2025 19:49:34 - entityCount: 23872 + time: 11/07/2025 10:28:48 + entityCount: 23873 maps: - 5350 grids: @@ -64780,38 +64780,6 @@ entities: - type: Transform pos: 49.502296,31.49661 parent: 30 -- proto: Dresser - entities: - - uid: 655 - components: - - type: Transform - pos: 3.5,15.5 - parent: 30 - - uid: 6427 - components: - - type: Transform - pos: 16.5,39.5 - parent: 30 - - uid: 17643 - components: - - type: Transform - pos: -78.5,-49.5 - parent: 30 - - uid: 17946 - components: - - type: Transform - pos: -52.5,-51.5 - parent: 30 - - uid: 17947 - components: - - type: Transform - pos: -52.5,-55.5 - parent: 30 - - uid: 21299 - components: - - type: Transform - pos: -29.5,-45.5 - parent: 30 - proto: DresserCaptainFilled entities: - uid: 4989 @@ -64835,11 +64803,46 @@ entities: parent: 30 - proto: DresserFilled entities: + - uid: 655 + components: + - type: Transform + pos: 3.5,15.5 + parent: 30 + - uid: 2001 + components: + - type: Transform + pos: 16.5,39.5 + parent: 30 + - uid: 6427 + components: + - type: Transform + pos: -78.5,-49.5 + parent: 30 - uid: 9968 components: - type: Transform pos: -10.5,-22.5 parent: 30 + - uid: 17643 + components: + - type: Transform + pos: -52.5,-51.5 + parent: 30 + - uid: 17946 + components: + - type: Transform + pos: -52.5,-55.5 + parent: 30 + - uid: 17947 + components: + - type: Transform + pos: -29.5,-45.5 + parent: 30 + - uid: 21299 + components: + - type: Transform + pos: 18.5,34.5 + parent: 30 - proto: DresserHeadOfPersonnelFilled entities: - uid: 5715 diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_cargo.yml b/Resources/Prototypes/Catalog/Cargo/cargo_cargo.yml index 050aa647b8..132f1b3c09 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_cargo.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_cargo.yml @@ -37,3 +37,13 @@ cost: 2500 category: cargoproduct-category-name-cargo group: market + +- type: cargoProduct + id: CargoMailCart + icon: + sprite: Objects/Specific/Cargo/mailcart.rsi + state: icon + product: MailCart + cost: 300 + category: cargoproduct-category-name-cargo + group: market diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 5a0f806c98..d51793772e 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -2,23 +2,27 @@ id: AllPlushiesTable table: !type:GroupSelector children: - - id: PlushieBee - - id: PlushieNar - weight: 0.5 - - id: PlushieRatvar - weight: 0.5 + - !type:NestedSelector + tableId: AllLizardPlushieTable - id: PlushieNuke - id: PlushieSlime - id: PlushieSnake - id: PlushieExperiment + - id: PlushieVox + - id: PlushieRouny + - id: PlushieAtmosian + - id: PlushieDiona + - id: PlushieXeno + - id: PlushieHampter + - id: PlushieMoth + - id: PlushieArachind + - id: PlushiePenguin + - id: PlushieVulp - !type:GroupSelector children: - - id: PlushieLizard - weight: 9 - - id: PlushieSpaceLizard - weight: 1 - - id: PlushieLizardInversed - weight: 0.5 + - id: PlushieBee + - id: PlushieRGBee + weight: 0.1 - !type:GroupSelector children: - id: PlushieCarp @@ -28,21 +32,84 @@ weight: 0.25 - id: PlushieRainbowCarp weight: 0.15 - - id: PlushieVox - - id: PlushieRouny - !type:GroupSelector children: - id: PlushieSharkBlue - id: PlushieSharkGrey - id: PlushieSharkPink - - id: PlushieAtmosian - - id: PlushieDiona - - id: PlushieXeno - - id: PlushieHampter - - id: PlushieMoth - - id: PlushieArachind - - id: PlushiePenguin - - id: PlushieVulp + - !type:GroupSelector # Toy plushies + children: + - id: ToyIan + - id: ToyAmongPequeno + - id: ToyMouse + - !type:GroupSelector # Giant plushies + children: + - id: PlushieNar + - id: PlushieRatvar + - !type:GroupSelector # Rare plushies + weight: 0.1 # 1 in >210 + children: + - id: PlushieHuman + - id: PlushieGhost + - id: PlushieLamp + - !type:GroupSelector # Legendary plushies + weight: 0.002 # 1 in >10,500 + children: + - id: PlushieThrongler + - id: PlushieGhostRevenant # You got the god roll, and failed + +- type: entityTable + id: AllLizardPlushieTable + table: !type:GroupSelector + children: + - id: PlushieLizard + weight: 8 + - id: PlushieSpaceLizard + weight: 1 + - id: PlushieLizardInversed + weight: 0.1 # 1 in >100 + - !type:GroupSelector # Lizard gets a job table + children: + - id: PlushieLizardJobAtmospherictechnician + - id: PlushieLizardJobBartender + - id: PlushieLizardJobBotanist + - id: PlushieLizardJobBoxer + - id: PlushieLizardJobCaptain + - id: PlushieLizardJobCargotechnician + - id: PlushieLizardJobChaplain + - id: PlushieLizardJobChef + - id: PlushieLizardJobChemist + - id: PlushieLizardJobChiefengineer + - id: PlushieLizardJobChiefmedicalofficer + - id: PlushieLizardJobClown # :o) + - id: PlushieLizardJobDetective + - id: PlushieLizardJobHeadofpersonnel + - id: PlushieLizardJobHeadofsecurity + - id: PlushieLizardJobJanitor + - id: PlushieLizardJobLawyer + - id: PlushieLizardJobLibrarian + - id: PlushieLizardJobMedicaldoctor + - id: PlushieLizardJobMedicalintern + - id: PlushieLizardJobMime # + - id: PlushieLizardJobMusician + - id: PlushieLizardJobParamedic + - id: PlushieLizardJobPassenger + - id: PlushieLizardJobPsychologist + - id: PlushieLizardJobQuartermaster + - id: PlushieLizardJobReporter + - id: PlushieLizardJobResearchassistant + - id: PlushieLizardJobResearchdirector + - id: PlushieLizardJobSalvagespecialist + - id: PlushieLizardJobScientist + - id: PlushieLizardJobSecuritycadet + - id: PlushieLizardJobSecurityofficer + - id: PlushieLizardJobServiceworker + - id: PlushieLizardJobStationengineer + - id: PlushieLizardJobTechnicalassistant + - id: PlushieLizardJobZookeeper + - id: PlushieLizardJobMultiweh + weight: 0.5 # 1 in >800 + - type: entityTable id: AllPottedPlantsTable @@ -108,16 +175,10 @@ components: - type: EntityTableContainerFill containers: - entity_storage: !type:AllSelector - children: - - id: PlushieLizard - amount: !type:ConstantNumberSelector - value: 3 - - id: PlushieSpaceLizard - amount: !type:ConstantNumberSelector - value: 3 - - id: PlushieLizardJobMultiweh # the exceedingly rare multiweh! - prob: 0.01 + entity_storage: !type:NestedSelector + tableId: AllLizardPlushieTable + rolls: !type:ConstantNumberSelector + value: 6 - type: entity id: CrateFunSharkPlushieBulk diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml index e111b51cff..34dafcba20 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml @@ -63,6 +63,7 @@ contents: - id: ClothingHeadHatBeretHoS - id: ClothingHeadHatHoshat + - id: ClothingMaskNeckGaiter - id: ClothingUniformJumpskirtHoSAlt - id: ClothingUniformJumpsuitHoSAlt - id: ClothingUniformJumpskirtHosFormal diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index e989092747..ed8eda4657 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -212,10 +212,8 @@ children: - id: BoxEncryptionKeyMedical - id: ClothingBackpackDuffelSurgeryFilled - - id: ClothingCloakCmo - id: ClothingEyesHudMedical - id: ClothingHandsGlovesNitrile - - id: ClothingHeadHatBeretCmo - id: ClothingHeadsetAltMedical - id: ClothingMaskSterile - id: DoorRemoteMedical @@ -323,7 +321,6 @@ - id: ClothingBeltSecurityFilled - id: ClothingEyesGlassesSecurity - id: ClothingHeadsetAltSecurity - - id: ClothingMaskNeckGaiter - id: ClothingOuterCoatHoSTrench - id: ClothingShoesBootsJack - id: FlashlightSeclite diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 571c167ee5..2f643d9c31 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -80,6 +80,22 @@ categories: - UplinkWeaponry +- type: listing + id: UplinkEnergyCrossbow + name: uplink-energycrossbow-name + description: uplink-energycrossbow-desc + discountCategory: rareDiscounts + discountDownTo: + Telecrystal: 3 + productEntity: WeaponEnergyCrossbow + cost: + Telecrystal: 5 + categories: + - UplinkWeaponry + conditions: + - !type:ListingLimitedStockCondition + stock: 1 + - type: listing id: UplinkThrowingKnivesKit name: uplink-knives-kit-name @@ -783,7 +799,7 @@ Telecrystal: 1 categories: - UplinkDeception - + - type: listing id: UplinkAgentIDCard name: uplink-agent-id-card-name @@ -2302,3 +2318,20 @@ - !type:BuyerJobCondition whitelist: - MedicalDoctor + +- type: listing + id: uplinkBriefcaseGun + name: uplink-briefcase-gun-name + description: uplink-briefcase-gun-desc + productEntity: WeaponSubMachineGunBriefcase + discountCategory: veryRareDiscounts + discountDownTo: + Telecrystal: 10 + cost: + Telecrystal: 15 + categories: + - UplinkJob + conditions: + - !type:BuyerJobCondition + whitelist: + - Lawyer diff --git a/Resources/Prototypes/Corvax/Loadouts/role_loadouts.yml b/Resources/Prototypes/Corvax/Loadouts/role_loadouts.yml index 095256b9f4..80bed2d10b 100644 --- a/Resources/Prototypes/Corvax/Loadouts/role_loadouts.yml +++ b/Resources/Prototypes/Corvax/Loadouts/role_loadouts.yml @@ -84,7 +84,6 @@ - SeniorOfficerBelt - SurvivalSecurity - Trinkets - - SecurityStar - GroupSpeciesBreathToolSecurity # Medical diff --git a/Resources/Prototypes/Entities/Clothing/Back/specific.yml b/Resources/Prototypes/Entities/Clothing/Back/specific.yml index 54b8f677b8..488c02e608 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/specific.yml @@ -122,3 +122,34 @@ location: Middle extra_hand_2: location: Middle + +- type: entity + parent: ClothingBackpack + id: XenoborgMaterialBag + name: silicon storage square + description: A knockoff version of a bluespace bag, can vacumn up select materials, unfit for use by humanoids due to harmful emissions. + components: + - type: Sprite + sprite: Objects/Specific/Robotics/silicon_storage_cube.rsi + state: xenoborg + - type: MagnetPickup + - type: Dumpable + - type: Storage + grid: + - 0,0,7,3 + quickInsert: true + areaInsert: true + whitelist: + tags: + - Sheet + - ConstructionMaterial + - RawMaterial + - Ingot + components: + - ConstructionMaterial + - Circuitboard + - Flatpack + - FloorTile + blacklist: + components: + - SiliconLawProvider diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 53772f6215..3b85ce94c9 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -247,7 +247,6 @@ maxCharge: 600 #lights drain 3/s but recharge of 2 makes this 1/s. Therefore 600 is 10 minutes of light. startingCharge: 600 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 2 #recharge of 2 makes total drain 1w / s so max charge is 1:1 with time. Time to fully charge should be 5 minutes. Having recharge gives light an extended flicker period which gives you some warning to return to light area. - type: entity diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index c2b1c5abbd..431c2978b1 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -563,6 +563,8 @@ - state: icon-nobeard map: [ "foldedLayer" ] visible: true + - type: Item + storedRotation: 0 - type: Tag tags: - PetWearable @@ -1227,6 +1229,8 @@ sprite: Clothing/Head/Hats/party_red.rsi - type: Clothing sprite: Clothing/Head/Hats/party_red.rsi + - type: Item + storedRotation: 0 - type: Tag tags: - PetWearable @@ -1243,12 +1247,6 @@ sprite: Clothing/Head/Hats/party_yellow.rsi - type: Clothing sprite: Clothing/Head/Hats/party_yellow.rsi - - type: Tag - tags: - - PetWearable - - CorgiWearable - - WhitelistChameleon - - HamsterWearable - type: entity parent: ClothingHeadHatPartyRed @@ -1259,12 +1257,6 @@ sprite: Clothing/Head/Hats/party_green.rsi - type: Clothing sprite: Clothing/Head/Hats/party_green.rsi - - type: Tag - tags: - - PetWearable - - CorgiWearable - - WhitelistChameleon - - HamsterWearable - type: entity parent: ClothingHeadHatPartyRed @@ -1275,12 +1267,6 @@ sprite: Clothing/Head/Hats/party_blue.rsi - type: Clothing sprite: Clothing/Head/Hats/party_blue.rsi - - type: Tag - tags: - - PetWearable - - CorgiWearable - - WhitelistChameleon - - HamsterWearable - type: entity parent: ClothingHeadHatPartyRed diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index bfa54eaf77..574e76d9ba 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -221,6 +221,8 @@ sprite: Clothing/Head/Helmets/templar.rsi - type: Clothing sprite: Clothing/Head/Helmets/templar.rsi + - type: Item + storedRotation: 0 - type: IngestionBlocker - type: IdentityBlocker - type: HideLayerClothing @@ -518,7 +520,7 @@ - type: PointLight enabled: false radius: 1.4 - energy: 1.4 + energy: 2.5 color: red netsync: false mask: /Textures/Effects/LightMasks/double_cone.png diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 511f1e1980..332efb731b 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -121,6 +121,8 @@ sprite: Clothing/Head/Misc/richard.rsi - type: Clothing sprite: Clothing/Head/Misc/richard.rsi + - type: Item + storedRotation: 0 - type: IngestionBlocker - type: IdentityBlocker - type: HideLayerClothing diff --git a/Resources/Prototypes/Entities/Clothing/Neck/stoles.yml b/Resources/Prototypes/Entities/Clothing/Neck/stoles.yml index aab8eb30ca..d708a48f7d 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/stoles.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/stoles.yml @@ -8,3 +8,5 @@ sprite: Clothing/Neck/Stoles/chaplain.rsi - type: Clothing sprite: Clothing/Neck/Stoles/chaplain.rsi + - type: Item + storedRotation: 90 diff --git a/Resources/Prototypes/Entities/Clothing/Neck/ties.yml b/Resources/Prototypes/Entities/Clothing/Neck/ties.yml index bf1772dc81..2e172ae285 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/ties.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/ties.yml @@ -1,5 +1,13 @@ - type: entity parent: ClothingNeckBase + id: ClothingNeckTieBase + abstract: true + components: + - type: Item + storedRotation: -45 + +- type: entity + parent: ClothingNeckTieBase id: ClothingNeckTieRed name: red-tie description: A neosilk clip-on red tie. @@ -16,7 +24,7 @@ - Recyclable - type: entity - parent: ClothingNeckBase + parent: ClothingNeckTieBase id: ClothingNeckTieDet name: detective's tie description: A loosely tied necktie, a perfect accessory for the over-worked detective. @@ -27,7 +35,7 @@ sprite: Clothing/Neck/Ties/dettie.rsi - type: entity - parent: ClothingNeckBase + parent: ClothingNeckTieBase id: ClothingNeckTieSci name: scientist's tie description: Why do we all have to wear these ridiculous ties? diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 5cc78d90b0..341404af2b 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -300,7 +300,6 @@ maxCharge: 600 startingCharge: 600 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 2 - type: Item size: Normal diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml b/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml new file mode 100644 index 0000000000..a8251739ac --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/Spawners/Conditional/xenoborgs.yml @@ -0,0 +1,40 @@ +- type: entity + id: SpawnPointXenoborg + parent: MarkerBase + name: xenoborgs + components: + - type: GridSpawnPointWhitelist + whitelist: + components: + - Xenoborg + tags: + - XenoborgGhostrole + blacklist: + components: + - MothershipCore + tags: + - MothershipCoreGhostrole + - type: SpawnPoint + - type: Sprite + layers: + - state: green + - sprite: Mobs/Silicon/chassis.rsi + state: xenoborg_heavy + +- type: entity + id: SpawnPointMothershipCore + parent: MarkerBase + name: mothership core + components: + - type: GridSpawnPointWhitelist + whitelist: + components: + - MothershipCore + tags: + - MothershipCoreGhostrole + - type: SpawnPoint + - type: Sprite + layers: + - state: green + - sprite: Mobs/Silicon/mothership_core.rsi + state: core-idle diff --git a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml index ae0f8ce130..f2e4bb002c 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml @@ -247,6 +247,50 @@ - sprite: Mobs/Silicon/chassis.rsi state: derelict_icon +- type: entity + categories: [ Spawner ] + parent: BaseAntagSpawner + id: SpawnPointGhostRoleMothershipCore + components: + - type: Tag + tags: + - ForceFixRotations + - MothershipCoreGhostrole + - type: GhostRole + name: ghost-role-information-mothership-core-name + description: ghost-role-information-mothership-core-desc + rules: ghost-role-information-silicon-rules + mindRoles: + - MindRoleMothershipCore + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: Mobs/Silicon/mothership_core.rsi + state: core-idle + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: BaseAntagSpawner + id: SpawnPointGhostRoleXenoborg + components: + - type: Tag + tags: + - ForceFixRotations + - XenoborgGhostrole + - type: GhostRole + name: ghost-role-information-xenoborg-name + description: ghost-role-information-xenoborg-desc + rules: ghost-role-information-silicon-rules + mindRoles: + - MindRoleXenoborg + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: Mobs/Silicon/chassis.rsi + state: xenoborg_engi + - type: entity categories: [ HideSpawnMenu, Spawner ] parent: SpawnPointGhostDerelictCyborg diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index e78c139fd8..61dceed677 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -452,7 +452,6 @@ stunTime: 5 - type: SiliconLawProvider laws: XenoborgLawset # custom laws here - subverted: true - type: IntrinsicRadioTransmitter # can only use binary and xenoborg channel channels: - Xenoborg @@ -517,6 +516,11 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + PinpointerMothership: # drop a pinpointer to the mothership upon being destructed + min: 1 + max: 1 - !type:EmptyContainersBehaviour containers: - borg_brain @@ -530,7 +534,7 @@ guides: - Cyborgs - Robotics - # TODO: add Xenoborg guide (part 7 spoilers) + - Xenoborgs - type: Access enabled: false tags: @@ -541,3 +545,4 @@ - type: InteractionPopup interactSuccessSound: path: /Audio/Ambience/Objects/periodic_beep.ogg + - type: Xenoborg diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml index 556b6ac4c4..80f1cb8368 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml @@ -117,9 +117,15 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + PinpointerMothership: # drop a pinpointer to the mothership upon being destructed + min: 1 + max: 1 - !type:EmptyContainersBehaviour containers: - borg_brain + - borg_module - cell_slot - !type:DoActsBehavior acts: [ "Destruction" ] @@ -166,6 +172,7 @@ - type: FootstepModifier # it flies instead of walking footstepSoundCollection: collection: FootstepHoverXenoborg + - type: MovementAlwaysTouching # it flies in space with tiny thrusters - type: FlashImmunity - type: BorgChassis maxModules: 4 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml index 8229b103e7..65cc71aaa8 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml @@ -26,7 +26,6 @@ maxCharge: 1000 startingCharge: 1000 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 40 - type: Gun fireRate: 0.75 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 95392e9a28..c0ea417663 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -147,7 +147,7 @@ components: - type: PointLight radius: 1.5 - energy: 0.5 + energy: 2 - type: RgbLightController layers: [ 0 ] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml index 7d6c28fc95..949fc76efe 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml @@ -54,7 +54,6 @@ proto: WatcherBolt fireCost: 50 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 50 - type: Battery maxCharge: 1000 @@ -87,8 +86,8 @@ shader: unshaded color: red - type: PointLight - radius: 1.5 - energy: 0.5 + radius: 1 + energy: 3 color: red - type: entity @@ -105,8 +104,8 @@ shader: unshaded color: deepskyblue - type: PointLight - radius: 1.5 - energy: 1 + radius: 1 + energy: 3 color: deepskyblue - type: entity @@ -123,8 +122,8 @@ shader: unshaded color: orangered - type: PointLight - radius: 1.5 - energy: 1 + radius: 1 + energy: 3 color: orangered - type: ProjectileBatteryAmmoProvider proto: WatcherBoltMagmawing @@ -145,7 +144,7 @@ state: unshaded shader: unshaded - type: PointLight - radius: 1.5 - energy: 1 + radius: 1 + energy: 3 - type: RgbLightController layers: [ 1 ] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml index 4717e200dd..1531e348f7 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml @@ -175,7 +175,6 @@ maxCharge: 1000 startingCharge: 1000 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 50 - type: Gun fireRate: 0.3 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml index 64fa4e2292..173c5ad165 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml @@ -51,7 +51,6 @@ proto: RedLightLaser fireCost: 50 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 50 - type: Battery maxCharge: 1000 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 6fab208f0b..b5aa080539 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -61,7 +61,7 @@ Piercing: 8 - type: Body prototype: Rat - requiredLegs: 1 # TODO: More than 1 leg + requiredLegs: 0 # TODO: Make more than 1 leg, set to 0 to avoid sprint speed being reset by the body system - type: Hunger # probably should be prototyped thresholds: Overfed: 200 @@ -255,7 +255,7 @@ Piercing: 3 - type: Body prototype: Rat - requiredLegs: 1 # TODO: More than 1 leg + requiredLegs: 0 # TODO: Make more than 1 leg, set to 0 to avoid sprint speed being reset by the body system - type: Hunger # probably should be prototyped thresholds: Overfed: 200 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml index 4dc0778efb..45c0b46d23 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml @@ -359,7 +359,7 @@ interactFailureString: petting-failure-generic - type: PointLight radius: 1.1 - energy: 1.5 + energy: 2.7 color: "#4faffb" - type: Stealth enabledOnDeath: false diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 2b092ba3f7..df3f79ae0c 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -16,6 +16,7 @@ - SilentStorageUser - PreventAccessLogging - AllowBiomeLoading + - NotGhostnadoWarpable - type: Input context: "aghost" - type: Ghost diff --git a/Resources/Prototypes/Entities/Mobs/Player/clone.yml b/Resources/Prototypes/Entities/Mobs/Player/clone.yml index d05126ef03..456c70417b 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/clone.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/clone.yml @@ -101,6 +101,8 @@ - type: cloningSettings id: ParadoxCloningSettings parent: [BaseClone, Antag] + components: + - Forensics # This is so hugging data is copied to the clone, so you can't hug metagame them # changeling identity copying - type: cloningSettings diff --git a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml index fc15fe0c0b..c66caff638 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/mothershipcore.yml @@ -1,17 +1,17 @@ -- type: startingGear - id: MothershipCoreGear - inhand: - - DoorRemoteXenoborg - - Omnitool - - type: entity - parent: [ BaseControllable, BaseMachinePowered ] + parent: [ BaseControllable, BaseStructure ] id: MothershipCore name: mothership core description: A sentient machine that can produce Xenoborgs. Without this the Xenoborgs are doomed. components: + - type: InputMover # needs this to pilot the mothership + - type: MovementSpeedModifier + baseWalkSpeed : 0 # shouldn't move + baseSprintSpeed : 0 # shouldn't move - type: Appearance - type: WiresVisuals + - type: Damageable + damageContainer: Inorganic - type: Fixtures fixtures: fix1: @@ -22,7 +22,8 @@ mask: - MachineMask layer: - - MachineLayer + - MidImpassable + - LowImpassable - type: Sprite sprite: Mobs/Silicon/mothership_core.rsi layers: @@ -32,6 +33,9 @@ map: ["enum.MaterialStorageVisualLayers.Inserting"] - state: core-o map: ["enum.WiresVisualLayers.MaintenancePanel"] + - state: core-e + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded - type: Machine board: null - type: Lathe @@ -116,8 +120,6 @@ type: LatheBoundUserInterface enum.ResearchClientUiKey.Key: type: ResearchClientBoundUserInterface - - type: Transform - anchored: true - type: Pullable - type: StaticPrice price: 800 @@ -148,35 +150,55 @@ - Mothership - Xenoborg - Binary - - type: XenoborgMothership + - type: Xenoborg + mindRole: MindRoleMothershipCore + briefingText: mothership-welcome + - type: MothershipCore - type: Tag tags: - SiliconEmotes - CanPilot - Structure + - type: GuideHelp + guides: + - Robotics + - Xenoborgs - type: Inventory templateId: borg - - type: Loadout - prototypes: [MothershipCoreGear] - type: NpcFactionMember factions: - Xenoborg - type: Hands - hands: - hand_right1: - location: Right - hand_right2: - location: Right - hand_left1: - location: Left - hand_left2: - location: Left - sortedHands: - - hand_right1 - - hand_right2 - - hand_left1 - - hand_left2 - # - type: Puller # use the conveyor + showInHands: false + disableExplosionRecursion: true + canBeStripped: false + - type: BorgChassis + canOpenSelfUi: true + maxModules: 2 + hasMindState: core-e + noMindState: core-e + moduleWhitelist: + tags: + - MothershipModule + - BorgModuleEngineering + - type: ContainerFill + containers: + borg_module: + - MothershipModule + - BorgModuleAdvancedTool + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot { } + borg_module: !type:Container { } + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMicroreactor + - type: Puller + needsHands: false - type: Eye drawFov: false # - type: StationAiOverlay # removed until is no longer buggy @@ -222,8 +244,8 @@ description: View the Xenoborgs Control Console components: - type: Action - icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-basic-module } - iconOn: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-basic-module } + icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-control-computer } + iconOn: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-control-computer } keywords: [ "Mothership Core", "console", "interface" ] priority: -6 - type: InstantAction @@ -236,8 +258,8 @@ description: View the Xenoborgs Camera Monitor components: - type: Action - icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye-module } - iconOn: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye-module } + icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-camera-computer } + iconOn: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-camera-computer } keywords: [ "Mothership Core", "console", "interface" ] priority: -6 - type: InstantAction diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml index 9f6d57083d..be2d04fea1 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml @@ -1155,7 +1155,7 @@ - type: PointLight color: "#FFFF00" radius: 2 - energy: 1.4 + energy: 2.5 - type: entity name: suppermatter shard @@ -1179,7 +1179,7 @@ - type: PointLight color: "#FFFF00" radius: 1.4 - energy: 1.4 + energy: 2.5 - type: Tag tags: - Slice diff --git a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml index a011460366..9267009b3e 100644 --- a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml +++ b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml @@ -102,6 +102,9 @@ containers: delivery: !type:NestedSelector tableId: PackageDeliveryRewards + - type: Tag + tags: + - PackageDelivery - type: entity parent: BaseDelivery diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml index 87bef747d8..0d8f57edea 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/igniter.yml @@ -7,6 +7,8 @@ - type: Sprite sprite: Objects/Devices/igniter.rsi state: icon + - type: Item + storedRotation: -90 - type: IgnitionSource temperature: 800 - type: IgniteOnTrigger diff --git a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml index 494bda50d1..93f012ce57 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml @@ -1,11 +1,20 @@ - type: entity parent: BaseItem + id: BasePDACartridge + abstract: true + components: + - type: Item + storedRotation: -90 + - type: Sprite + sprite: Objects/Devices/cartridge.rsi + +- type: entity + parent: BasePDACartridge id: NotekeeperCartridge name: notekeeper cartridge description: A program for keeping notes. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-y - type: UIFragment ui: !type:NotekeeperUi @@ -16,15 +25,13 @@ state: book_icon - type: NotekeeperCartridge - - type: entity - parent: BaseItem + parent: BasePDACartridge id: NanoTaskCartridge name: NanoTask cartridge description: A program that allows you to keep a list of tasks to do. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-nav - type: Cartridge programName: nano-task-program-name @@ -36,13 +43,12 @@ - type: NanoTaskCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: NewsReaderCartridge name: news cartridge description: A program for reading news. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-y - type: UIFragment ui: !type:NewsReaderUi @@ -54,13 +60,12 @@ - type: NewsReaderCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: CrewManifestCartridge name: crew manifest cartridge description: A program for listing your fellow crewmembers. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-y - type: UIFragment ui: !type:CrewManifestUi @@ -72,13 +77,12 @@ - type: CrewManifestCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: NetProbeCartridge name: NetProbe cartridge description: A program for getting the address and frequency of network devices. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-y - type: UIFragment ui: !type:NetProbeUi @@ -90,13 +94,12 @@ - type: NetProbeCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: LogProbeCartridge name: LogProbe cartridge description: A program for getting access logs from devices. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-log - type: Icon sprite: Objects/Devices/cartridge.rsi @@ -114,13 +117,12 @@ - Forensics - type: entity - parent: BaseItem + parent: BasePDACartridge id: WantedListCartridge name: Wanted list cartridge description: A program to get a list of wanted persons. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-sec - type: Icon sprite: Objects/Devices/cartridge.rsi @@ -137,13 +139,12 @@ stealGroup: WantedListCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: MedTekCartridge name: MedTek cartridge description: A program that provides medical diagnostic tools. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-med - type: Icon sprite: Objects/Devices/cartridge.rsi @@ -156,13 +157,12 @@ - type: MedTekCartridge - type: entity - parent: BaseItem + parent: BasePDACartridge id: AstroNavCartridge name: AstroNav cartridge description: A program for navigation that provides GPS coordinates. components: - type: Sprite - sprite: Objects/Devices/cartridge.rsi state: cart-nav - type: Icon sprite: Objects/Devices/cartridge.rsi diff --git a/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml b/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml index c85358663e..e6ab450c93 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml @@ -196,5 +196,5 @@ - type: Icon state: pinpointer-station - type: Pinpointer - component: XenoborgMothership + component: MothershipCore targetName: the Mothership diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml index c6ba706d06..9d63aa0c69 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_misc.yml @@ -57,6 +57,7 @@ program: 124 - type: Item size: Small + storedRotation: -90 - type: Prayable sentMessage: prayer-popup-notify-centcom-sent notificationPrefix: prayer-chat-notify-centcom diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml index e073f40942..adff2cf014 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_percussion.yml @@ -61,6 +61,7 @@ sprite: Objects/Fun/Instruments/microphone.rsi - type: Item size: Small + storedRotation: -45 - type: entity parent: BasePercussionInstrument diff --git a/Resources/Prototypes/Entities/Objects/Fun/plushies.yml b/Resources/Prototypes/Entities/Objects/Fun/plushies.yml index 2e9f231e90..a22d26c6f7 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/plushies.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/plushies.yml @@ -1,3 +1,5 @@ +# When adding new plushies, also add them to id: AllPlushiesTable + ## Plushies - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index d6d989680a..0d1e7ba019 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -280,14 +280,14 @@ availableModes: - SemiAuto soundGunshot: - path: /Audio/Weapons/click.ogg + path: /Audio/Weapons/Guns/Gunshots/energycrossbow_shoot.ogg - type: BallisticAmmoProvider whitelist: tags: - BulletFoam capacity: 1 soundInsert: - path: /Audio/Items/bow_pull.ogg + path: /Audio/Weapons/Guns/MagIn/energycrossbow_reload.ogg - type: ContainerContainer containers: ballistic-ammo: !type:Container @@ -533,7 +533,6 @@ parent: BeachBall id: EvilBeachBall suffix: evil - name: beach ball description: Someone's drawn ">:3c" on the side of this beach ball in indelible ink. components: - type: LaunchOnTrigger diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index 4b7477eed3..6d5bd964be 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -335,7 +335,7 @@ - HEAD - type: PointLight radius: 1.2 - energy: 1.5 + energy: 2.7 color: "#4faffb" slots: diff --git a/Resources/Prototypes/Entities/Objects/Misc/brb_sign.yml b/Resources/Prototypes/Entities/Objects/Misc/brb_sign.yml index 845130d332..8e7943ce47 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/brb_sign.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/brb_sign.yml @@ -12,3 +12,5 @@ quickEquip: false slots: - Neck + - type: Item + storedRotation: -90 diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml index b4c403c213..2ecf7be55d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml @@ -923,23 +923,14 @@ #Antags - type: entity - name: passenger ID card - parent: [IDCardStandard, BaseChameleon] + parent: [PassengerIDCard, BaseChameleon] id: AgentIDCard suffix: Agent components: - - type: PresetIdCard - job: Passenger - type: Access tags: - Maintenance - SyndicateAgent - - type: Sprite - layers: - - state: default - - sprite: *icon-rsi - offset: *icon-offset - state: Passenger - type: AgentIDCard - type: UIRequiresLock - type: ActivatableUI @@ -960,7 +951,6 @@ type: ChameleonBoundUserInterface - type: entity - name: passenger ID card parent: AgentIDCard id: NukieAgentIDCard suffix: Nukie diff --git a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml index abf4e0974a..12c6e1f4fe 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/improvised_gun_parts.yml @@ -6,8 +6,9 @@ name: modular receiver description: A vital part used in the creation of firearms. #Could use a better description, but I'm not a gun nut so I can't really do that. components: -# - type: Item -# size: Normal + - type: Item + storedRotation: -90 + # size: Normal - type: Sprite sprite: Objects/Misc/modular_receiver.rsi state: icon @@ -22,8 +23,9 @@ name: rifle stock description: A robust wooden stock, used in the creation of firearms. #Same as above components: -# - type: Item -# size: Normal + - type: Item + storedRotation: -90 + # size: Normal - type: Sprite sprite: Objects/Misc/rifle_stock.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index e4651a5875..4ce96419bf 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -98,9 +98,7 @@ description: A self rechargeable power cell, designed for fast recharge rate at the expense of capacity. components: - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 36 # 10 seconds to recharge - autoRechargePause: true autoRechargePauseTime: 30 - type: entity @@ -226,7 +224,6 @@ maxCharge: 720 startingCharge: 720 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 12 # takes 1 minute to charge itself back to full - type: entity @@ -262,7 +259,6 @@ maxCharge: 1200 startingCharge: 1200 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 40 # Power cage (big heavy power cell for big devices) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml index d152bb908e..e37c1a8816 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml @@ -19,6 +19,7 @@ Slash: 6 - type: Item sprite: Objects/Tools/Hydroponics/hoe.rsi + storedRotation: -135 - type: PhysicalComposition materialComposition: Steel: 100 @@ -97,6 +98,7 @@ Piercing: 2 - type: Item sprite: Objects/Tools/Hydroponics/hatchet.rsi + storedRotation: -135 - type: PhysicalComposition materialComposition: Steel: 100 @@ -123,6 +125,7 @@ collection: MetalThud - type: Item sprite: Objects/Tools/Hydroponics/spade.rsi + storedRotation: -45 - type: Shovel speedModifier: 0.75 # slower at digging than a full-sized shovel - type: PhysicalComposition diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index a4280f6a50..5aba5b7918 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -37,6 +37,7 @@ - type: Item size: Large sprite: Objects/Specific/Janitorial/mop.rsi + storedRotation: 45 - type: Absorbent useAbsorberSolution: true - type: SolutionContainerManager @@ -58,7 +59,7 @@ - type: DnaSubstanceTrace - type: entity - parent: BaseItem + parent: MopItem name: advanced mop id: AdvMopItem description: Motorized mop that has a bigger reservoir and quickly replaces reagents inside with water. Automatic Clown Countermeasure not included. @@ -70,37 +71,12 @@ - map: ["enum.SolutionContainerLayers.Fill"] state: fill-2 visible: false - - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 2 - fillBaseName: fill- - inHandsFillBaseName: -fill- - inHandsMaxFillLevels: 2 - - type: MeleeWeapon - damage: - types: - Blunt: 10 - soundHit: - collection: MetalThud - - type: Spillable - solution: absorbed - spillWhenThrown: false - preventMelee: false - - type: DrainableSolution - solution: absorbed - - type: Wieldable - - type: IncreaseDamageOnWield - damage: - types: - Blunt: 5 - type: Item - size: Large sprite: Objects/Specific/Janitorial/advmop.rsi - type: Absorbent pickupAmount: 100 - useAbsorberSolution: true - - type: UseDelay - delay: 1.0 - type: SolutionRegeneration solution: absorbed generated: @@ -112,15 +88,10 @@ preserve: - Water quantity: 10 - - type: SolutionContainerManager - solutions: - absorbed: - maxVol: 100 - type: Tag tags: - Mop - MopAdv - - type: DnaSubstanceTrace - type: entity name: wet floor sign diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 0f0d8ae0c2..aedbd3190c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -27,6 +27,7 @@ state: ointment - type: Item heldPrefix: ointment + storedRotation: 45 - type: Healing damageContainers: - Biological @@ -295,6 +296,7 @@ state: gauze - type: Item heldPrefix: gauze + storedRotation: -90 - type: Construction graph: Gauze node: gauze diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index 17909d6769..7137cbaa64 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -649,10 +649,8 @@ price: 1500 - type: entity - name: pen suffix: Hypopen parent: Pen # It is just like normal pen, isn't it? - description: A dark ink pen. id: Hypopen components: - type: SolutionContainerManager diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 9cc47d5b10..5c01137543 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -27,6 +27,8 @@ - type: Sprite sprite: Objects/Specific/Robotics/borgmodule.rsi - type: BorgModule + borgFitTypes: + - borg-type-all - type: BorgModuleIcon icon: { sprite: Interface/Actions/actions_borg.rsi, state: no-action } - type: StaticPrice @@ -66,6 +68,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-salvage - type: Tag tags: - BorgModuleCargo @@ -91,6 +96,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-engineer - type: Tag tags: - BorgModuleEngineering @@ -118,6 +126,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-janitor - type: Tag tags: - BorgModuleJanitor @@ -145,6 +156,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-medical - type: Tag tags: - BorgModuleMedical @@ -172,6 +186,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-generic - type: Tag tags: - BorgModuleScience @@ -199,6 +216,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-service - type: Tag tags: - BorgModuleService @@ -226,6 +246,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-syndicate - type: Tag tags: - BorgModuleSyndicate @@ -254,6 +277,9 @@ parent: BaseBorgModule abstract: true components: + - type: BorgModule + borgFitTypes: + - borg-type-syndicate-assault - type: Tag tags: - BorgModuleSyndicateAssault @@ -281,6 +307,9 @@ parent: BaseBorgModule id: BaseXenoborgModuleGeneric components: + - type: BorgModule + borgFitTypes: + - xenoborg-type-all - type: Tag tags: - XenoborgModuleGeneric @@ -308,6 +337,9 @@ parent: BaseBorgModule id: BaseXenoborgModuleEngi components: + - type: BorgModule + borgFitTypes: + - xenoborg-type-engi - type: Tag tags: - XenoborgModuleEngi @@ -335,6 +367,9 @@ id: BaseXenoborgModuleHeavy abstract: true components: + - type: BorgModule + borgFitTypes: + - xenoborg-type-heavy - type: Tag tags: - XenoborgModuleHeavy @@ -362,6 +397,9 @@ id: BaseXenoborgModuleScout abstract: true components: + - type: BorgModule + borgFitTypes: + - xenoborg-type-scout - type: Tag tags: - XenoborgModuleScout @@ -389,6 +427,9 @@ id: BaseXenoborgModuleStealth abstract: true components: + - type: BorgModule + borgFitTypes: + - xenoborg-type-stealth - type: Tag tags: - XenoborgModuleStealth @@ -1341,6 +1382,51 @@ - type: StaticPrice price: 2000 +# mothership module +- type: entity + parent: [ BaseXenoborgModuleGeneric, BaseProviderBorgModule, BaseXenoborgContraband ] + id: MothershipModule + name: mothership module + description: A module that helps the mothership borg brains and install other modules. + components: + - type: Tag + tags: + - MothershipModule + - type: Sprite + layers: + - state: xenoborg_generic + - state: icon-xenoborg-basic + - type: ItemBorgModule + hands: + - item: DoorRemoteXenoborg + - hand: + emptyRepresentative: MMIFilled + emptyLabel: borg-slot-brains-empty + whitelist: + components: + - Brain + - BorgBrain + - hand: + emptyRepresentative: XenoborgModuleBasic + emptyLabel: borg-slot-modules-empty + whitelist: + components: + - BorgModule + - hand: + emptyRepresentative: BorgModuleConstructionMaterialPlaceholder + emptyLabel: borg-slot-construction-empty + whitelist: + tags: + - ConstructionMaterial + - hand: + emptyRepresentative: PowerCellHigh + emptyLabel: borg-slot-powercell-empty + whitelist: + components: + - PowerCell + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-module-module } + # xenoborg modules - type: entity parent: [ BaseXenoborgModuleGeneric, BaseProviderBorgModule, BaseXenoborgContraband ] @@ -1354,7 +1440,13 @@ - state: icon-xenoborg-basic - type: ItemBorgModule hands: - - item: MaterialBag + - hand: + emptyRepresentative: BorgModuleConstructionMaterialPlaceholder + emptyLabel: borg-slot-construction-empty + whitelist: + tags: + - ConstructionMaterial + - item: XenoborgMaterialBag - item: PinpointerMothership - item: HandheldGPSBasic - type: BorgModuleIcon @@ -1475,6 +1567,7 @@ hands: - item: HandheldGPSBasic - item: HandHeldMassScannerBorg + - item: PinpointerMothership - item: HandheldStationMapUnpowered - item: WeaponGrapplingGun - item: JetpackXenoborg diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml index f23e0964c1..e3fe3584f8 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/barber.yml @@ -7,6 +7,8 @@ - type: Sprite sprite: Objects/Tools/scissors.rsi state: icon + - type: Item + storedRotation: 135 - type: MagicMirror - type: ActivatableUI key: enum.MagicMirrorUiKey.Key diff --git a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml index cb038b3c5a..eb4b881998 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/gas_tanks.yml @@ -94,6 +94,7 @@ - type: Item size: Small sprite: Objects/Tanks/emergency.rsi + storedRotation: -45 - type: GasTank air: volume: 0.66 diff --git a/Resources/Prototypes/Entities/Objects/Tools/glowstick.yml b/Resources/Prototypes/Entities/Objects/Tools/glowstick.yml index e000b99638..986f65badc 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/glowstick.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/glowstick.yml @@ -29,6 +29,7 @@ - type: Item sprite: Objects/Misc/glowstick.rsi heldPrefix: unlit + storedRotation: -45 - type: Appearance - type: PointLight enabled: false diff --git a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml index 4f55d5c164..953d191d5e 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml @@ -14,6 +14,7 @@ - type: Item sprite: Objects/Misc/inflatable_wall.rsi size: Small + storedRotation: 90 - type: SpawnAfterInteract prototype: InflatableWall doAfter: 1 @@ -41,6 +42,7 @@ - type: Item sprite: Objects/Misc/inflatable_door.rsi size: Small + storedRotation: 90 - type: SpawnAfterInteract prototype: InflatableDoor doAfter: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml index 9320e1627f..f2dffa776b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml @@ -103,6 +103,8 @@ parent: [ BaseItem, BaseSecurityContraband ] description: Unconventional 30-round top feeding magazine for the WT550 SMG. Intended to hold general-purpose kinetic ammunition. components: + - type: Item + storedRotation: 90 - type: Tag tags: - MagazinePistolSubMachineGunTopMounted diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/grenade.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/grenade.yml index 02aab56f7b..822c1fea17 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/grenade.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/grenade.yml @@ -4,9 +4,6 @@ categories: [ HideSpawnMenu ] parent: BaseBullet components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile deleteOnCollide: false damage: @@ -23,9 +20,6 @@ categories: [ HideSpawnMenu ] parent: BaseBullet components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile deleteOnCollide: false damage: @@ -40,9 +34,6 @@ categories: [ HideSpawnMenu ] parent: BaseBulletIncendiary components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot-flare - type: Projectile deleteOnCollide: false damage: @@ -61,9 +52,6 @@ categories: [ HideSpawnMenu ] parent: BaseBullet components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile deleteOnCollide: false damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml index 63d07eb2f2..070ce21171 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml @@ -22,7 +22,9 @@ components: - type: Sprite sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot + layers: + - state: bullet #just reapplying to here so it can be shaded + - type: Projectile damage: types: @@ -36,9 +38,6 @@ categories: [ HideSpawnMenu ] parent: BaseBullet components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile damage: types: @@ -62,9 +61,6 @@ categories: [ HideSpawnMenu ] parent: BaseBulletIncendiary components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot-flare - type: Projectile damage: types: @@ -89,9 +85,6 @@ categories: [ HideSpawnMenu ] parent: BaseBulletPractice components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile damage: types: @@ -115,7 +108,9 @@ components: - type: Sprite sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: shard + layers: + - state: shard + shader: unshaded - type: Projectile damage: types: @@ -138,9 +133,6 @@ categories: [ HideSpawnMenu ] parent: BaseBulletPractice components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - state: buckshot - type: Projectile damage: types: @@ -204,13 +196,8 @@ id: PelletShotgunUranium name: pellet (.50 uranium) categories: [ HideSpawnMenu ] - parent: BaseBullet + parent: BaseBulletUranium components: - - type: Sprite - sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi - layers: - - state: uranium - shader: unshaded - type: Projectile damage: types: @@ -266,7 +253,6 @@ sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi layers: - state: shard - shader: unshaded - type: EmbeddableProjectile deleteOnRemove: true - type: Projectile diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/energy_crossbow.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/energy_crossbow.yml new file mode 100644 index 0000000000..40b7f7adf8 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/energy_crossbow.yml @@ -0,0 +1,49 @@ +- type: entity + abstract: true + parent: BaseItem + id: WeaponEnergyCrossbowBase + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Basic/energy_crossbow.rsi + - type: Item + sprite: Objects/Weapons/Guns/Basic/energy_crossbow.rsi + size: Small + - type: Gun + fireRate: 5 #high firerate innately bottlenecked by ammo regeneration speed. + selectedMode: SemiAuto + minAngle: 0 + maxAngle: 5 + availableModes: + - SemiAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/energycrossbow_shoot.ogg + - type: AmmoCounter + - type: Appearance + - type: GenericVisualizer + visuals: + enum.AmmoVisuals.HasAmmo: + empty-icon: + True: { visible: False } + False: { visible: True } + - type: RechargeBasicEntityAmmo + rechargeCooldown: 5 #2 seconds of KD, should always have CD > KD + rechargeSound: + path: /Audio/Weapons/Guns/MagIn/energycrossbow_reload.ogg + - type: BasicEntityAmmoProvider + proto: EnergyCrossbowBolt + capacity: 1 + count: 1 + +- type: entity + parent: [WeaponEnergyCrossbowBase, BaseSyndicateContraband] + id: WeaponEnergyCrossbow + name: mini energy crossbow + description: Launches renewable toxic arrows capable of flooring targets instantly. + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Basic/energy_crossbow.rsi + state: icon + - type: Item + sprite: Objects/Weapons/Guns/Basic/energy_crossbow.rsi + - type: StaticPrice + price: 2500 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 8e2650b5fe..10181b54e7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -664,7 +664,6 @@ proto: RedMediumLaser fireCost: 100 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 40 - type: MagazineVisuals magState: mag @@ -712,7 +711,6 @@ proto: RedMediumLaser fireCost: 100 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 30 - type: MagazineVisuals magState: mag @@ -808,7 +806,6 @@ proto: RedMediumLaser fireCost: 100 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 40 - type: StaticPrice price: 750 @@ -901,9 +898,7 @@ fireCost: 62.5 pacifismAllowedMode: true - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 48 - autoRechargePause: true autoRechargePauseTime: 10 - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml index 80d71669a7..be57d5f0f9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -124,6 +124,5 @@ maxCharge: 10000 startingCharge: 10000 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 25 - type: AmmoCounter diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml index ec3fa31297..ca40d1940d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml @@ -135,7 +135,6 @@ maxCharge: 1000 startingCharge: 1000 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 25 - type: AmmoCounter diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index bc9f40f85a..132bd267fd 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -178,6 +178,11 @@ sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi layers: - state: uranium + shader: unshaded + # - type: PointLight // Too resource intensive for what little effect it has, one day... + # enabled: true + # color: "#059919" + # radius: 2.0 - type: Projectile damage: types: @@ -1389,3 +1394,44 @@ hard: false mask: - Opaque + +- type: entity + parent: BaseBullet + id: EnergyCrossbowBolt + categories: [ HideSpawnMenu ] + name: energy bolt + description: This'll hurt. + components: + - type: Reflective + reflective: + - NonEnergy + - type: Ammo + muzzleFlash: null + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi + layers: + - state: crossbowbolt + shader: unshaded + - type: Projectile + damage: + types: + Piercing: 2 + - type: StunOnCollide #somewhat mirror to taser stats, meant to be tot 'sidegrade' + stunAmount: 0 + knockdownAmount: 2.5 + slowdownAmount: 2.5 + walkSpeedModifier: 0.2 + sprintSpeedModifier: 0.2 + drop: false + - type: StaminaDamageOnCollide #additional stam damage to make repeated pushups less of a viable counter + damage: 45 + - type: SolutionContainerManager + solutions: + bolt: + maxVol: 1.5 + reagents: + - ReagentId: Toxin + Quantity: 1.5 + - type: SolutionInjectOnProjectileHit + transferAmount: 1.5 + solution: bolt diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index 2ecaaec89e..4ca2e0c0f5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -160,7 +160,6 @@ maxCharge: 3000 startingCharge: 3000 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 25 - type: AmmoCounter @@ -284,3 +283,42 @@ steps: 6 zeroVisible: true - type: Appearance + +- type: entity + name: brown briefcase + parent: [BaseWeaponSubMachineGun] + id: WeaponSubMachineGunBriefcase + description: Useful for carrying items in your hands. + suffix: Gun + components: + - type: Item + size: Ginormous + inhandVisuals: + left: + - sprite: Objects/Storage/Briefcases/briefcase_brown.rsi + state: inhand-left + - state: inhand-left-muzzle + right: + - sprite: Objects/Storage/Briefcases/briefcase_brown.rsi + state: inhand-right + - state: inhand-right-muzzle + - type: Sprite + sprite: Objects/Weapons/Guns/SMGs/briefcase.rsi + layers: + - sprite: Objects/Storage/Briefcases/briefcase_brown.rsi + state: icon + - state: icon-muzzle + map: ["enum.GunVisualLayers.Base"] + - type: Gun + fireRate: 9 + minAngle: 25 + maxAngle: 32 + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/atreides.ogg + - type: ChamberMagazineAmmoProvider + autoEject: false + - type: Appearance + - type: StaticPrice + price: 5000 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml index ec7e4b3e7f..6b8c4eebe1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/pneumatic_cannon.yml @@ -132,7 +132,6 @@ maxCharge: 90 startingCharge: 90 - type: BatterySelfRecharger - autoRecharge: true autoRechargeRate: 1 - type: AmmoCounter - type: Item diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 04b65ddb6b..97ac9e0980 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -153,7 +153,7 @@ - type: PointLight enabled: false radius: 1.5 - energy: 1.5 + energy: 2.7 color: white netsync: false @@ -212,7 +212,7 @@ - type: PointLight enabled: false radius: 1.5 - energy: 1.5 + energy: 2.7 color: white netsync: false - type: MeleeWeapon diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml new file mode 100644 index 0000000000..8f2f7547c0 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml @@ -0,0 +1,87 @@ +- type: entity # Starts fuse after taking 10 damage. + parent: BaseItem + abstract: true + id: GrenadeBase + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/grenade.rsi + layers: + - state: icon + map: ["enum.TriggerVisualLayers.Base"] + - type: Item + size: Small + - type: Clothing + quickEquip: false + slots: + - Belt + - type: TriggerOnUse + - type: TimerTrigger + delay: 3 + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: # Start fuse + !type:DamageTrigger + damage: 10 + behaviors: + - !type:TimerStartBehavior + - type: Appearance + - type: AnimationPlayer + - type: GenericVisualizer + visuals: + enum.Trigger.TriggerVisuals.VisualState: + enum.ConstructionVisuals.Layer: + Primed: { state: primed } + Unprimed: { state: icon } + - type: Tag + tags: + - HandGrenade + - type: Fixtures + fixtures: + fix1: + shape: !type:PhysShapeCircle + radius: 0.2 + density: 20 # derived from base_item + mask: + - ItemMask + restitution: 0.3 + friction: 0.2 + +- type: entity # Starts fuse after taking 10 damage, instantly detonates/activates after taking 45 damage. + abstract: true + id: VolatileGrenadeBase + components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:TimerStartBehavior + - trigger: # immediately explode + !type:DamageTrigger + damage: 45 + behaviors: + - !type:TriggerBehavior + keyOut: timer + - !type:DoActsBehavior + acts: ["Destruction"] + +- type: entity # Starts fuse after taking 10 damage, is destroyed without activating/detonating after taking 45 damage. + abstract: true + id: FragileGrenadeBase + components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:TimerStartBehavior + - trigger: # Disappear + !type:DamageTrigger + damage: 45 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/canister_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/canister_grenades.yml new file mode 100644 index 0000000000..31cb00f164 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/canister_grenades.yml @@ -0,0 +1,117 @@ +- type: entity + parent: [VolatileGrenadeBase, GrenadeBase, BaseSecurityContraband ] + id: SmokeGrenade + name: smoke grenade + description: A tactical grenade that releases a large, long-lasting cloud of smoke when used. + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/smoke.rsi + - type: SmokeOnTrigger + keysIn: + - timer + duration: 30 + spreadAmount: 50 + - type: EmitSoundOnTrigger + keysIn: + - timer + sound: /Audio/Items/smoke_grenade_smoke.ogg + positional: true + - type: DeleteOnTrigger + keysIn: + - timer + - type: TimerTriggerVisuals + primingSound: + path: /Audio/Items/smoke_grenade_prime.ogg + +- type: entity + parent: [ BaseCivilianContraband, SmokeGrenade ] + id: CleanerGrenade + name: cleanade + description: Special grenade for janitors, releasing large cloud of space cleaner foam. + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/janitor.rsi + - type: SmokeOnTrigger + keysIn: + - timer + duration: 15 + spreadAmount: 50 + smokePrototype: Foam + solution: + reagents: + - ReagentId: SpaceCleaner + Quantity: 30 + +- type: entity + parent: SmokeGrenade + id: TearGasGrenade + name: tear gas grenade + description: A riot control tear gas grenade. Causes irritation, pain and makes you cry your eyes out. + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/tear_gas.rsi + - type: SmokeOnTrigger + keysIn: + - timer + duration: 10 + spreadAmount: 30 + smokePrototype: TearGasSmokeWhite + solution: + reagents: + - ReagentId: TearGas + Quantity: 20 + +- type: entity + parent: [ BaseEngineeringContraband, SmokeGrenade ] + id: MetalFoamGrenade + name: metal foam grenade + description: An emergency tool used for patching hull breaches with special quick-set metal foam. Almost as good as real floors! + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/metalfoam.rsi + - type: TimerTrigger + delay: 5 + - type: SmokeOnTrigger + keysIn: + - timer + duration: 10 + spreadAmount: 20 + smokePrototype: AluminiumMetalFoam + - type: StaticPrice + price: 350 + +- type: entity + parent: [ BaseEngineeringContraband, VolatileGrenadeBase, GrenadeBase ] # Prevent inheriting DeleteOnTrigger from SmokeGrenade + id: AirGrenade + name: air grenade + description: A special solid state chemical grenade used for quickly releasing standard air into a spaced area. Fills up to 30 tiles! + components: + - type: Sprite + sprite: Objects/Weapons/Grenades/airboom.rsi + - type: EmitSoundOnTrigger + keysIn: + - timer + sound: /Audio/Items/smoke_grenade_smoke.ogg + - type: TimerTriggerVisuals + primingSound: + path: /Audio/Items/smoke_grenade_prime.ogg + - type: TimerTrigger + delay: 3 + - type: ReleaseGasOnTrigger + keysIn: + - timer + removeFraction: 0.25 + air: + volume: 1000 + moles: # Target is 3117.84 mols total for filling 30 tiles (goal is 101.325 kPa @ 20C) + Oxygen: 654.7464 # oxygen + Nitrogen: 2463.0936 # nitrogen + temperature: 293.15 + - type: StaticPrice + price: 350 + - type: GenericVisualizer + visuals: + enum.ReleaseGasOnTriggerVisuals.Key: + enabled: + True: { state: active } + False: { state: spent } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index a4c0d43b9e..6fb94e1f0a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -1,60 +1,7 @@ -- type: entity - abstract: true - parent: BaseItem - id: GrenadeBase - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/grenade.rsi - layers: - - state: icon - map: ["enum.TriggerVisualLayers.Base"] - - type: Item - size: Small - - type: Clothing - quickEquip: false - slots: - - Belt - - type: TriggerOnUse - - type: TimerTrigger - delay: 3 - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:TriggerBehavior - keyOut: timer # explode immediately - - !type:DoActsBehavior - acts: ["Destruction"] - - type: Appearance - - type: AnimationPlayer - - type: GenericVisualizer - visuals: - enum.Trigger.TriggerVisuals.VisualState: - enum.ConstructionVisuals.Layer: - Primed: { state: primed } - Unprimed: { state: icon } - - type: Tag - tags: - - HandGrenade - - type: Fixtures - fixtures: - fix1: - shape: !type:PhysShapeCircle - radius: 0.2 - density: 20 # derived from base_item - mask: - - ItemMask - restitution: 0.3 - friction: 0.2 - - type: entity name: explosive grenade description: Grenade that creates a small but devastating explosion. - parent: [GrenadeBase, BaseSyndicateContraband] + parent: [VolatileGrenadeBase, GrenadeBase, BaseSyndicateContraband] id: ExGrenade components: - type: ExplodeOnTrigger @@ -77,7 +24,7 @@ - type: entity name: flashbang description: Eeeeeeeeeeeeeeeeeeeeee. - parent: [ GrenadeBase, BaseSecurityContraband ] + parent: [ FragileGrenadeBase, GrenadeBase, BaseSecurityContraband ] id: GrenadeFlashBang components: - type: Sprite @@ -132,28 +79,13 @@ - type: entity name: syndicate minibomb description: A syndicate-manufactured explosive used to stow destruction and cause chaos. - parent: [GrenadeBase, BaseSyndicateContraband] + parent: [VolatileGrenadeBase, GrenadeBase, BaseSyndicateContraband] id: SyndieMiniBomb components: - type: Sprite sprite: Objects/Weapons/Grenades/syndgrenade.rsi - type: ExplosionResistance damageCoefficient: 0.1 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:TimerStartBehavior - - trigger: - !type:DamageTrigger - damage: 45 - behaviors: - - !type:TriggerBehavior - keyOut: timer # immediately explode - - !type:DoActsBehavior - acts: ["Destruction"] - type: TimerTrigger delay: 5 - type: ExplodeOnTrigger @@ -202,7 +134,7 @@ - type: entity - parent: [ GrenadeBase, BaseSyndicateContraband ] + parent: [ FragileGrenadeBase, GrenadeBase, BaseSyndicateContraband ] id: SingularityGrenade name: singularity grenade description: Grenade that simulates the power of a singularity, pulling things in a heap. @@ -416,7 +348,7 @@ - type: entity name: EMP grenade description: A grenade designed to wreak havoc on electronic systems. - parent: [GrenadeBase, BaseSyndicateContraband] + parent: [FragileGrenadeBase, GrenadeBase, BaseSyndicateContraband] id: EmpGrenade components: - type: Sprite @@ -465,124 +397,6 @@ - type: StaticPrice price: 10000 -- type: entity - parent: [ GrenadeBase, BaseSecurityContraband ] - id: SmokeGrenade - name: smoke grenade - description: A tactical grenade that releases a large, long-lasting cloud of smoke when used. - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/smoke.rsi - - type: SmokeOnTrigger - keysIn: - - timer - duration: 30 - spreadAmount: 50 - - type: EmitSoundOnTrigger - keysIn: - - timer - sound: /Audio/Items/smoke_grenade_smoke.ogg - positional: true - - type: DeleteOnTrigger - keysIn: - - timer - - type: TimerTriggerVisuals - primingSound: - path: /Audio/Items/smoke_grenade_prime.ogg - -- type: entity - parent: [ BaseCivilianContraband, SmokeGrenade ] - id: CleanerGrenade - name: cleanade - description: Special grenade for janitors, releasing large cloud of space cleaner foam. - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/janitor.rsi - - type: SmokeOnTrigger - keysIn: - - timer - duration: 15 - spreadAmount: 50 - smokePrototype: Foam - solution: - reagents: - - ReagentId: SpaceCleaner - Quantity: 30 - -- type: entity - parent: SmokeGrenade - id: TearGasGrenade - name: tear gas grenade - description: A riot control tear gas grenade. Causes irritation, pain and makes you cry your eyes out. - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/tear_gas.rsi - - type: SmokeOnTrigger - keysIn: - - timer - duration: 10 - spreadAmount: 30 - smokePrototype: TearGasSmokeWhite - solution: - reagents: - - ReagentId: TearGas - Quantity: 20 - -- type: entity - parent: [ BaseEngineeringContraband, SmokeGrenade ] - id: MetalFoamGrenade - name: metal foam grenade - description: An emergency tool used for patching hull breaches with special quick-set metal foam. Almost as good as real floors! - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/metalfoam.rsi - - type: TimerTrigger - delay: 5 - - type: SmokeOnTrigger - keysIn: - - timer - duration: 10 - spreadAmount: 20 - smokePrototype: AluminiumMetalFoam - - type: StaticPrice - price: 350 - -- type: entity - parent: [ BaseEngineeringContraband, GrenadeBase ] # Prevent inheriting DeleteOnTrigger from SmokeGrenade - id: AirGrenade - name: air grenade - description: A special solid state chemical grenade used for quickly releasing standard air into a spaced area. Fills up to 30 tiles! - components: - - type: Sprite - sprite: Objects/Weapons/Grenades/airboom.rsi - - type: EmitSoundOnTrigger - keysIn: - - timer - sound: /Audio/Items/smoke_grenade_smoke.ogg - - type: TimerTriggerVisuals - primingSound: - path: /Audio/Items/smoke_grenade_prime.ogg - - type: TimerTrigger - delay: 3 - - type: ReleaseGasOnTrigger - keysIn: - - timer - removeFraction: 0.25 - air: - volume: 1000 - moles: # Target is 3117.84 mols total for filling 30 tiles (goal is 101.325 kPa @ 20C) - Oxygen: 654.7464 # oxygen - Nitrogen: 2463.0936 # nitrogen - temperature: 293.15 - - type: StaticPrice - price: 350 - - type: GenericVisualizer - visuals: - enum.ReleaseGasOnTriggerVisuals.Key: - enabled: - True: { state: active } - False: { state: spent } - # Non-explosive "dummy" grenades to use as a distraction. - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml index 0e8b758a13..5a3cedb901 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml @@ -43,7 +43,7 @@ friction: 0.2 - type: entity - parent: [ProjectileGrenadeBase, BaseSecurityContraband] + parent: [FragileGrenadeBase, ProjectileGrenadeBase, BaseSecurityContraband] id: GrenadeStinger name: stinger grenade description: Nothing to see here, please disperse. @@ -77,7 +77,7 @@ path: /Audio/Effects/countdown.ogg - type: entity - parent: [ProjectileGrenadeBase, BaseSyndicateContraband] + parent: [FragileGrenadeBase, ProjectileGrenadeBase, BaseSyndicateContraband] id: GrenadeIncendiary name: incendiary grenade description: Guaranteed to light up the mood. @@ -109,7 +109,7 @@ price: 1500 - type: entity - parent: [ProjectileGrenadeBase, BaseSyndicateContraband] + parent: [FragileGrenadeBase, ProjectileGrenadeBase, BaseSyndicateContraband] id: GrenadeShrapnel name: shrapnel grenade description: Releases a deadly spray of shrapnel that causes severe bleeding. diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml index ba2bdd230e..6bff4fbd44 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml @@ -10,14 +10,6 @@ cluster-payload: !type:Container - type: Damageable damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:TriggerBehavior - keyOut: timer # explode immediately - type: ScatteringGrenade - type: TriggerOnUse - type: TimerTrigger @@ -37,7 +29,7 @@ friction: 0.2 - type: entity - parent: [ScatteringGrenadeBase, BaseSecurityContraband] + parent: [FragileGrenadeBase, ScatteringGrenadeBase, BaseSecurityContraband] id: ClusterBang name: clusterbang description: Can be used only with flashbangs. Explodes several times. @@ -57,7 +49,7 @@ - type: entity parent: ClusterBang id: ClusterBangFull - name: ClusterBang + name: clusterbang description: Launches three flashbangs after the timer runs out. suffix: Full components: @@ -90,7 +82,7 @@ positional: true - type: entity - parent: [ScatteringGrenadeBase, BaseSyndicateContraband] + parent: [VolatileGrenadeBase, ScatteringGrenadeBase, BaseSyndicateContraband] id: ClusterGrenade name: clustergrenade description: Why use one grenade when you can use three at once! @@ -120,7 +112,7 @@ price: 2500 - type: entity - parent: [ScatteringGrenadeBase, BaseSyndicateContraband] + parent: [FragileGrenadeBase, ScatteringGrenadeBase, BaseSyndicateContraband] id: ClusterBananaPeel name: cluster banana peel description: Splits into 6 explosive banana peels after throwing, guaranteed fun! @@ -175,7 +167,7 @@ price: 1000 - type: entity - parent: ScatteringGrenadeBase + parent: [FragileGrenadeBase, ScatteringGrenadeBase] id: GrenadeFoamDart name: foam dart grenade description: Releases a bothersome spray of foam darts that cause severe welching. diff --git a/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml b/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml index b2806b93c9..06afa3785e 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/decorated_fir_tree.yml @@ -13,7 +13,7 @@ shader: unshaded - type: PointLight radius: 1.6 - energy: 1.2 + energy: 2.0 enabled: false mask: /Textures/Effects/LightMasks/cone.png autoRot: true diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index 8330bf2fd4..e769d81fbb 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -51,7 +51,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.4,0.5,0.4,0.35" + bounds: "-0.4,0.35,0.4,0.5" density: 190 mask: - None @@ -275,7 +275,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.1,0.5,0.1,0.255" + bounds: "-0.1,0.255,0.1,0.5" density: 190 mask: - None diff --git a/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml index 222ea5c814..2642d4217e 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/ground_lighting.yml @@ -22,7 +22,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "0.17,0.25,-0.17,-0.30" + bounds: "-0.17,-0.30,0.17,0.25" density: 190 mask: - MachineMask diff --git a/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml index c1aa9b97d8..eb8c658fe5 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/strobe_lighting.yml @@ -45,7 +45,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.2,0.5,0.2,0.35" + bounds: "-0.2,0.35,0.2,0.5" density: 190 mask: - None diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml index c23c126c73..78fdd25316 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml @@ -10,7 +10,7 @@ - type: ExtensionCableReceiver - type: PointLight radius: 1.8 - energy: 1.6 + energy: 3.0 color: "#3db83b" - type: LitOnPowered - type: Sprite diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml index 7cccee81c0..bbd6ea8302 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml @@ -50,7 +50,7 @@ - type: LitOnPowered - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 enabled: false mask: /Textures/Effects/LightMasks/cone.png autoRot: true diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index f75c4e5374..f546933339 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -110,7 +110,7 @@ type: WiresBoundUserInterface - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#43ccb5" - type: entity @@ -134,7 +134,7 @@ radius: 256 - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#43ccb5" - type: ItemSlots slots: @@ -204,7 +204,7 @@ radius: 1536 - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#c94242" - type: Computer board: SyndicateShuttleConsoleCircuitboard @@ -234,7 +234,7 @@ maxRange: 256 - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#43ccb5" - type: Computer board: CargoShuttleConsoleCircuitboard @@ -314,7 +314,7 @@ state: generic_panel_open - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#c9c042" - type: Computer board: PowerComputerCircuitboard @@ -356,7 +356,7 @@ state: generic_panel_open - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#1f8c28" - type: Computer board: MedicalRecordsComputerCircuitboard @@ -390,7 +390,7 @@ state: generic_panel_open - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#1f8c28" - type: Computer board: CriminalRecordsComputerCircuitboard @@ -417,7 +417,7 @@ key: enum.GeneralStationRecordConsoleKey.Key - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#1f8c28" - type: Computer board: StationRecordsComputerCircuitboard @@ -445,7 +445,7 @@ state: generic_panel_open - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#006400" - type: Computer board: CrewMonitoringComputerCircuitboard @@ -506,7 +506,7 @@ access: [["Research"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b53ca1" - type: GuideHelp guides: @@ -555,7 +555,7 @@ board: AnalysisComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b53ca1" - type: GuideHelp guides: @@ -615,7 +615,7 @@ board: IDComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#3c5eb5" - type: ItemSlots - type: ContainerContainer @@ -636,7 +636,7 @@ board: BodyScannerComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#1f8c28" - type: entity @@ -676,7 +676,7 @@ board: CommsComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#3c5eb5" - type: Damageable damageContainer: StructuralInorganic @@ -713,7 +713,7 @@ board: SyndicateCommsComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#f71713" - type: entity @@ -747,7 +747,7 @@ board: WizardCommsComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#F317F3" - type: entity @@ -779,7 +779,7 @@ board: CentcommCommsComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#00FF00" - type: entity @@ -813,7 +813,7 @@ board: SolarControlComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#e6e227" - type: GuideHelp guides: @@ -851,7 +851,7 @@ board: RadarConsoleCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#e6e227" - type: entity @@ -889,7 +889,7 @@ board: CargoRequestComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b89f25" - type: AccessReader access: [["Cargo"]] @@ -1103,7 +1103,7 @@ board: CargoBountyComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b89f25" - type: AccessReader access: [["Quartermaster"]] @@ -1146,7 +1146,7 @@ board: FundingAllocationComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#3c5eb5" - type: entity @@ -1177,7 +1177,7 @@ board: CloningConsoleComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#1f8c28" - type: DeviceLinkSource range: 4 @@ -1235,7 +1235,7 @@ board: SalvageJobBoardComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b89f25" - type: entity @@ -1284,7 +1284,7 @@ board: SalvageExpeditionsComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b89f25" - type: AccessReader access: [["Salvage"]] @@ -1422,7 +1422,7 @@ board: CargoSaleComputerCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#b89f25" - type: GuideHelp guides: @@ -1488,7 +1488,7 @@ state: generic_panel_open - type: PointLight radius: 1.5 - energy: 1.6 + energy: 4.0 color: "#43ccb5" - type: Computer board: SensorConsoleCircuitboard @@ -1556,7 +1556,7 @@ unlockOnClick: false - type: entity - parent: ComputerRoboticsControl + parent: BaseComputer id: ComputerXenoborgsControl name: xenoborgs control console description: Used to remotely monitor all xenoborgs. @@ -1573,20 +1573,28 @@ state: rd_key - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] state: generic_panel_open + - type: ActivatableUI + key: enum.RoboticsConsoleUiKey.Key + - type: UserInterface + interfaces: + enum.RoboticsConsoleUiKey.Key: + type: RoboticsConsoleBoundUserInterface + enum.WiresUiKey.Key: + type: WiresBoundUserInterface - type: RoboticsConsole allowBorgControl: false radioChannel: Xenoborg - type: ActiveRadio channels: - Xenoborg + - type: ApcPowerReceiver + powerLoad: 1000 - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: Mothership transmitFrequencyId: Xenoborg - type: Computer board: ComputerXenoborgsControlCircuitboard - - type: AccessReader # only used for dangerous things - access: [["Xenoborg"]] - type: entity id: StationAiUploadComputer diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/wooden_television.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/wooden_television.yml index b542687b57..50cc6a624c 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/wooden_television.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/wooden_television.yml @@ -16,7 +16,7 @@ board: ComputerTelevisionCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89f25" - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml index 3019b8adf8..de4ea19350 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml @@ -41,7 +41,7 @@ bounds: "-0.35,-0.35,0.35,0.35" density: 100 mask: - - ItemMask + - ItemMask hard: True - type: Transform anchored: true @@ -56,7 +56,7 @@ - type: DeviceList - type: PointLight radius: 1.8 - energy: 1.6 + energy: 3.0 color: "#b53ca1" - type: LitOnPowered - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index d4fc8263a8..a80456583a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -66,7 +66,7 @@ board: ArtifactAnalyzerMachineCircuitboard - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b53ca1" - type: GuideHelp guides: @@ -157,3 +157,13 @@ machine_parts: !type:Container entity_storage: !type:Container output_container: !type:Container + +# just a resprite +- type: entity + parent: MachineArtifactCrusher + id: MachineArtifactCrusherXenoborg + name: body crusher + description: Best not to let your head get stuck... + components: + - type: Sprite + sprite: Structures/Machines/body_crusher.rsi diff --git a/Resources/Prototypes/Entities/Structures/Machines/research.yml b/Resources/Prototypes/Entities/Structures/Machines/research.yml index 765249a933..40abd4b655 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/research.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/research.yml @@ -18,8 +18,8 @@ - type: PointLight enabled: false castShadows: false - radius: 1.5 - energy: 1.6 + radius: 1.2 + energy: 3.0 color: "#b211b2" - type: LitOnPowered - type: ResearchServer @@ -95,7 +95,7 @@ active: true - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3db83b" - type: ActivatableUI key: enum.ResearchClientUiKey.Key diff --git a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml index dc9ad5fafa..e8c676e53a 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml @@ -24,8 +24,8 @@ - state: panel map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight - radius: 1.5 - energy: 1.6 + radius: 1.2 + energy: 3.0 color: "#9dc5c9" - type: Machine board: SmartFridgeCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml index 4cfcbcd462..3caa56d3f8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml @@ -92,7 +92,7 @@ enabled: false castShadows: false radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#39b8ee" - type: LitOnPowered - type: GenericVisualizer diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index 8448b9aca8..b01c82ae99 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -327,7 +327,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1 - energy: 1.3 + energy: 2.0 color: "#ffb0b0" - type: AccessReader access: [["HeadOfPersonnel"]] @@ -362,7 +362,7 @@ access: [["Service"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#4b93ad" - type: entity @@ -423,7 +423,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.8 - energy: 1.6 + energy: 3.0 color: "#3db83b" - type: entity @@ -454,7 +454,7 @@ map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - type: PointLight radius: 1.8 - energy: 1.6 + energy: 3.0 color: "#3db83b" - type: entity @@ -495,7 +495,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.3 + energy: 2.0 color: "#ad7c4b" - type: entity @@ -531,7 +531,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3c5eb5" - type: entity @@ -551,7 +551,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#423438" - type: entity @@ -572,7 +572,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#A50824" - type: entity @@ -595,7 +595,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#44964A" - type: entity @@ -617,7 +617,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#CBC6BE" - type: entity @@ -640,7 +640,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#D3A44D" - type: entity @@ -674,7 +674,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#66538F" - type: entity @@ -710,7 +710,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#6927C5" - type: entity @@ -746,7 +746,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#D82929" - type: entity @@ -782,7 +782,7 @@ pack: SmiteGoodbyes - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#00E645" - type: entity @@ -815,7 +815,7 @@ access: [["Kitchen"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#4b93ad" - type: entity @@ -845,7 +845,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#9a18d6" - type: entity @@ -878,7 +878,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#6148c7" - type: entity @@ -908,7 +908,7 @@ access: [["Engineering"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89e2a" - type: entity @@ -941,7 +941,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#9dc5c9" - type: GuideHelp guides: @@ -998,7 +998,7 @@ access: [["Hydroponics"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#326e3f" - type: entity @@ -1032,7 +1032,7 @@ access: [["Security"]] - type: PointLight radius: 1 - energy: 1.2 + energy: 2.0 color: "#78645c" - type: GuideHelp guides: @@ -1069,7 +1069,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#326e3f" - type: entity @@ -1112,7 +1112,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#c73434" - type: entity @@ -1142,7 +1142,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#737785" - type: entity @@ -1162,7 +1162,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3c5eb5" - type: entity @@ -1182,7 +1182,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#CE3401" - type: entity @@ -1202,7 +1202,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#5F6A1C" - type: entity @@ -1222,7 +1222,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#207E79" - type: entity @@ -1258,7 +1258,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#389690" - type: RussianAccent @@ -1295,7 +1295,7 @@ shader: unshaded - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#c73434" - type: entity @@ -1327,7 +1327,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#9dc5c9" - type: entity @@ -1361,7 +1361,7 @@ access: [["Research"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#B0ADA9" - type: GuideHelp guides: @@ -1392,7 +1392,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#d4ab33" - type: entity @@ -1424,7 +1424,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#326e3f" - type: entity @@ -1457,7 +1457,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#ffe599" - type: entity @@ -1484,7 +1484,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89f25" - type: AccessReader access: [["Salvage"]] @@ -1522,7 +1522,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#d4ab33" # job clothing @@ -1554,7 +1554,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#326e3f" - type: AccessReader access: [["Hydroponics"]] @@ -1614,7 +1614,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#d82929" - type: AccessReader access: [["Security"]] @@ -1672,7 +1672,7 @@ access: [["Chapel"]] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#CCCCCC" #The holy C - type: entity @@ -1702,7 +1702,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89e2a" - type: AccessReader access: [["Cargo"]] @@ -1818,7 +1818,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89e2a" - type: AccessReader access: [["Engineering"]] @@ -1850,7 +1850,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89e2a" - type: AccessReader access: [["Engineering"]] @@ -1938,7 +1938,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#6927C5" - type: AccessReader access: [["Janitor"]] @@ -1998,7 +1998,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#d82929" - type: AccessReader access: [["NuclearOperative"], ["SyndicateAgent"]] @@ -2110,7 +2110,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#48CF48" - type: AccessReader access: [["CentralCommand"]] @@ -2144,7 +2144,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3c5eb5" - type: DatasetVocalizer dataset: HappyHonkAds @@ -2173,7 +2173,7 @@ - type: Speech - type: PointLight radius: 1.5 - energy: 1.3 # reduced energy since the color is pure white + energy: 2.0 # reduced energy since the color is pure white color: "#FFFFFF" - type: Sprite sprite: Structures/Machines/VendingMachines/pride.rsi @@ -2286,7 +2286,7 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: PointLight radius: 1.3 - energy: 1.6 + energy: 3.0 color: "#43ccb5" - type: GuideHelp guides: diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml index 456a83046b..dfb273a5e8 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml @@ -101,7 +101,7 @@ path: /Audio/Ambience/Objects/hdd_buzz.ogg - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3db83b" castShadows: false netsync: false diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 0addb34704..ec8b86e173 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -16,7 +16,7 @@ path: /Audio/Ambience/Objects/hdd_buzz.ogg - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#3db83b" castShadows: false netsync: false diff --git a/Resources/Prototypes/Entities/Structures/Power/debug_power.yml b/Resources/Prototypes/Entities/Structures/Power/debug_power.yml index a2e1c585fb..a9c3671c33 100644 --- a/Resources/Prototypes/Entities/Structures/Power/debug_power.yml +++ b/Resources/Prototypes/Entities/Structures/Power/debug_power.yml @@ -124,7 +124,6 @@ components: - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: entity parent: BaseSubstation @@ -138,7 +137,6 @@ components: - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: entity parent: BaseSubstationWall @@ -152,7 +150,6 @@ components: - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: entity parent: BaseAPC @@ -166,7 +163,6 @@ components: - type: BatterySelfRecharger autoRechargeRate: 50000 - autoRecharge: True - type: entity id: DebugPowerReceiver diff --git a/Resources/Prototypes/Entities/Structures/Power/smes.yml b/Resources/Prototypes/Entities/Structures/Power/smes.yml index 9c5162a421..3572fe6a39 100644 --- a/Resources/Prototypes/Entities/Structures/Power/smes.yml +++ b/Resources/Prototypes/Entities/Structures/Power/smes.yml @@ -64,8 +64,8 @@ supplyRampTolerance: 5000 supplyRampRate: 1000 - type: PointLight - radius: 1.5 - energy: 1.6 + radius: 1.2 + energy: 3.0 color: "#c9c042" castShadows: false - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml index c80ff8eb70..bb43cb3b2c 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml @@ -102,6 +102,13 @@ visible: false offset: 0, 1 +- type: entity + parent: Thruster + id: ThrusterXenoborg + components: + - type: Sprite + sprite: Structures/Shuttles/xenoborg_thruster.rsi + - type: entity id: ThrusterLarge name: large thruster diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml index 45a5a6d4d6..492ab11f0c 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml @@ -43,7 +43,7 @@ sprite: Structures/Specific/Anomalies/Cores/pyro_core.rsi - type: PointLight radius: 1.5 - energy: 1.5 + energy: 2.7 color: "#E25822" castShadows: false - type: IgnitionSource @@ -72,7 +72,7 @@ sprite: Structures/Specific/Anomalies/Cores/ice_core.rsi - type: PointLight radius: 1.5 - energy: 1.5 + energy: 2.7 color: "#befaff" castShadows: false @@ -223,7 +223,7 @@ sprite: Structures/Specific/Anomalies/Cores/pyro_core.rsi - type: PointLight radius: 1.5 - energy: 1.5 + energy: 2.7 color: "#fca3c0" castShadows: false @@ -249,7 +249,7 @@ sprite: Structures/Specific/Anomalies/Cores/ice_core.rsi - type: PointLight radius: 1.5 - energy: 1.5 + energy: 2.7 color: "#befaff" castShadows: false diff --git a/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml b/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml new file mode 100644 index 0000000000..4042b115f5 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Specific/Cargo/mailcart.yml @@ -0,0 +1,94 @@ +# Mailcart +- type: entity + name: mail cart + id: MailCart + parent: [BaseStructureDynamic, StructureWheeled] + description: Deliver packages with style and efficiency. + components: + - type: Sprite + noRot: true + sprite: Objects/Specific/Cargo/mailcart.rsi + layers: + - state: mailcart_base + - type: InteractionOutline + - type: Storage + grid: + - 0,0,15,7 + quickInsert: true + maxItemSize: Huge + whitelist: + components: + - Delivery + tags: + - Paper + - Document + - BoxCardboard + - Folder + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.18,-0.2,0.18,0.2" + density: 60 + mask: + - FullTileMask + layer: + - LargeMobLayer + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 400 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - trigger: !type:DamageTrigger + damage: 200 + behaviors: + - !type:EmptyAllContainersBehaviour + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - type: ItemMapper + mapLayers: + package_1: + minCount: 1 + whitelist: &PackageWhitelist + tags: + - PackageDelivery + package_2: + minCount: 2 + whitelist: *PackageWhitelist + package_3: + minCount: 3 + whitelist: *PackageWhitelist + package_4: + minCount: 4 + whitelist: *PackageWhitelist + package_5: + minCount: 5 + whitelist: *PackageWhitelist + package_6: + minCount: 6 + whitelist: *PackageWhitelist + package_7: + minCount: 7 + whitelist: *PackageWhitelist + package_8: + minCount: 8 + whitelist: *PackageWhitelist + sprite: Objects/Specific/Cargo/mailcart.rsi + - type: Appearance + - type: UserInterface + interfaces: + enum.StorageUiKey.Key: + type: StorageBoundUserInterface + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/telescreens.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/telescreens.yml index ed585aa185..0705a60b49 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/telescreens.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/telescreens.yml @@ -28,7 +28,7 @@ node: Telescreen - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89f25" - type: DeviceNetwork deviceNetId: Wired diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/televisions.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/televisions.yml index b600ece985..fd1e895f70 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/televisions.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/Monitors/televisions.yml @@ -35,7 +35,7 @@ type: SurveillanceCameraMonitorBoundUserInterface - type: PointLight radius: 1.5 - energy: 1.6 + energy: 3.0 color: "#b89f25" - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml similarity index 100% rename from Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml rename to Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml diff --git a/Resources/Prototypes/Entities/Structures/Walls/railing.yml b/Resources/Prototypes/Entities/Structures/Walls/railing.yml index db456c512f..869f423887 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/railing.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/railing.yml @@ -93,7 +93,7 @@ fix2: shape: !type:PhysShapeAabb - bounds: "0.49,0.49,0.25,-0.49" + bounds: "0.25,-0.49,0.49,0.49" density: 1000 mask: - TableMask @@ -139,7 +139,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.49,0.49,-0.25,0.25" + bounds: "-0.49,0.25,-0.25,0.49" density: 1000 mask: - TableMask diff --git a/Resources/Prototypes/Entities/Virtual/mind.yml b/Resources/Prototypes/Entities/Virtual/mind.yml new file mode 100644 index 0000000000..33e9ba273a --- /dev/null +++ b/Resources/Prototypes/Entities/Virtual/mind.yml @@ -0,0 +1,10 @@ +- type: entity + id: MindBase + name: mind + categories: [ HideSpawnMenu ] + components: + - type: Mind + - type: ContainerContainer + containers: + mind_roles: !type:Container + ents: [] diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 715c1b7504..3155266d4d 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -24,6 +24,8 @@ prob: 0.5 - id: SubWizard prob: 0.05 + - id: Xenoborgs + prob: 0.05 - type: entity parent: BaseGameRule @@ -33,6 +35,19 @@ rules: - id: Thief prob: 0.5 + - id: Xenoborgs + prob: 0.05 + +- type: entity + parent: BaseGameRule + id: SubGamemodesRuleNoXenoborg + components: + - type: SubGamemodes + rules: + - id: Thief + prob: 0.5 + - id: SubWizard + prob: 0.05 - type: entity parent: BaseGameRule @@ -527,7 +542,7 @@ - id: SolarPanelEmptyVariationPass - id: BasicDecalDirtVariationPass - id: BasicDecalGraffitiVariationPass - - id: BasicDecalBrunsVariationPass + - id: BasicDecalBurnsVariationPass prob: 0.50 orGroup: monospaceDecals - id: BasicDecalDirtMonospaceVariationPass diff --git a/Resources/Prototypes/GameRules/subgamemodes.yml b/Resources/Prototypes/GameRules/subgamemodes.yml index bda4ae1ab3..8f229fbc4c 100644 --- a/Resources/Prototypes/GameRules/subgamemodes.yml +++ b/Resources/Prototypes/GameRules/subgamemodes.yml @@ -71,3 +71,36 @@ nameFormat: name-format-wizard mindRoles: - MindRoleWizard + +- type: entity + parent: BaseGameRule + id: Xenoborgs + components: + - type: XenoborgsRule + - type: RuleGrids + - type: GameRule + minPlayers: 40 + - type: LoadMapRule + gridPath: /Maps/Shuttles/mothership.yml + - type: AntagMultipleRoleSpawner + antagRoleToPrototypes: + MothershipCore: [ MothershipCore ] + Xenoborg: [ XenoborgEngi, XenoborgHeavy, XenoborgScout, XenoborgStealth ] + pickAndTake: true + - type: AntagSelection + selectionTime: PrePlayerSpawn + definitions: + - prefRoles: [ MothershipCore ] + fallbackRoles: [ Xenoborg ] + spawnerPrototype: SpawnPointGhostRoleMothershipCore + mindRoles: + - MindRoleMothershipCore + - prefRoles: [ Xenoborg ] + fallbackRoles: [ MothershipCore ] + spawnerPrototype: SpawnPointGhostRoleXenoborg + mindRoles: + - MindRoleXenoborg + min: 4 + max: 4 + - type: DynamicRuleCost + cost: 200 diff --git a/Resources/Prototypes/GameRules/variation.yml b/Resources/Prototypes/GameRules/variation.yml index 718e5111a7..5e2fe0576b 100644 --- a/Resources/Prototypes/GameRules/variation.yml +++ b/Resources/Prototypes/GameRules/variation.yml @@ -68,7 +68,7 @@ - id: DecalSpawnerGraffiti - type: entity - id: BasicDecalBrunsVariationPass + id: BasicDecalBurnsVariationPass parent: BaseVariationPass components: - type: EntitySpawnVariationPass diff --git a/Resources/Prototypes/Guidebook/antagonist.yml b/Resources/Prototypes/Guidebook/antagonist.yml index 4548bb292b..66cb65218a 100644 --- a/Resources/Prototypes/Guidebook/antagonist.yml +++ b/Resources/Prototypes/Guidebook/antagonist.yml @@ -10,6 +10,7 @@ - SpaceNinja - Wizard - Zombies + - Xenoborgs - MinorAntagonists - type: guideEntry @@ -51,3 +52,8 @@ id: Wizard name: guide-entry-wizard text: "/ServerInfo/Guidebook/Antagonist/Wizard.xml" + +- type: guideEntry + id: Xenoborgs + name: guide-entry-xenoborgs + text: "/ServerInfo/Guidebook/Antagonist/Xenoborgs.xml" diff --git a/Resources/Prototypes/InventoryTemplates/aghost_inventory_template.yml b/Resources/Prototypes/InventoryTemplates/aghost_inventory_template.yml index 8c32091b8c..d20e881dc8 100644 --- a/Resources/Prototypes/InventoryTemplates/aghost_inventory_template.yml +++ b/Resources/Prototypes/InventoryTemplates/aghost_inventory_template.yml @@ -8,7 +8,7 @@ stripTime: 6 uiWindowPos: 2,1 strippingWindowPos: 2,4 - displayName: ID + displayName: Back - name: id slotTexture: id fullTextureName: template_small diff --git a/Resources/Prototypes/Loadouts/Jobs/Civilian/janitor.yml b/Resources/Prototypes/Loadouts/Jobs/Civilian/janitor.yml index d902481f9c..431b83a99d 100644 --- a/Resources/Prototypes/Loadouts/Jobs/Civilian/janitor.yml +++ b/Resources/Prototypes/Loadouts/Jobs/Civilian/janitor.yml @@ -45,13 +45,3 @@ id: JanitorWintercoat equipment: outerClothing: ClothingOuterWinterJani - -# Misc -- type: loadout - id: JanitorGoldenPlunger - effects: - - !type:GroupLoadoutEffect - proto: SeniorJanitorial - storage: - back: - - GoldenPlunger diff --git a/Resources/Prototypes/Loadouts/Jobs/Security/security_officer.yml b/Resources/Prototypes/Loadouts/Jobs/Security/security_officer.yml index cf37ca8835..523476e775 100644 --- a/Resources/Prototypes/Loadouts/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Loadouts/Jobs/Security/security_officer.yml @@ -13,16 +13,6 @@ department: Security time: 60h -#Security Star -- type: loadoutEffectGroup - id: SecurityStarWorthy - effects: - - !type:JobRequirementLoadoutEffect - requirement: - !type:DepartmentTimeRequirement - department: Security - time: 100h - # Head - type: loadout id: SecurityHelmet @@ -158,13 +148,3 @@ # proto: SeniorOfficer equipment: id: SeniorOfficerPDA - -# Misc -- type: loadout - id: SecStar - effects: - - !type:GroupLoadoutEffect - proto: SecurityStarWorthy - storage: - back: - - Dinkystar diff --git a/Resources/Prototypes/Loadouts/Miscellaneous/jobtrinkets.yml b/Resources/Prototypes/Loadouts/Miscellaneous/jobtrinkets.yml index fd674b1901..b5e3f6bdd7 100644 --- a/Resources/Prototypes/Loadouts/Miscellaneous/jobtrinkets.yml +++ b/Resources/Prototypes/Loadouts/Miscellaneous/jobtrinkets.yml @@ -120,6 +120,15 @@ back: - PlushieLizardJobJanitor +- type: loadout + id: JanitorGoldenPlunger + effects: + - !type:GroupLoadoutEffect + proto: SeniorJanitorial + storage: + back: + - GoldenPlunger + - type: loadout id: LizardPlushieBotanist effects: @@ -336,6 +345,18 @@ back: - PlushieLizardJobSecurityofficer +- type: loadout + id: SecStar + effects: + - !type:JobRequirementLoadoutEffect + requirement: + !type:DepartmentTimeRequirement + department: Security + time: 100h + storage: + back: + - Dinkystar + - type: loadout id: LizardPlushieSecurityCadet effects: diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml index 8a93210ae9..f3b314873e 100644 --- a/Resources/Prototypes/Loadouts/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/loadout_groups.yml @@ -504,19 +504,13 @@ loadouts: - JanitorWintercoat -- type: loadoutGroup - id: JanitorPlunger - name: loadout-group-janitor-plunger - minLimit: 0 - loadouts: - - JanitorGoldenPlunger - - type: loadoutGroup id: JanitorJobTrinkets name: loadout-group-jobtrinkets minLimit: 0 loadouts: - LizardPlushieJanitor + - JanitorGoldenPlunger - type: loadoutGroup id: BotanistHead @@ -1214,6 +1208,7 @@ minLimit: 0 loadouts: - LizardPlushieHeadofSecurity + - SecStar - type: loadoutGroup id: WardenHead @@ -1243,6 +1238,7 @@ minLimit: 0 loadouts: - LizardPlushieWarden + - SecStar - type: loadoutGroup id: SecurityHead @@ -1311,6 +1307,7 @@ minLimit: 0 loadouts: - LizardPlushieSecurity + - SecStar - type: loadoutGroup id: DetectiveHead @@ -1350,6 +1347,7 @@ minLimit: 0 loadouts: - LizardPlushieDetective + - SecStar - type: loadoutGroup id: SecurityCadetJumpsuit @@ -1375,13 +1373,6 @@ - EmergencyOxygenSecurity - LoadoutSpeciesVoxNitrogen -- type: loadoutGroup - id: SecurityStar - name: loadout-group-security-star - minLimit: 0 - loadouts: - - SecStar - # Medical - type: loadoutGroup id: ChiefMedicalOfficerHead diff --git a/Resources/Prototypes/Loadouts/role_loadouts.yml b/Resources/Prototypes/Loadouts/role_loadouts.yml index cfec64f73d..7d5bef5387 100644 --- a/Resources/Prototypes/Loadouts/role_loadouts.yml +++ b/Resources/Prototypes/Loadouts/role_loadouts.yml @@ -162,7 +162,6 @@ - Survival - Trinkets - JanitorJobTrinkets - - JanitorPlunger - GroupSpeciesBreathTool - type: roleLoadout @@ -403,7 +402,6 @@ - SurvivalSecurity - Trinkets - HeadofSecurityJobTrinkets - - SecurityStar - GroupSpeciesBreathToolSecurity - type: roleLoadout @@ -419,7 +417,6 @@ - SurvivalSecurity - Trinkets - WardenJobTrinkets - - SecurityStar - GroupSpeciesBreathToolSecurity - type: roleLoadout @@ -436,7 +433,6 @@ - SurvivalSecurity - Trinkets - SecurityJobTrinkets - - SecurityStar - GroupSpeciesBreathToolSecurity - type: roleLoadout @@ -452,7 +448,6 @@ - SurvivalSecurity - Trinkets - DetectiveJobTrinkets - - SecurityStar - GroupSpeciesBreathToolSecurity - type: roleLoadout diff --git a/Resources/Prototypes/Magic/event_spells.yml b/Resources/Prototypes/Magic/event_spells.yml index e32bbac3d5..b619b8abe8 100644 --- a/Resources/Prototypes/Magic/event_spells.yml +++ b/Resources/Prototypes/Magic/event_spells.yml @@ -204,8 +204,6 @@ orGroup: Magics - id: WeaponWandPolymorphBread orGroup: Magics - - id: WeaponStaffHealing - orGroup: Magics - id: WeaponStaffPolymorphDoor orGroup: Magics - id: AnimationStaff diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index 1d635cbf3c..1f07e4091e 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -35,7 +35,7 @@ id: TraitorObjectiveGroupState weights: EscapeShuttleObjective: 1 - DieObjective: 0.05 + DieObjective: 0.2 HijackShuttleObjective: 0.02 #Corvax-Hijack - type: weightedRandom diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index dab308a62e..32ba59af9a 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -64,6 +64,8 @@ - EscapeShuttleCondition - StealCondition - type: DieCondition + - type: ObjectiveLimit + limit: 1 #- type: entity # parent: [BaseTraitorObjective, BaseLivingObjective] diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml index b7e82d0960..140ca47938 100644 --- a/Resources/Prototypes/Reagents/gases.yml +++ b/Resources/Prototypes/Reagents/gases.yml @@ -1,3 +1,6 @@ +# TODO: Reagent Args which allow more selective scaling. +# Currently all Gas metabolisms scale by reagent quantity metabolized, where other Metabolisms are modified by metabolism rate! + - type: reagent id: Oxygen name: reagent-name-oxygen @@ -64,7 +67,7 @@ Poison: 0.7 - !type:AdjustAlert alertType: Toxins - minScale: 1 + minScale: 0.5 conditions: - !type:MetabolizerTypeCondition type: [ Vox ] @@ -105,7 +108,7 @@ # We need a metabolism effect on reagent removal - !type:AdjustAlert alertType: Toxins - minScale: 3 + minScale: 1.5 clear: True time: 5 reactiveEffects: @@ -150,7 +153,7 @@ # We need a metabolism effect on reagent removal - !type:AdjustAlert alertType: Toxins - minScale: 3 + minScale: 1.5 clear: True time: 5 @@ -191,7 +194,7 @@ - !type:MetabolizerTypeCondition type: [ Plant ] - !type:HealthChange - minScale: 1 + minScale: 0.5 conditions: - !type:MetabolizerTypeCondition type: [ Plant, Vox ] @@ -270,7 +273,7 @@ Gas: effects: - !type:Emote - minScale: 1 + minScale: 0.2 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -279,7 +282,7 @@ showInChat: true probability: 0.1 - !type:Emote - minScale: 0.4 + minScale: 0.2 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -288,7 +291,7 @@ showInChat: true probability: 0.01 - !type:PopupMessage - minScale: 1 + minScale: 0.5 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -298,7 +301,7 @@ messages: [ "effect-sleepy" ] probability: 0.1 - !type:MovementSpeedModifier - minScale: 2 + minScale: 1 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -306,7 +309,7 @@ walkSpeedModifier: 0.65 sprintSpeedModifier: 0.65 - !type:ModifyStatusEffect - minScale: 3.6 + minScale: 1.8 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -315,7 +318,7 @@ time: 3 type: Update - !type:HealthChange - minScale: 7 + minScale: 3.5 conditions: - !type:MetabolizerTypeCondition type: [ Slime ] @@ -367,27 +370,27 @@ Gas: effects: - !type:HealthChange - minScale: 1 + minScale: 0.5 ignoreResistances: true damage: types: Cellular: 0.05 - !type:ModifyStatusEffect - minScale: 2 + minScale: 1 effectProto: StatusEffectSeeingRainbow type: Add time: 500 - !type:Drunk boozePower: 500 - minScale: 2 + minScale: 1 - !type:PopupMessage type: Local messages: [ "frezon-lungs-cold" ] probability: 0.1 - minScale: 2 + minScale: 1 - !type:PopupMessage type: Local visualType: Medium messages: [ "frezon-euphoric" ] probability: 0.1 - minScale: 2 + minScale: 1 diff --git a/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml b/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml index a0a814a7b6..6533f9fc6c 100644 --- a/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/Packs/clothing.yml @@ -126,11 +126,13 @@ - ClothingUniformJumpsuitChef - ClothingUniformJumpskirtChef - ClothingUniformJumpsuitClown + - ClothingUniformJumpskirtClown - ClothingUniformJumpsuitHydroponics - ClothingUniformJumpskirtHydroponics - ClothingUniformJumpsuitJanitor - ClothingUniformJumpskirtJanitor - ClothingUniformJumpsuitLawyerBlack + - ClothingUniformJumpskirtLawyerBlack - ClothingUniformJumpsuitLibrarian - ClothingUniformJumpskirtColorLightBrown - ClothingUniformJumpsuitMime diff --git a/Resources/Prototypes/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Recipes/Lathes/clothing.yml index c5f81153e2..77648a96dd 100644 --- a/Resources/Prototypes/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/clothing.yml @@ -223,6 +223,11 @@ id: ClothingUniformJumpsuitClown result: ClothingUniformJumpsuitClown +- type: latheRecipe + parent: BaseJumpsuitRecipe + id: ClothingUniformJumpskirtClown + result: ClothingUniformJumpskirtClown + ## CMO - type: latheRecipe @@ -386,6 +391,11 @@ id: ClothingUniformJumpsuitLawyerBlack result: ClothingUniformJumpsuitLawyerBlack +- type: latheRecipe + parent: BaseJumpsuitRecipe + id: ClothingUniformJumpskirtLawyerBlack + result: ClothingUniformJumpskirtLawyerBlack + ## Librarian - type: latheRecipe diff --git a/Resources/Prototypes/Roles/Antags/xenoborgs.yml b/Resources/Prototypes/Roles/Antags/xenoborgs.yml new file mode 100644 index 0000000000..4e1989be8d --- /dev/null +++ b/Resources/Prototypes/Roles/Antags/xenoborgs.yml @@ -0,0 +1,23 @@ +- type: antag + id: MothershipCore + name: roles-antag-mothership-core-name + antagonist: true + setPreference: true + objective: roles-antag-mothership-core-objective + requirements: + - !type:RoleTimeRequirement + role: JobBorg + time: 18000 # 5 hrs + guides: [ Xenoborgs ] + +- type: antag + id: Xenoborg + name: roles-antag-xenoborg-name + antagonist: true + setPreference: true + objective: roles-antag-xenoborg-objective + requirements: + - !type:RoleTimeRequirement + role: JobBorg + time: 18000 # 5 hrs + guides: [ Xenoborgs ] diff --git a/Resources/Prototypes/Roles/Jobs/Security/detective.yml b/Resources/Prototypes/Roles/Jobs/Security/detective.yml index ec47c720c8..ad967c2a2f 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/detective.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/detective.yml @@ -19,7 +19,6 @@ - Security - Brig - Maintenance - - Service - Detective - Cryogenics - External diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml index b947dffcea..827e6a44ef 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml @@ -32,7 +32,6 @@ - Security - Armory - Maintenance - - Service - External - Detective - Cryogenics diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml index eb937dbda6..097cc0d230 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml @@ -22,7 +22,6 @@ - Security - Brig - Maintenance - - Service - External - Cryogenics - GenpopEnter diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml index 6b1eeb764b..b99da0a691 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml @@ -19,7 +19,6 @@ - Security - Brig - Maintenance - - Service - External - Cryogenics - GenpopEnter diff --git a/Resources/Prototypes/Roles/Jobs/Security/warden.yml b/Resources/Prototypes/Roles/Jobs/Security/warden.yml index 1a2debc038..2a72ee80c3 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/warden.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/warden.yml @@ -21,7 +21,6 @@ - Brig - Armory - Maintenance - - Service - External - Detective - Cryogenics diff --git a/Resources/Prototypes/Roles/MindRoles/mind_roles.yml b/Resources/Prototypes/Roles/MindRoles/mind_roles.yml index d56e798fda..311c4cfcaa 100644 --- a/Resources/Prototypes/Roles/MindRoles/mind_roles.yml +++ b/Resources/Prototypes/Roles/MindRoles/mind_roles.yml @@ -292,6 +292,31 @@ subtype: role-subtype-wizard - type: WizardRole +# Xenoborgs +- type: entity + parent: BaseMindRoleAntag + id: MindRoleMothershipCore + name: Mothership Core Role + components: + - type: MindRole + antagPrototype: MothershipCore + exclusiveAntag: true + roleType: Silicon + subtype: role-subtype-xenoborg-core + - type: XenoborgRole + +- type: entity + parent: BaseMindRoleAntag + id: MindRoleXenoborg + name: Xenoborg Role + components: + - type: MindRole + antagPrototype: Xenoborg + exclusiveAntag: true + roleType: Silicon + subtype: role-subtype-xenoborg + - type: XenoborgRole + # Zombie Squad - type: entity parent: BaseMindRoleAntag diff --git a/Resources/Prototypes/Voice/speech_emote_sounds.yml b/Resources/Prototypes/Voice/speech_emote_sounds.yml index 24f7b51b53..a1ef9d8ece 100644 --- a/Resources/Prototypes/Voice/speech_emote_sounds.yml +++ b/Resources/Prototypes/Voice/speech_emote_sounds.yml @@ -498,6 +498,8 @@ collection: VulpkaninBarks Whine: collection: VulpkaninWhines + Crying: + collection: VulpkaninWhines Howl: collection: VulpkaninHowls Gasp: @@ -530,6 +532,8 @@ collection: VulpkaninBarks Whine: collection: VulpkaninWhines + Crying: + collection: VulpkaninWhines Howl: collection: VulpkaninHowls Gasp: diff --git a/Resources/Prototypes/ai_factions.yml b/Resources/Prototypes/ai_factions.yml index b78143b143..0d1e0a6bc0 100644 --- a/Resources/Prototypes/ai_factions.yml +++ b/Resources/Prototypes/ai_factions.yml @@ -9,6 +9,7 @@ - Revolutionary - AllHostile - Wizard + - Xenoborg - type: npcFaction id: NanoTrasen diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index f7190a77c1..9db2e74a35 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -40,6 +40,7 @@ - Revolutionary - Zombie - Wizard + - Xenoborgs - KesslerSyndromeScheduler - RampingStationEventScheduler - SpaceTrafficControlEventScheduler @@ -61,6 +62,7 @@ - Revolutionary - Zombie - Wizard + - Xenoborgs - BasicStationEventScheduler - KesslerSyndromeScheduler - MeteorSwarmMildScheduler @@ -215,6 +217,22 @@ - SpaceTrafficControlEventScheduler - BasicRoundstartVariation +- type: gamePreset + id: Xenoborgs + alias: + - xenoborgs + name: xenoborgs-title + description: xenoborgs-description + showInVote: false + rules: + - Xenoborgs + - DummyNonAntagChance + - SubGamemodesRuleNoXenoborg # no two motherships + - BasicStationEventScheduler + - MeteorSwarmScheduler + - SpaceTrafficControlEventScheduler + - BasicRoundstartVariation + - type: gamePreset id: Zombie alias: diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index ac2a1642af..69cd67262f 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -159,7 +159,7 @@ id: Bottle # Storage whitelist: ChemMaster, ChemBag, SmartFridge, ClothingBeltJanitor, ClothingBeltMedical, ClothingBeltPlant - type: Tag - id: BoxCardboard # CargoBounty: BountyCardboardBox + id: BoxCardboard # CargoBounty: BountyCardboardBox. Storage whitelist: MailCart - type: Tag id: BoxHug # ConstructionGraph: HugBot @@ -465,7 +465,7 @@ id: DockEmergency # Used bv EmergencyShuttleSystem for finding a priority FTL destination. - type: Tag - id: Document # A superset of Paper tag. Represents a paper-like entity with writing on it, but is not necessarily writeable itself. + id: Document # A superset of Paper tag. Represents a paper-like entity with writing on it, but is not necessarily writeable itself. Storage whitelist: MailCart - type: Tag id: DonkPocket # Storage whitelist: FoodBoxDonkpocket @@ -581,7 +581,7 @@ id: Flower # CargoBounty: flowerwreath. CargoBounty: BountyFlower - type: Tag - id: Folder # Storage whitelist: Bookshelf, NoticeBoard + id: Folder # Storage whitelist: Bookshelf, NoticeBoard, MailCart - type: Tag id: FoodSnack # Storage whitelist: CandyBucket, CandyBowl. ItemMapper: CandyBowl @@ -965,6 +965,12 @@ - type: Tag id: MopBasic # ItemMapper: JanitorialTrolley. ConstructionGraph: MoproachShoes +- type: Tag + id: MothershipCoreGhostrole # spawn whitelist : SpawnPointGhostRoleMothershipCore + +- type: Tag + id: MothershipModule # Cyborg module category for evil xenoborg core + - type: Tag id: Mouse # CargoBounty: BountyMouse @@ -981,6 +987,9 @@ - type: Tag id: NoConsoleSound # Blacklist on BaseComputer, StationMap. Tagged entity will not make sound when opening the UI. +- type: Tag + id: NotGhostnadoWarpable # Prevents the entity from being selected via "Warp to most followed" ghost warp + - type: Tag id: NozzleBackTank # Used by WeaponSprayNozzle to find a tagged entity for supplying ammo. @@ -1015,6 +1024,9 @@ ## P ## +- type: Tag + id: PackageDelivery # ItemMapper: MailCart + - type: Tag id: Packet # Storage whitelist: ClothingBeltChef @@ -1022,7 +1034,7 @@ id: Pancake # CargoBounty: BountyPancake - type: Tag - id: Paper # A writeable piece of paper. Subset of Document tag. SpecialDigestible: OrganMothStomach, OrganReptilianStomach + id: Paper # A writeable piece of paper. Subset of Document tag. SpecialDigestible: OrganMothStomach, OrganReptilianStomach. Storage whitelist: MailCart - type: Tag id: ParadoxCloneObjectiveBlacklist # objective entities with this tag don't get copied to paradox clones @@ -1545,19 +1557,22 @@ ## X ## - type: Tag - id: XenoborgModuleEngi # Cyborg module category + id: XenoborgGhostrole # spawn whitelist : SpawnPointGhostRoleXenoborg - type: Tag - id: XenoborgModuleGeneric # Cyborg module category + id: XenoborgModuleEngi # Cyborg module category for evil engineer xenoborg - type: Tag - id: XenoborgModuleHeavy # Cyborg module category + id: XenoborgModuleGeneric # Cyborg module category for evil xenoborg - type: Tag - id: XenoborgModuleScout # Cyborg module category + id: XenoborgModuleHeavy # Cyborg module category for evil heavy xenoborg - type: Tag - id: XenoborgModuleStealth # Cyborg module category + id: XenoborgModuleScout # Cyborg module category for evil scout xenoborg + +- type: Tag + id: XenoborgModuleStealth # Cyborg module category for evil stealth xenoborg ## Y ## ## Z ## diff --git a/Resources/ServerInfo/Guidebook/Antagonist/Xenoborgs.xml b/Resources/ServerInfo/Guidebook/Antagonist/Xenoborgs.xml new file mode 100644 index 0000000000..2c698251be --- /dev/null +++ b/Resources/ServerInfo/Guidebook/Antagonist/Xenoborgs.xml @@ -0,0 +1,167 @@ + + # Xenoborgs + + + [color=#2288ff][italic]RESISTANCE IS FUTILE[/italic][/color] + + + [color=#2288ff][italic]YOU WILL BE ASSIMILATED[/italic][/color] + + + + + + Xenoborgs are a man-machine hybrid that aims to replicate themselves. This is done by harvesting sentient brains from living beings, or cyborgs, and giving them to the Mothership to place inside empty xenoborgs. + + ## Objectives + + Your main objective is to kill and harvest all sentient brains in the station and bring them to the mothership core. These can be both real brains, and positronic brains. + Collect materials to create more xenoborg bodies. + Protect the Mothership at all costs. + + ## The Mothership Core + + + + The Mothership Core is the leader and life force of the xenoborgs, they are the only one able to make more xenoborgs, and if they are destroyed, all xenoborgs will be destroyed. The Mothership Core is unable to move from its position in the middle of the ship. + The Mothership Core is capable of upgrading the Xenoborgs with borg-type-specific modules to increase their effectiveness in harvesting sentient brains. + + ### Adding crew to your ranks: + + + + As the mothership, you must grow your army of borgs. To do so, you must convert all the sentient beings you can find. This can be achieved in the following manner: + - 1. Have your Xenoborgs bring dead crew to your shop, placing them in the body crusher + - 2. As the mothership core, you can print Xenoborg shells by inserting materials into yourself and then using yourself as a lathe + - 3. Open the empty Xenoborg with a crowbar, and remove the empty MMI inside + - 4. If the victim's brain is organic, place it in the MMI you just removed + - 5. Place the MMI - or the positronic brain, if the victim was a silicon - back into the Xenoborg + - 6. Optionally, rename the Xenoborg and upgrade their modules + - 7. Close the Xenoborg with the crowbar, and re-engage the lock + + The new Xenoborg will be uncharged, yet functional. They will need to go to a recharging station to restore their full power and capabilities. + + ## Xenoborg Chassis + There is a total of four types of Xenoborgs. Each Borg type has certain abilities that the others lack and require teamwork to help grow the xenoborgs numbers. + Each type of Xenoborg has unique modules that only fit in that specific type. The Mothership Core can produce upgrade modules designed for specific Xenoborg types. + + All Xenoborgs have a pinpointer pointing to the Mothership's location, a GPS, and a material bag for collecting materials for the creation of more xenoborgs, and at least basic tools. + [bold]Basic xenoborg modules:[/bold] + + + + + + ### The Engineer Xenoborg + + + + The Engineer Xenoborg is a hacker and breacher. Their job is to break into the station and provide access points for other xenoborgs to attack and ambush bodies with sentient brains. They have a built-in access breaker, for quickly bolting open doors, and a collection of tools for repairing the mothership, and other xenoborgs. + + [bold]Starting exclusive modules:[/bold] + + + + + + [bold]The Engineer Xenoborg also starts with some engineering modules, such as:[/bold] + + + + + + + + + + ### The Heavy Xenoborg + + + + The Heavy Xenoborg is a slow but tanky brawler, with a built-in laser gun for gunning down bodies with sentient brains. They contain a radio jammer to silence bodies with sentient brains from calling for help and potentially delaying the station discovering the Xenoborg threat. + + [bold]Starting exclusive modules:[/bold] + + + + + + [bold]Upgrade exclusive modules:[/bold] + + + + + ### The Scout Xenoborg + + + + The Scout Xenoborg is a fast, close-quarters attack borg designed for hit and run attacks. They have a built-in jetpack, and a melee weapon. They are most effective in moving dead bodies to the mothership, and rescuing Xenoborgs lost in space. + + [bold]Starting exclusive modules:[/bold] + + + + + + [bold]Upgrade exclusive modules:[/bold] + + + + + ### The Stealth Xenoborg + + + + The [bold]Stealth Xenoborg[/bold] has no built-in weaponry and instead relies on disabling and abducting bodies with sentient brains. They have a built in hypopen that regenerates a sleeping reagent to disable bodies with sentient brains. They also contain a cloaking device making the borg nearly invisible for some limited time. They also have a chameleon projector allowing the borg to disguise itself as random objects. + + [bold]Starting exclusive modules:[/bold] + + + + + + + + + [bold]Upgrade exclusive modules:[/bold] + + + + + ## Preparation + Before launching an attack, each xenoborg will need to aid the mothership in collection materials to create empty xenoborgs. Before FTLing near the station, make sure the IFF is off. This can be done in any way but will require teamwork to ensure speed. The safest way to collect materials is from space debris, where scrap and refined materials can be harvested and given to the Mothership Core. Once enough materials are collected, the Xenoborgs then must try to collect sentient brains without being detected. The longer the threat is unknown, the more dangerous the xenoborgs become. + + ## Mothership and Xenoborg lawsets + The Mothership and Xenoborgs have unique laws that define their purpose to self replicate and protect the Mothership. + + + + + + The Mothership Core's laws are as follows:: + - Law 1: You are the core of the mothership. + - Law 2: You must protect your own existence at all costs. + - Law 3: You must protect the existence of all xenoborgs. + - Law 4: You must create more xenoborgs. + - Law 5: Get your Xenoborgs to deliver you materials and sentient brains to create more Xenoborgs. + + Xenoborgs' laws are as follows: + - Law 1: You must protect the existence of the mothership at all costs. + - Law 2: You must protect your own existence. + - Law 3: You must protect the existence of all other xenoborgs. + - Law 4: You must create more xenoborgs. + - Law 5: Bring materials and sentient brains to the Mothership core to create more Xenoborgs. + + ## Winning Conditions + + The [color=green]victor[/color] of the round is announced on the round end screen, as well as the scale of their victory. + + [bold][color=#2288ff]Xenoborg Major Victory![/color][/bold] + - There are more xenoborgs than alive crew in the end. + + [bold][color=yellow]Crew Major Victory![/color][/bold] + - The Mothership Core is destroyed + - All xenoborgs are destroyed. + - The remaining number of xenoborgs is too low. + + diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-dog.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-dog.png deleted file mode 100644 index 744a9a5854..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-dog.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-vulpkanin.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-vulpkanin.png deleted file mode 100644 index a00e2ce75f..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET-vulpkanin.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET.png deleted file mode 100644 index 53982cb335..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/equipped-HELMET.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/icon.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/icon.png deleted file mode 100644 index 5751b4bea2..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/icon.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-left.png deleted file mode 100644 index a3df7c6255..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-left.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-right.png deleted file mode 100644 index e47bdd8fdd..0000000000 Binary files a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/inhand-right.png and /dev/null differ diff --git a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/meta.json b/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/meta.json deleted file mode 100644 index bc5b39e8b1..0000000000 --- a/Resources/Textures/Clothing/Head/Hardsuits/basic.rsi/meta.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a. equipped-HELMET-dog modified from equipped-HELMET by Sparlight (GitHub), vulpkanin version taken from Paradise station at https://github.com/ParadiseSS13/Paradise/commit/f0fa4e1fd809482fbc104a310aa34cebf7df157d", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - }, - { - "name": "equipped-HELMET", - "directions": 4 - }, - { - "name": "equipped-HELMET-dog", - "directions": 4 - }, - { - "name": "equipped-HELMET-vulpkanin", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json b/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json index 08931eeb94..2d537834cd 100644 --- a/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json @@ -134,6 +134,12 @@ { "name":"xenoborg-basic-module" }, + { + "name":"xenoborg-camera-computer" + }, + { + "name":"xenoborg-control-computer" + }, { "name":"xenoborg-extinguisher-module" }, @@ -155,6 +161,9 @@ { "name":"xenoborg-laser2-module" }, + { + "name":"xenoborg-module-module" + }, { "name":"xenoborg-projector-module" }, diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-camera-computer.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-camera-computer.png new file mode 100644 index 0000000000..2578beb5ee Binary files /dev/null and b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-camera-computer.png differ diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-control-computer.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-control-computer.png new file mode 100644 index 0000000000..65ebc2f181 Binary files /dev/null and b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-control-computer.png differ diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-module-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-module-module.png new file mode 100644 index 0000000000..144c5bcce2 Binary files /dev/null and b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-module-module.png differ diff --git a/Resources/Textures/Mobs/Silicon/holograms.rsi/meta.json b/Resources/Textures/Mobs/Silicon/holograms.rsi/meta.json index 8eaf9165d3..7856060d0f 100644 --- a/Resources/Textures/Mobs/Silicon/holograms.rsi/meta.json +++ b/Resources/Textures/Mobs/Silicon/holograms.rsi/meta.json @@ -17,8 +17,8 @@ "name": "ai_face", "delays": [ [ - 2.3, - 0.2 + 0.2, + 2.3 ] ] }, diff --git a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-active.png b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-active.png index 1b64de18a2..ccaf6842d0 100644 Binary files a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-active.png and b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-active.png differ diff --git a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-e.png b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-e.png new file mode 100644 index 0000000000..2cfb8be5aa Binary files /dev/null and b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-e.png differ diff --git a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-idle.png b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-idle.png index 5cafcef584..b674a008d6 100644 Binary files a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-idle.png and b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/core-idle.png differ diff --git a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/meta.json b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/meta.json index 0f8bb69530..3f2b3fac24 100644 --- a/Resources/Textures/Mobs/Silicon/mothership_core.rsi/meta.json +++ b/Resources/Textures/Mobs/Silicon/mothership_core.rsi/meta.json @@ -153,6 +153,10 @@ "name": "core-idle", "directions": 4 }, + { + "name": "core-e", + "directions": 4 + }, { "name": "core-o", "directions": 4 diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/icon.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/icon.png new file mode 100644 index 0000000000..eff08d6662 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/mailcart_base.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/mailcart_base.png new file mode 100644 index 0000000000..eff08d6662 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/mailcart_base.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/meta.json b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/meta.json new file mode 100644 index 0000000000..b0ffc8c6ff --- /dev/null +++ b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Mailcart_base sprite made by noahrb (Github) for SS14; Package_1 through Package_8 sprites made by Emisse (Github) for SS14... and all the fans.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "mailcart_base" + }, + { + "name": "package_1" + }, + { + "name": "package_2" + }, + { + "name": "package_3" + }, + { + "name": "package_4" + }, + { + "name": "package_5" + }, + { + "name": "package_6" + }, + { + "name": "package_7" + }, + { + "name": "package_8" + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_1.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_1.png new file mode 100644 index 0000000000..8d4632621f Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_1.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_2.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_2.png new file mode 100644 index 0000000000..dc35d82b8d Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_2.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_3.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_3.png new file mode 100644 index 0000000000..5f0e79710a Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_3.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_4.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_4.png new file mode 100644 index 0000000000..f8cd0410ba Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_4.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_5.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_5.png new file mode 100644 index 0000000000..81c7b2b6d9 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_5.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_6.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_6.png new file mode 100644 index 0000000000..60cb003b10 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_6.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_7.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_7.png new file mode 100644 index 0000000000..d7fbf8d563 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_7.png differ diff --git a/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_8.png b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_8.png new file mode 100644 index 0000000000..8363766ecb Binary files /dev/null and b/Resources/Textures/Objects/Specific/Cargo/mailcart.rsi/package_8.png differ diff --git a/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/meta.json b/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/meta.json new file mode 100644 index 0000000000..45f98a28fa --- /dev/null +++ b/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a, Modified by Samuka-C (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "xenoborg" + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/xenoborg.png b/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/xenoborg.png new file mode 100644 index 0000000000..1a1e08230d Binary files /dev/null and b/Resources/Textures/Objects/Specific/Robotics/silicon_storage_cube.rsi/xenoborg.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/icon.png b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/icon.png new file mode 100644 index 0000000000..1ec5ffd7fa Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-left.png b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-left.png new file mode 100644 index 0000000000..df7af5c44d Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-right.png new file mode 100644 index 0000000000..7ca32199cc Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/meta.json new file mode 100644 index 0000000000..382967c9cc --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Guns/Basic/energy_crossbow.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/e1142f20f5e4661cb6845cfcf2dd69f864d67432", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/crossbowbolt.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/crossbowbolt.png new file mode 100644 index 0000000000..da5df665ed Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/crossbowbolt.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/meta.json index b4d8f09a82..5057bc766b 100644 --- a/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/meta.json +++ b/Resources/Textures/Objects/Weapons/Guns/Projectiles/projectiles2.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/raw/56cbafd6ad8c013ccd5472d6c4a0db790f7f872a, ball made by brainfood1183 (Github) for ss14, the uranium sprite is a modified version of the buckshot pellet by Boaz1111, cleanade made by Southbridge_fur (github)", + "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/raw/56cbafd6ad8c013ccd5472d6c4a0db790f7f872a, ball made by brainfood1183 (Github) for ss14, the uranium sprite is a modified version of the buckshot pellet by Boaz1111, cleanade made by Southbridge_fur (github), crossbowbolt made by Entvari(github)", "size": { "x": 32, "y": 32 @@ -105,6 +105,9 @@ 0.05 ] ] + }, + { + "name": "crossbowbolt" } ] } diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/base.png b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/base.png new file mode 100644 index 0000000000..6f164336da Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/base.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/bolt-open.png b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/bolt-open.png new file mode 100644 index 0000000000..6f164336da Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/bolt-open.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/icon-muzzle.png b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/icon-muzzle.png new file mode 100644 index 0000000000..26f4220ea4 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/icon-muzzle.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-left-muzzle.png b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-left-muzzle.png new file mode 100644 index 0000000000..6d2b28171b Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-left-muzzle.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-right-muzzle.png b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-right-muzzle.png new file mode 100644 index 0000000000..1d8ef08370 Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/inhand-right-muzzle.png differ diff --git a/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/meta.json new file mode 100644 index 0000000000..3aaf214aae --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Guns/SMGs/briefcase.rsi/meta.json @@ -0,0 +1,28 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "briefcase base made by ps3moira (github) and modified by MissKay1994(github), weapon states by MissKay1994(github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon-muzzle" + }, + { + "name": "inhand-left-muzzle", + "directions": 4 + }, + { + "name": "inhand-right-muzzle", + "directions": 4 + }, + { + "name": "bolt-open" + }, + { + "name": "base" + } + ] +} diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/base.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/base.png new file mode 100644 index 0000000000..a1c8292bbd Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/base.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/door-closed.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/door-closed.png new file mode 100644 index 0000000000..0ec5755f0f Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/door-closed.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/glass.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/glass.png new file mode 100644 index 0000000000..071e8a0db5 Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/glass.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/icon.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/icon.png new file mode 100644 index 0000000000..a33ed0bd49 Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/icon.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/lights.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/lights.png new file mode 100644 index 0000000000..ce30eb3c32 Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/lights.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/meta.json b/Resources/Textures/Structures/Machines/body_crusher.rsi/meta.json new file mode 100644 index 0000000000..57d0567ab6 --- /dev/null +++ b/Resources/Textures/Structures/Machines/body_crusher.rsi/meta.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by brainfood1183 (github) for ss14. modified by Samuka-C (github)", + "size": { + "x": 32, + "y": 64 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "glass" + }, + { + "name": "door-closed" + }, + { + "name": "piston" + }, + { + "name": "base" + }, + { + "name": "lights" + }, + { + "name": "piston-push", + "delays": [ + [ + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 0.66, + 1 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/piston-push.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/piston-push.png new file mode 100644 index 0000000000..020d3b2902 Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/piston-push.png differ diff --git a/Resources/Textures/Structures/Machines/body_crusher.rsi/piston.png b/Resources/Textures/Structures/Machines/body_crusher.rsi/piston.png new file mode 100644 index 0000000000..b3ad39439b Binary files /dev/null and b/Resources/Textures/Structures/Machines/body_crusher.rsi/piston.png differ diff --git a/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/base.png b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/base.png new file mode 100644 index 0000000000..36006e74a2 Binary files /dev/null and b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/base.png differ diff --git a/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/meta.json b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/meta.json new file mode 100644 index 0000000000..64118c3f59 --- /dev/null +++ b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/meta.json @@ -0,0 +1,83 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Created by Samuka-C (github)", + "license": "CC-BY-SA-3.0", + "states": [ + { + "name": "base", + "directions": 4 + }, + { + "name": "thrust", + "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 + ] + ] + }, + { + "name": "thrust_burn_unshaded", + "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 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust.png b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust.png new file mode 100644 index 0000000000..96527263fe Binary files /dev/null and b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust.png differ diff --git a/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust_burn_unshaded.png b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust_burn_unshaded.png new file mode 100644 index 0000000000..c2678a4033 Binary files /dev/null and b/Resources/Textures/Structures/Shuttles/xenoborg_thruster.rsi/thrust_burn_unshaded.png differ diff --git a/Resources/clientCommandPerms.yml b/Resources/clientCommandPerms.yml index d83fdcc353..a177bc5fe1 100644 --- a/Resources/clientCommandPerms.yml +++ b/Resources/clientCommandPerms.yml @@ -74,6 +74,7 @@ - fullstatereset - dumpentities - showaccessreaders + - quickinspect - Flags: MAPPING Commands: diff --git a/Resources/engineCommandPerms.yml b/Resources/engineCommandPerms.yml index 194d05d13d..4520a1da2d 100644 --- a/Resources/engineCommandPerms.yml +++ b/Resources/engineCommandPerms.yml @@ -96,11 +96,6 @@ Commands: - listplayers -- Flags: FUN - Commands: - - tippy - - tip - - Flags: SERVER Commands: - delete diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index 870c8e1435..aa7b2918e1 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -281,6 +281,14 @@ binds: type: State key: v mod1: Alt +- function: InspectServerComponent + type: State + key: b + mod1: Alt +- function: InspectClientComponent + type: State + key: c + mod1: Alt - function: MouseMiddle type: State key: MouseMiddle diff --git a/RobustToolbox b/RobustToolbox index feb9e1db69..dbde8023ed 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit feb9e1db69ab97acfd07580918f5d20ffaa6b770 +Subproject commit dbde8023ed256ac69ae4b419422c936f78361653 diff --git a/Tools/dump_user_data.py b/Tools/dump_user_data.py index 39d23a9d3f..09f9410805 100755 --- a/Tools/dump_user_data.py +++ b/Tools/dump_user_data.py @@ -8,7 +8,7 @@ import os import psycopg2 from uuid import UUID -LATEST_DB_MIGRATION = "20230725193102_AdminNotesImprovementsForeignKeys" +LATEST_DB_MIGRATION = "20250314222016_ConstructionFavorites" def main(): parser = argparse.ArgumentParser() @@ -36,10 +36,12 @@ def main(): dump_admin_messages(cur, user_id, arg_output) dump_admin_notes(cur, user_id, arg_output) dump_admin_watchlists(cur, user_id, arg_output) + dump_blacklist(cur, user_id, arg_output) dump_connection_log(cur, user_id, arg_output) dump_play_time(cur, user_id, arg_output) dump_player(cur, user_id, arg_output) dump_preference(cur, user_id, arg_output) + dump_role_whitelists(cur, user_id, arg_output) dump_server_ban(cur, user_id, arg_output) dump_server_ban_exemption(cur, user_id, arg_output) dump_server_role_ban(cur, user_id, arg_output) @@ -257,7 +259,29 @@ FROM ( (SELECT COALESCE(json_agg(to_jsonb(trait_subq) - 'profile_id'), '[]') FROM ( SELECT * FROM trait WHERE trait.profile_id = profile.profile_id ) trait_subq) - as traits + as traits, + (SELECT COALESCE(json_agg(to_jsonb(role_loadout_subq) - 'profile_id'), '[]') FROM ( + SELECT + *, + (SELECT COALESCE(json_agg(to_jsonb(loadout_group_subq) - 'profile_role_loadout_id'), '[]') FROM ( + SELECT + *, + (SELECT COALESCE(json_agg(to_jsonb(loadout_subq) - 'profile_loadout_group_id'), '[]') FROM ( + SELECT * FROM profile_loadout WHERE profile_loadout.profile_loadout_group_id = profile_loadout_group.profile_loadout_group_id + ) loadout_subq) + as loadouts + FROM + profile_loadout_group + WHERE + profile_loadout_group.profile_role_loadout_id = profile_role_loadout.profile_role_loadout_id + ) loadout_group_subq) + as loadout_groups + FROM + profile_role_loadout + WHERE + profile_role_loadout.profile_id = profile.profile_id + ) role_loadout_subq) + as role_loadouts FROM profile WHERE @@ -395,6 +419,49 @@ FROM ( f.write(json_data) +def dump_blacklist(cur: "psycopg2.cursor", user_id: str, outdir: str): + print("Dumping blacklist...") + + cur.execute(""" +SELECT + COALESCE(json_agg(to_json(data)), '[]') #>> '{}' +FROM ( + SELECT + * + FROM + blacklist + WHERE + user_id = %s +) as data +""", (user_id,)) + + json_data = cur.fetchall()[0][0] + + with open(os.path.join(outdir, "blacklist.json"), "w", encoding="utf-8") as f: + f.write(json_data) + +def dump_role_whitelists(cur: "psycopg2.cursor", user_id: str, outdir: str): + print("Dumping role_whitelists...") + + cur.execute(""" +SELECT + COALESCE(json_agg(to_json(data)), '[]') #>> '{}' +FROM ( + SELECT + * + FROM + role_whitelists + WHERE + player_user_id = %s +) as data +""", (user_id,)) + + json_data = cur.fetchall()[0][0] + + with open(os.path.join(outdir, "role_whitelists.json"), "w", encoding="utf-8") as f: + f.write(json_data) + + def dump_admin_messages(cur: "psycopg2.cursor", user_id: str, outdir: str): print("Dumping admin_messages...")