From 72832bf19dd509afb9069c1f1f92f80882a4373d Mon Sep 17 00:00:00 2001 From: AutoOtter Date: Fri, 30 Aug 2024 19:24:13 -0400 Subject: [PATCH 001/414] Meteor rock debuff (#31651) * Makes meteor swarms spawn meteorite walls with 1/10 health of an asteroid wall. * Changed MeteorRock prototype base - Rebased MeteorRock to AsteroidRock from Basewall - MeteorRock now only changes the Destructible damage value * Tried to fix comments --- .../Entities/Structures/Walls/meteor.yml | 219 ++++++++++++++++++ .../Prototypes/GameRules/meteorswarms.yml | 20 +- 2 files changed, 229 insertions(+), 10 deletions(-) create mode 100644 Resources/Prototypes/Entities/Structures/Walls/meteor.yml diff --git a/Resources/Prototypes/Entities/Structures/Walls/meteor.yml b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml new file mode 100644 index 0000000000..6f310e3b74 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml @@ -0,0 +1,219 @@ +# These define Meteor Walls separate from Asteroid walls so they have different properties +- type: entity + id: MeteorRock + parent: AsteroidRock + name: meteorite rock + description: What remains of a meteorite. + components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 12 #This change makes meteorite walls easier to destroy for cleanup + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/break_stone.ogg + params: + volume: -6 + +# Ore veins +- type: entity + id: MeteorRockCoal + parent: MeteorRock + description: An ore vein rich with coal. + suffix: Coal + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreCoal + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_coal + +- type: entity + id: MeteorRockGold + parent: MeteorRock + description: An ore vein rich with gold. + suffix: Gold + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreGold + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_gold + +- type: entity + id: MeteorRockDiamond + parent: MeteorRock + description: An ore vein rich with diamonds. + suffix: Diamond + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreDiamond + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_diamond + +- type: entity + id: MeteorRockPlasma + parent: MeteorRock + description: An ore vein rich with plasma. + suffix: Plasma + components: + - type: OreVein + oreChance: 1.0 + currentOre: OrePlasma + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_phoron + +- type: entity + id: MeteorRockQuartz + parent: MeteorRock + description: An ore vein rich with quartz. + suffix: Quartz + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreSpaceQuartz + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_quartz + +- type: entity + id: MeteorRockSilver + parent: MeteorRock + description: An ore vein rich with silver. + suffix: Silver + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreSilver + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_silver +# Tin name is a holdover from the asteroid.yml prototype. +- type: entity + id: MeteorRockTin + parent: MeteorRock + description: An ore vein rich with iron. + suffix: Iron + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreSteel + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_tin + +- type: entity + id: MeteorRockUranium + parent: MeteorRock + description: An ore vein rich with uranium. + suffix: Uranium + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreUranium + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_uranium + +- type: entity + id: MeteorRockBananium + parent: MeteorRock + description: An ore vein rich with bananium. + suffix: Bananium + components: + - type: OreVein + oreChance: 1.0 + currentOre: OreBananium + - type: Sprite + layers: + - state: rock_asteroid + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - state: rock_bananium diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index 799b353eab..6203ee35ab 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -38,16 +38,16 @@ - type: weightedRandomEntity id: MeteorSpawnAsteroidWallTable weights: - AsteroidRock: 10 - AsteroidRockCoal: 5 - AsteroidRockQuartz: 5 - AsteroidRockTin: 5 - AsteroidRockSilver: 2 - AsteroidRockGold: 2 - AsteroidRockPlasma: 2 - AsteroidRockDiamond: 2 - AsteroidRockUranium: 0.5 - AsteroidRockBananium: 0.5 + MeteorRock: 10 + MeteorRockCoal: 5 + MeteorRockQuartz: 5 + MeteorRockTin: 5 + MeteorRockSilver: 2 + MeteorRockGold: 2 + MeteorRockPlasma: 2 + MeteorRockDiamond: 2 + MeteorRockUranium: 0.5 + MeteorRockBananium: 0.5 # Event Schedulers From 9183c50d81a30c6bfdbe5cbbf8f5092a4002519c Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 30 Aug 2024 23:25:20 +0000 Subject: [PATCH 002/414] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2a12003ebf..da8524f3b8 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: lzk228 - changes: - - message: Fixed ability for mime to not choose any mask. - type: Fix - id: 6751 - time: '2024-06-15T21:32:49.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29056 - author: FunTust changes: - message: Fixed hair disappearing when hats are tucked away in a pocket. @@ -3843,3 +3836,10 @@ id: 7250 time: '2024-08-30T10:34:25.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31628 +- author: AutoOtter + changes: + - message: Greatly reduced meteorite wall health for easier cleanup and repair. + type: Tweak + id: 7251 + time: '2024-08-30T23:24:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31651 From 849d3d9f5c43bcdc91b1f771a671a9abbe3f81e3 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 31 Aug 2024 12:35:30 +1000 Subject: [PATCH 003/414] Fix test threading (#31669) --- .../Tests/Actions/ActionPvsDetachTest.cs | 24 ++++++++++++------- .../Tests/Buckle/BuckleDragTest.cs | 6 ++++- Content.IntegrationTests/Tests/CargoTest.cs | 9 ++++--- .../Tests/Commands/SuicideCommandTests.cs | 6 ++--- .../Tests/Shuttle/DockTest.cs | 3 ++- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs b/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs index 420a90a50b..b07c352c81 100644 --- a/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs +++ b/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs @@ -32,11 +32,16 @@ public sealed class ActionPvsDetachTest // PVS-detach action entities // We do this by just giving them the ghost layer var visSys = server.System(); - var enumerator = server.Transform(ent).ChildEnumerator; - while (enumerator.MoveNext(out var child)) + + await server.WaitPost(() => { - visSys.AddLayer(child, (int) VisibilityFlags.Ghost); - } + var enumerator = server.Transform(ent).ChildEnumerator; + while (enumerator.MoveNext(out var child)) + { + visSys.AddLayer(child, (int)VisibilityFlags.Ghost); + } + }); + await pair.RunTicksSync(5); // Client's actions have left been detached / are out of view, but action comp state has not changed @@ -44,11 +49,14 @@ public sealed class ActionPvsDetachTest Assert.That(cSys.GetActions(cEnt).Count(), Is.EqualTo(initActions)); // Re-enter PVS view - enumerator = server.Transform(ent).ChildEnumerator; - while (enumerator.MoveNext(out var child)) + await server.WaitPost(() => { - visSys.RemoveLayer(child, (int) VisibilityFlags.Ghost); - } + var enumerator = server.Transform(ent).ChildEnumerator; + while (enumerator.MoveNext(out var child)) + { + visSys.RemoveLayer(child, (int) VisibilityFlags.Ghost); + } + }); await pair.RunTicksSync(5); Assert.That(sys.GetActions(ent).Count(), Is.EqualTo(initActions)); Assert.That(cSys.GetActions(cEnt).Count(), Is.EqualTo(initActions)); diff --git a/Content.IntegrationTests/Tests/Buckle/BuckleDragTest.cs b/Content.IntegrationTests/Tests/Buckle/BuckleDragTest.cs index 82d5d3baa0..19e8aba182 100644 --- a/Content.IntegrationTests/Tests/Buckle/BuckleDragTest.cs +++ b/Content.IntegrationTests/Tests/Buckle/BuckleDragTest.cs @@ -34,7 +34,11 @@ public sealed class BuckleDragTest : InteractionTest Assert.That(pullable.BeingPulled, Is.False); // Strap the human to the chair - Assert.That(Server.System().TryBuckle(sUrist, SPlayer, STarget.Value)); + await Server.WaitAssertion(() => + { + Assert.That(Server.System().TryBuckle(sUrist, SPlayer, STarget.Value)); + }); + await RunTicks(5); Assert.That(buckle.Buckled, Is.True); Assert.That(buckle.BuckledTo, Is.EqualTo(STarget)); diff --git a/Content.IntegrationTests/Tests/CargoTest.cs b/Content.IntegrationTests/Tests/CargoTest.cs index 89018d9d17..1b29e7ea7a 100644 --- a/Content.IntegrationTests/Tests/CargoTest.cs +++ b/Content.IntegrationTests/Tests/CargoTest.cs @@ -257,9 +257,12 @@ public sealed class CargoTest var entManager = server.ResolveDependency(); var priceSystem = entManager.System(); - var ent = entManager.SpawnEntity("StackEnt", MapCoordinates.Nullspace); - var price = priceSystem.GetPrice(ent); - Assert.That(price, Is.EqualTo(100.0)); + await server.WaitAssertion(() => + { + var ent = entManager.SpawnEntity("StackEnt", MapCoordinates.Nullspace); + var price = priceSystem.GetPrice(ent); + Assert.That(price, Is.EqualTo(100.0)); + }); await pair.CleanReturnAsync(); } diff --git a/Content.IntegrationTests/Tests/Commands/SuicideCommandTests.cs b/Content.IntegrationTests/Tests/Commands/SuicideCommandTests.cs index 540e86c650..e1eef2be4a 100644 --- a/Content.IntegrationTests/Tests/Commands/SuicideCommandTests.cs +++ b/Content.IntegrationTests/Tests/Commands/SuicideCommandTests.cs @@ -143,10 +143,10 @@ public sealed class SuicideCommandTests mobStateComp = entManager.GetComponent(player); mobThresholdsComp = entManager.GetComponent(player); damageableComp = entManager.GetComponent(player); - }); - if (protoMan.TryIndex("Slash", out var slashProto)) - damageableSystem.TryChangeDamage(player, new DamageSpecifier(slashProto, FixedPoint2.New(46.5))); + if (protoMan.TryIndex("Slash", out var slashProto)) + damageableSystem.TryChangeDamage(player, new DamageSpecifier(slashProto, FixedPoint2.New(46.5))); + }); // Check that running the suicide command kills the player // and properly ghosts them without them being able to return to their body diff --git a/Content.IntegrationTests/Tests/Shuttle/DockTest.cs b/Content.IntegrationTests/Tests/Shuttle/DockTest.cs index a1aa462a69..f6e99596e9 100644 --- a/Content.IntegrationTests/Tests/Shuttle/DockTest.cs +++ b/Content.IntegrationTests/Tests/Shuttle/DockTest.cs @@ -97,13 +97,14 @@ public sealed class DockTest : ContentUnitTest var entManager = server.ResolveDependency(); var dockingSystem = entManager.System(); var mapSystem = entManager.System(); + MapGridComponent mapGrid = default!; - var mapGrid = entManager.AddComponent(map.MapUid); var shuttle = EntityUid.Invalid; // Spawn shuttle and affirm no valid docks. await server.WaitAssertion(() => { + mapGrid = entManager.AddComponent(map.MapUid); entManager.DeleteEntity(map.Grid); Assert.That(entManager.System().TryLoad(otherMap.MapId, "/Maps/Shuttles/emergency.yml", out var rootUids)); shuttle = rootUids[0]; From 9685abea2093821a7052721bee7bc1892f9a36dc Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sat, 31 Aug 2024 05:02:58 +0200 Subject: [PATCH 004/414] Fix revenant being blocked by walls (#31670) fix revenant being blocked by walls --- Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index 19f43bf550..cf964822f1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -1,8 +1,8 @@ - type: entity id: MobRevenant parent: - - BaseMob - Incorporeal + - BaseMob name: revenant description: A spooky ghostie. components: From f5f777b924ddd6f98b200ac402299774879a009e Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 31 Aug 2024 03:04:05 +0000 Subject: [PATCH 005/414] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index da8524f3b8..ed7346e1da 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: FunTust - changes: - - message: Fixed hair disappearing when hats are tucked away in a pocket. - type: Fix - id: 6752 - time: '2024-06-15T21:42:13.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/28949 - author: Cojoke-dot changes: - message: You can now find Jackboots in the security load-outs @@ -3843,3 +3836,10 @@ id: 7251 time: '2024-08-30T23:24:13.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31651 +- author: slarticodefast + changes: + - message: The revenant can now fly through walls again. + type: Fix + id: 7252 + time: '2024-08-31T03:02:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31670 From 8ca4337bd86a56fa85a051a6d45c0913e2ba6d46 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 31 Aug 2024 14:49:49 +1000 Subject: [PATCH 006/414] Update submodule to 233.0.0 (#31673) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index f659b2b58c..c558a0327b 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit f659b2b58c7d0784f3582b93ba368a529558d3fd +Subproject commit c558a0327bc8179e2618a4587e99c73cb3ae094c From 2d43bb6b3897d805b9f792c3d8aed85964f9174a Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 31 Aug 2024 07:49:20 +0200 Subject: [PATCH 007/414] Fix broken tests directly mutating entities from wrong thread. (#31647) * Fix broken tests directly mutating entities from wrong thread. * fix build * gundam * stuff --------- Co-authored-by: metalgearsloth --- .../Tests/Actions/ActionPvsDetachTest.cs | 8 +++----- Content.IntegrationTests/Tests/CargoTest.cs | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs b/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs index b07c352c81..45addff00b 100644 --- a/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs +++ b/Content.IntegrationTests/Tests/Actions/ActionPvsDetachTest.cs @@ -32,16 +32,14 @@ public sealed class ActionPvsDetachTest // PVS-detach action entities // We do this by just giving them the ghost layer var visSys = server.System(); - - await server.WaitPost(() => + server.Post(() => { var enumerator = server.Transform(ent).ChildEnumerator; while (enumerator.MoveNext(out var child)) { - visSys.AddLayer(child, (int)VisibilityFlags.Ghost); + visSys.AddLayer(child, (int) VisibilityFlags.Ghost); } }); - await pair.RunTicksSync(5); // Client's actions have left been detached / are out of view, but action comp state has not changed @@ -49,7 +47,7 @@ public sealed class ActionPvsDetachTest Assert.That(cSys.GetActions(cEnt).Count(), Is.EqualTo(initActions)); // Re-enter PVS view - await server.WaitPost(() => + server.Post(() => { var enumerator = server.Transform(ent).ChildEnumerator; while (enumerator.MoveNext(out var child)) diff --git a/Content.IntegrationTests/Tests/CargoTest.cs b/Content.IntegrationTests/Tests/CargoTest.cs index 1b29e7ea7a..37fd3a80f9 100644 --- a/Content.IntegrationTests/Tests/CargoTest.cs +++ b/Content.IntegrationTests/Tests/CargoTest.cs @@ -253,12 +253,12 @@ public sealed class CargoTest { await using var pair = await PoolManager.GetServerClient(); var server = pair.Server; - var entManager = server.ResolveDependency(); - var priceSystem = entManager.System(); await server.WaitAssertion(() => { + var priceSystem = entManager.System(); + var ent = entManager.SpawnEntity("StackEnt", MapCoordinates.Nullspace); var price = priceSystem.GetPrice(ent); Assert.That(price, Is.EqualTo(100.0)); From 18f5a0dca88ca83a73adfb00066e287213bf0e7a Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:24:12 +1000 Subject: [PATCH 008/414] Fix AI singulo shenanigans (#31556) * weh * Fix broken tests directly mutating entities from wrong thread. * fix build * gundam * weher * WHY --------- Co-authored-by: Pieter-Jan Briers --- .../EntitySystems/EventHorizonSystem.cs | 29 ++++++++++--------- .../EntitySystems/GravityWellSystem.cs | 24 +++++++++++---- Content.Shared/Physics/CollisionGroup.cs | 4 +++ .../Entities/Mobs/Player/narsie.yml | 8 ++--- .../Entities/Mobs/Player/observer.yml | 2 +- .../Entities/Mobs/Player/ratvar.yml | 8 ++--- .../Generation/Singularity/singularity.yml | 8 ++--- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index 6e3d9e9251..3bf820535f 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -11,7 +11,9 @@ using Content.Shared.Tag; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; +using Robust.Shared.Physics.Systems; using Robust.Shared.Timing; namespace Content.Server.Singularity.EntitySystems; @@ -28,16 +30,20 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem [Dependency] private readonly IMapManager _mapMan = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedTransformSystem _xformSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; #endregion Dependencies + private EntityQuery _physicsQuery; + public override void Initialize() { base.Initialize(); + _physicsQuery = GetEntityQuery(); + SubscribeLocalEvent(PreventConsume); - SubscribeLocalEvent(PreventConsume); SubscribeLocalEvent(PreventConsume); SubscribeLocalEvent(OnHorizonMapInit); SubscribeLocalEvent(OnStartCollide); @@ -159,24 +165,19 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem /// Attempts to consume all entities within a given distance of an entity; /// Excludes the center entity. /// - public void ConsumeEntitiesInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null) + public void ConsumeEntitiesInRange(EntityUid uid, float range, PhysicsComponent? body = null, EventHorizonComponent? eventHorizon = null) { - if (!Resolve(uid, ref xform, ref eventHorizon)) + if (!Resolve(uid, ref body, ref eventHorizon)) return; - var range2 = range * range; - var xformQuery = EntityManager.GetEntityQuery(); - var epicenter = _xformSystem.GetWorldPosition(xform, xformQuery); - foreach (var entity in _lookup.GetEntitiesInRange(_xformSystem.GetMapCoordinates(uid, xform), range, flags: LookupFlags.Uncontained)) + // TODO: Should be sundries + static-sundries but apparently this is load-bearing for SpawnAndDeleteAllEntitiesInTheSameSpot so go figure. + foreach (var entity in _lookup.GetEntitiesInRange(uid, range, flags: LookupFlags.Uncontained)) { if (entity == uid) continue; - if (!xformQuery.TryGetComponent(entity, out var entityXform)) - continue; - // GetEntitiesInRange gets everything in a _square_ centered on the given position, but we are a _circle_. If we don't have this check and the station is rotated it is possible for the singularity to reach _outside of the containment field_ and eat the emitters. - var displacement = _xformSystem.GetWorldPosition(entityXform, xformQuery) - epicenter; - if (displacement.LengthSquared() > range2) + // See TODO above + if (_physicsQuery.TryComp(entity, out var otherBody) && !_physics.IsHardCollidable((uid, null, body), (entity, null, otherBody))) continue; AttemptConsumeEntity(uid, entity, eventHorizon); @@ -318,11 +319,11 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem /// public void ConsumeEverythingInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null) { - if (!Resolve(uid, ref xform, ref eventHorizon)) + if (!Resolve(uid, ref eventHorizon)) return; if (eventHorizon.ConsumeEntities) - ConsumeEntitiesInRange(uid, range, xform, eventHorizon); + ConsumeEntitiesInRange(uid, range, null, eventHorizon); if (eventHorizon.ConsumeTiles) ConsumeTilesInRange(uid, range, xform, eventHorizon); } diff --git a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs index 8c884d023c..7dcf3ef1ae 100644 --- a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs +++ b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs @@ -2,6 +2,7 @@ using System.Numerics; using Content.Server.Singularity.Components; using Content.Shared.Atmos.Components; using Content.Shared.Ghost; +using Content.Shared.Physics; using Content.Shared.Singularity.EntitySystems; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -33,9 +34,18 @@ public sealed class GravityWellSystem : SharedGravityWellSystem /// public const float MinGravPulseRange = 0.00001f; + private EntityQuery _wellQuery; + private EntityQuery _mapQuery; + private EntityQuery _gridQuery; + private EntityQuery _physicsQuery; + public override void Initialize() { base.Initialize(); + _wellQuery = GetEntityQuery(); + _mapQuery = GetEntityQuery(); + _gridQuery = GetEntityQuery(); + _physicsQuery = GetEntityQuery(); SubscribeLocalEvent(OnGravityWellStartup); var vvHandle = _vvManager.GetTypeHandler(); @@ -111,11 +121,15 @@ public sealed class GravityWellSystem : SharedGravityWellSystem /// The entity to check. private bool CanGravPulseAffect(EntityUid entity) { - return !( - EntityManager.HasComponent(entity) || - EntityManager.HasComponent(entity) || - EntityManager.HasComponent(entity) || - EntityManager.HasComponent(entity) + if (_physicsQuery.TryComp(entity, out var physics)) + { + if (physics.CollisionLayer == (int) CollisionGroup.GhostImpassable) + return false; + } + + return !(_gridQuery.HasComp(entity) || + _mapQuery.HasComp(entity) || + _wellQuery.HasComp(entity) ); } diff --git a/Content.Shared/Physics/CollisionGroup.cs b/Content.Shared/Physics/CollisionGroup.cs index 9f8c5ad9be..0a11f93dbc 100644 --- a/Content.Shared/Physics/CollisionGroup.cs +++ b/Content.Shared/Physics/CollisionGroup.cs @@ -22,13 +22,17 @@ public enum CollisionGroup GhostImpassable = 1 << 5, // 32 Things impassible by ghosts/observers, ie blessed tiles or forcefields BulletImpassable = 1 << 6, // 64 Can be hit by bullets InteractImpassable = 1 << 7, // 128 Blocks interaction/InRangeUnobstructed + // Y dis door passable when all the others impassable / collision. DoorPassable = 1 << 8, // 256 Allows door to close over top, Like blast doors over conveyors for disposals rooms/cargo. MapGrid = MapGridHelpers.CollisionGroup, // Map grids, like shuttles. This is the actual grid itself, not the walls or other entities connected to the grid. // 32 possible groups + // Why dis exist AllMask = -1, + SingularityLayer = Opaque | Impassable | MidImpassable | HighImpassable | LowImpassable | BulletImpassable | InteractImpassable | DoorPassable, + // Humanoids, etc. MobMask = Impassable | HighImpassable | MidImpassable | LowImpassable, MobLayer = Opaque | BulletImpassable, diff --git a/Resources/Prototypes/Entities/Mobs/Player/narsie.yml b/Resources/Prototypes/Entities/Mobs/Player/narsie.yml index 7030572cf4..5d07409b5f 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/narsie.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/narsie.yml @@ -52,18 +52,18 @@ restitution: 0.8 density: 99999 mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer EventHorizonConsumer: shape: !type:PhysShapeCircle radius: 5 hard: false mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer - type: Input context: "ghost" - type: MovementIgnoreGravity diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index 52994a72c6..5ceac9e773 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -24,7 +24,7 @@ !type:PhysShapeCircle radius: 0.35 density: 15 - mask: + layer: - GhostImpassable - type: entity diff --git a/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml b/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml index 958c98f483..530f5e1037 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/ratvar.yml @@ -49,18 +49,18 @@ restitution: 0.8 density: 1 mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer EventHorizonConsumer: shape: !type:PhysShapeCircle radius: 5 hard: false mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer - type: Input context: "ghost" - type: MovementIgnoreGravity diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml index 25d219ab94..bf2c6cfcc0 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml @@ -31,18 +31,18 @@ restitution: 0.8 density: 99999 mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer EventHorizonConsumer: shape: !type:PhysShapeCircle radius: 0.35 hard: false mask: - - AllMask + - SingularityLayer layer: - - AllMask + - SingularityLayer - type: Singularity energy: 180 level: 1 From 2ae23bc71a0bb9d4a038c1fca161a540949fe601 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:24:57 +1000 Subject: [PATCH 009/414] Update submodule to 233.0.1 (#31676) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index c558a0327b..da56851846 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit c558a0327bc8179e2618a4587e99c73cb3ae094c +Subproject commit da56851846d3fb33f7a77233fc3d505affd81ac1 From f22db1fa1b2d8177df92d791ea6efdb6b97568eb Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 31 Aug 2024 08:25:18 +0000 Subject: [PATCH 010/414] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ed7346e1da..d65020af6d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: You can now find Jackboots in the security load-outs - type: Add - - message: The Sec drobe no longer has a Cowboy hat or boots - type: Remove - id: 6753 - time: '2024-06-15T22:38:29.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29018 - author: Keer-Sar changes: - message: Fixed a spelling error in the cargo bounty for lungs. @@ -3843,3 +3834,10 @@ id: 7252 time: '2024-08-31T03:02:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31670 +- author: metalgearsloth + changes: + - message: Fix AI eye getting deleted by singulo. + type: Fix + id: 7253 + time: '2024-08-31T08:24:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31556 From 99db9ea39d3abfd896a081b6f58f142b8ef9fc25 Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Sat, 31 Aug 2024 08:26:52 +0000 Subject: [PATCH 011/414] Fix suicide logs (#31661) Make suicide logs include the username, as well as the character(where possible) --- Content.Server/Chat/SuicideSystem.cs | 19 +++++++++++++++++-- Content.Server/Ghost/GhostSystem.cs | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Content.Server/Chat/SuicideSystem.cs b/Content.Server/Chat/SuicideSystem.cs index 69d87472fb..4eda532385 100644 --- a/Content.Server/Chat/SuicideSystem.cs +++ b/Content.Server/Chat/SuicideSystem.cs @@ -46,7 +46,15 @@ public sealed class SuicideSystem : EntitySystem if (!TryComp(victim, out var mobState) || _mobState.IsDead(victim, mobState)) return false; + _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(victim):player} is attempting to suicide"); + + ICommonSession? session = null; + + if (TryComp(victim, out var actor)) + session = actor.PlayerSession; + var suicideGhostEvent = new SuicideGhostEvent(victim); + RaiseLocalEvent(victim, suicideGhostEvent); // Suicide is considered a fail if the user wasn't able to ghost @@ -54,11 +62,18 @@ public sealed class SuicideSystem : EntitySystem if (!suicideGhostEvent.Handled || _tagSystem.HasTag(victim, "CannotSuicide")) return false; - _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(victim):player} is attempting to suicide"); var suicideEvent = new SuicideEvent(victim); RaiseLocalEvent(victim, suicideEvent); - _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(victim):player} suicided."); + // Since the player is already dead the log will not contain their username. + if (session != null) + { + _adminLogger.Add(LogType.Mind, $"{session:player} suicided."); + } + else + { + _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(victim):player} suicided."); + } return true; } diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index b045214329..945b0ff998 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -571,14 +571,14 @@ namespace Content.Server.Ghost } } + if (playerEntity != null) + _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} ghosted{(!canReturn ? " (non-returnable)" : "")}"); + var ghost = SpawnGhost((mindId, mind), position, canReturn); if (ghost == null) return false; - if (playerEntity != null) - _adminLogger.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} ghosted{(!canReturn ? " (non-returnable)" : "")}"); - return true; } } From 5ab065fc806e62135a2ce7682dc450777eae62d8 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 31 Aug 2024 08:27:58 +0000 Subject: [PATCH 012/414] Automatic changelog update --- Resources/Changelog/Admin.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index bd42b8ee7b..47b4295472 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -499,5 +499,12 @@ Entries: id: 62 time: '2024-08-25T01:55:31.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31397 +- author: nikthechampiongr + changes: + - message: Suicide logs display username info again. + type: Fix + id: 63 + time: '2024-08-31T08:26:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31661 Name: Admin Order: 1 From 494024d2465dc65cef5d33c3ffbeb6f1d0a5b186 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sat, 31 Aug 2024 10:28:36 +0200 Subject: [PATCH 013/414] More ItemTogglePointLight fixes (#31655) more ItemTogglePointLight fixes --- Resources/Prototypes/Entities/Objects/Fun/toys.yml | 1 + .../Prototypes/Entities/Objects/Misc/arabianlamp.yml | 11 ++++++----- .../Prototypes/Entities/Objects/Tools/lighters.yml | 2 ++ .../Prototypes/Entities/Objects/Tools/welders.yml | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 6ac158630f..0de4631b29 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -1268,6 +1268,7 @@ right: - state: inhand-right-blade shader: unshaded + - type: ItemTogglePointLight - type: DisarmMalus malus: 0 - type: StaminaDamageOnHit diff --git a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml index a15e30fbc7..791a0d0945 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/arabianlamp.yml @@ -14,9 +14,9 @@ - type: EntityStorage capacity: 1 # Its smol. itemCanStoreMobs: false # just leaving this here explicitly since I know at some point someone will want to use this to hold a mob. This also prevents it from becoming His Grace. - # - type: StorageFill - # contents: - # - id: PuddleSparkle # Ha! Cute. Unfortunately it despawns before the container is likely to open. + # - type: StorageFill + # contents: + # - id: PuddleSparkle # Ha! Cute. Unfortunately it despawns before the container is likely to open. - type: ContainerContainer containers: entity_storage: !type:Container @@ -64,7 +64,7 @@ - type: Sprite sprite: Objects/Misc/arabianlamp.rsi layers: - - state: lamp + - state: lamp map: [ "enum.StorageVisualLayers.Base" ] - state: lamptop map: ["enum.StorageVisualLayers.Door"] @@ -130,10 +130,11 @@ netsync: false radius: 5 color: orange + - type: ItemTogglePointLight - type: StaticPrice price: 1500 - type: Prayable sentMessage: prayer-popup-notify-lamp-sent notificationPrefix: prayer-chat-notify-lamp verb: prayer-verbs-rub - verbImage: null \ No newline at end of file + verbImage: null diff --git a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml index d03cc725ef..c35d67e7eb 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml @@ -87,6 +87,7 @@ netsync: false radius: 1.1 #smallest possible color: orange + - type: ItemTogglePointLight - type: entity name: cheap lighter @@ -205,6 +206,7 @@ netsync: false radius: 1.2 #slightly stronger than the other lighters color: orange + - type: ItemTogglePointLight - type: UseDelay - type: IgnitionSource ignited: false diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index cd188969b5..197dca00ff 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -95,6 +95,7 @@ radius: 1.5 color: orange netsync: false + - type: ItemTogglePointLight - type: Appearance - type: RequiresEyeProtection - type: PhysicalComposition From 4435ccd29f326ef1ebb8df518c2f18623a46860d Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 31 Aug 2024 08:29:42 +0000 Subject: [PATCH 014/414] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d65020af6d..d0491e6c46 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Keer-Sar - changes: - - message: Fixed a spelling error in the cargo bounty for lungs. - type: Fix - id: 6754 - time: '2024-06-16T00:24:29.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29064 - author: Keer-Sar changes: - message: Non-humanoids' names are now capitalized when inserting materials into @@ -3841,3 +3834,11 @@ id: 7253 time: '2024-08-31T08:24:12.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31556 +- author: slarticodefast + changes: + - message: Fixed toggleable pointlights for the toy sword, lighters, welders and + arabian lamp. + type: Fix + id: 7254 + time: '2024-08-31T08:28:36.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31655 From 9a63144636f9ef272d955f1e131b17233c6ec5da Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Sat, 31 Aug 2024 11:38:03 +0000 Subject: [PATCH 015/414] Allow for respawn and erase verb to be used on offline players. Also minor rewrite on respawn command and new erase command (#30433) * Localize respawn command, allow for it to use userids, and make it use [Dependency] attributes * Make respawn verb available for offline players * Make erase available for offline players A thousand admins rejoice * Reorder verbs in code * Add erase command * Fix localisation for erase command * Address reviews and add completion to respawn command * Complete reviews which I forgor --- Content.Server/Administration/BanPanelEui.cs | 5 +- .../Administration/Commands/EraseCommand.cs | 47 ++++++++++++++ .../Administration/Systems/AdminSystem.cs | 58 +++++++++-------- .../Administration/Systems/AdminVerbSystem.cs | 62 +++++++++--------- Content.Server/Chat/Managers/ChatManager.cs | 8 +-- Content.Server/Chat/Managers/IChatManager.cs | 2 +- .../GameTicking/Commands/RespawnCommand.cs | 65 ++++++++++++------- .../en-US/administration/commands/erase.ftl | 7 ++ .../en-US/administration/commands/respawn.ftl | 9 +++ 9 files changed, 175 insertions(+), 88 deletions(-) create mode 100644 Content.Server/Administration/Commands/EraseCommand.cs create mode 100644 Resources/Locale/en-US/administration/commands/erase.ftl create mode 100644 Resources/Locale/en-US/administration/commands/respawn.ftl diff --git a/Content.Server/Administration/BanPanelEui.cs b/Content.Server/Administration/BanPanelEui.cs index aa6bd8d4bf..b3253f0d0c 100644 --- a/Content.Server/Administration/BanPanelEui.cs +++ b/Content.Server/Administration/BanPanelEui.cs @@ -132,13 +132,12 @@ public sealed class BanPanelEui : BaseEui } if (erase && - targetUid != null && - _playerManager.TryGetSessionById(targetUid.Value, out var targetPlayer)) + targetUid != null) { try { if (_entities.TrySystem(out AdminSystem? adminSystem)) - adminSystem.Erase(targetPlayer); + adminSystem.Erase(targetUid.Value); } catch (Exception e) { diff --git a/Content.Server/Administration/Commands/EraseCommand.cs b/Content.Server/Administration/Commands/EraseCommand.cs new file mode 100644 index 0000000000..cb01d742a0 --- /dev/null +++ b/Content.Server/Administration/Commands/EraseCommand.cs @@ -0,0 +1,47 @@ +using System.Linq; +using Content.Server.Administration.Systems; +using Content.Shared.Administration; +using Robust.Server.Player; +using Robust.Shared.Console; + +namespace Content.Server.Administration.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class EraseCommand : LocalizedEntityCommands +{ + [Dependency] private readonly IPlayerLocator _locator = default!; + [Dependency] private readonly IPlayerManager _players = default!; + [Dependency] private readonly AdminSystem _admin = default!; + + public override string Command => "erase"; + + public override async void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 1) + { + shell.WriteError(Loc.GetString("cmd-erase-invalid-args")); + shell.WriteLine(Help); + return; + } + + var located = await _locator.LookupIdByNameOrIdAsync(args[0]); + + if (located == null) + { + shell.WriteError(Loc.GetString("cmd-erase-player-not-found")); + return; + } + + _admin.Erase(located.UserId); + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length != 1) + return CompletionResult.Empty; + + var options = _players.Sessions.OrderBy(c => c.Name).Select(c => c.Name).ToArray(); + + return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-erase-player-completion")); + } +} diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index db22c41520..99551c714c 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -15,7 +15,9 @@ using Content.Shared.GameTicking; using Content.Shared.Hands.Components; using Content.Shared.IdentityManagement; using Content.Shared.Inventory; +using Content.Shared.Mind; using Content.Shared.PDA; +using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; using Content.Shared.Popups; using Content.Shared.Roles; @@ -377,30 +379,32 @@ public sealed class AdminSystem : EntitySystem } } - /// - /// Erases a player from the round. - /// This removes them and any trace of them from the round, deleting their - /// chat messages and showing a popup to other players. - /// Their items are dropped on the ground. - /// - public void Erase(ICommonSession player) - { - var entity = player.AttachedEntity; - _chat.DeleteMessagesBy(player); - - if (entity != null && !TerminatingOrDeleted(entity.Value)) + /// + /// Erases a player from the round. + /// This removes them and any trace of them from the round, deleting their + /// chat messages and showing a popup to other players. + /// Their items are dropped on the ground. + /// + public void Erase(NetUserId uid) { - if (TryComp(entity.Value, out TransformComponent? transform)) + _chat.DeleteMessagesBy(uid); + + if (!_minds.TryGetMind(uid, out var mindId, out var mind) || mind.OwnedEntity == null || TerminatingOrDeleted(mind.OwnedEntity.Value)) + return; + + var entity = mind.OwnedEntity.Value; + + if (TryComp(entity, out TransformComponent? transform)) { - var coordinates = _transform.GetMoverCoordinates(entity.Value, transform); - var name = Identity.Entity(entity.Value, EntityManager); + var coordinates = _transform.GetMoverCoordinates(entity, transform); + var name = Identity.Entity(entity, EntityManager); _popup.PopupCoordinates(Loc.GetString("admin-erase-popup", ("user", name)), coordinates, PopupType.LargeCaution); var filter = Filter.Pvs(coordinates, 1, EntityManager, _playerManager); var audioParams = new AudioParams().WithVolume(3); _audio.PlayStatic("/Audio/Effects/pop_high.ogg", filter, coordinates, true, audioParams); } - foreach (var item in _inventory.GetHandOrInventoryEntities(entity.Value)) + foreach (var item in _inventory.GetHandOrInventoryEntities(entity)) { if (TryComp(item, out PdaComponent? pda) && TryComp(pda.ContainedId, out StationRecordKeyStorageComponent? keyStorage) && @@ -424,30 +428,30 @@ public sealed class AdminSystem : EntitySystem } } - if (_inventory.TryGetContainerSlotEnumerator(entity.Value, out var enumerator)) + if (_inventory.TryGetContainerSlotEnumerator(entity, out var enumerator)) { while (enumerator.NextItem(out var item, out var slot)) { - if (_inventory.TryUnequip(entity.Value, entity.Value, slot.Name, true, true)) + if (_inventory.TryUnequip(entity, entity, slot.Name, true, true)) _physics.ApplyAngularImpulse(item, ThrowingSystem.ThrowAngularImpulse); } } - if (TryComp(entity.Value, out HandsComponent? hands)) + if (TryComp(entity, out HandsComponent? hands)) { - foreach (var hand in _hands.EnumerateHands(entity.Value, hands)) + foreach (var hand in _hands.EnumerateHands(entity, hands)) { - _hands.TryDrop(entity.Value, hand, checkActionBlocker: false, doDropInteraction: false, handsComp: hands); + _hands.TryDrop(entity, hand, checkActionBlocker: false, doDropInteraction: false, handsComp: hands); } } + + _minds.WipeMind(mindId, mind); + QueueDel(entity); + + if (_playerManager.TryGetSessionById(uid, out var session)) + _gameTicker.SpawnObserver(session); } - _minds.WipeMind(player); - QueueDel(entity); - - _gameTicker.SpawnObserver(player); - } - private void OnSessionPlayTimeUpdated(ICommonSession session) { UpdatePlayerList(session); diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 308a679846..5aa05ce28b 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -34,11 +34,11 @@ using Robust.Shared.Timing; using Robust.Shared.Toolshed; using Robust.Shared.Utility; using System.Linq; -using System.Numerics; using Content.Server.Silicons.Laws; using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using Robust.Server.Player; +using Content.Shared.Mind; using Robust.Shared.Physics.Components; using static Content.Shared.Configurable.ConfigurationComponent; @@ -137,34 +137,6 @@ namespace Content.Server.Administration.Systems prayerVerb.Impact = LogImpact.Low; args.Verbs.Add(prayerVerb); - // Erase - args.Verbs.Add(new Verb - { - Text = Loc.GetString("admin-verbs-erase"), - Message = Loc.GetString("admin-verbs-erase-description"), - Category = VerbCategory.Admin, - Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png")), - Act = () => - { - _adminSystem.Erase(targetActor.PlayerSession); - }, - Impact = LogImpact.Extreme, - ConfirmationPopup = true - }); - - // Respawn - args.Verbs.Add(new Verb() - { - Text = Loc.GetString("admin-player-actions-respawn"), - Category = VerbCategory.Admin, - Act = () => - { - _console.ExecuteCommand(player, $"respawn {targetActor.PlayerSession.Name}"); - }, - ConfirmationPopup = true, - // No logimpact as the command does it internally. - }); - // Spawn - Like respawn but on the spot. args.Verbs.Add(new Verb() { @@ -225,6 +197,38 @@ namespace Content.Server.Administration.Systems }); } + if (_mindSystem.TryGetMind(args.Target, out _, out var mind) && mind.UserId != null) + { + // Erase + args.Verbs.Add(new Verb + { + Text = Loc.GetString("admin-verbs-erase"), + Message = Loc.GetString("admin-verbs-erase-description"), + Category = VerbCategory.Admin, + Icon = new SpriteSpecifier.Texture( + new("/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png")), + Act = () => + { + _adminSystem.Erase(mind.UserId.Value); + }, + Impact = LogImpact.Extreme, + ConfirmationPopup = true + }); + + // Respawn + args.Verbs.Add(new Verb + { + Text = Loc.GetString("admin-player-actions-respawn"), + Category = VerbCategory.Admin, + Act = () => + { + _console.ExecuteCommand(player, $"respawn \"{mind.UserId}\""); + }, + ConfirmationPopup = true, + // No logimpact as the command does it internally. + }); + } + // Freeze var frozen = TryComp(args.Target, out var frozenComp); var frozenAndMuted = frozenComp?.Muted ?? false; diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index 6fb7bbba8e..02f718daef 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -81,10 +81,10 @@ internal sealed partial class ChatManager : IChatManager DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message")); } - public void DeleteMessagesBy(ICommonSession player) - { - if (!_players.TryGetValue(player.UserId, out var user)) - return; + public void DeleteMessagesBy(NetUserId uid) + { + if (!_players.TryGetValue(uid, out var user)) + return; var msg = new MsgDeleteChatMessagesBy { Key = user.Key, Entities = user.Entities }; _netManager.ServerSendToAll(msg); diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 15d1288ee2..76fa91d847 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -41,7 +41,7 @@ namespace Content.Server.Chat.Managers bool MessageCharacterLimit(ICommonSession player, string message); - void DeleteMessagesBy(ICommonSession player); + void DeleteMessagesBy(NetUserId uid); [return: NotNullIfNotNull(nameof(author))] ChatUser? EnsurePlayer(NetUserId? author); diff --git a/Content.Server/GameTicking/Commands/RespawnCommand.cs b/Content.Server/GameTicking/Commands/RespawnCommand.cs index 4f101d0939..f7ea11baf1 100644 --- a/Content.Server/GameTicking/Commands/RespawnCommand.cs +++ b/Content.Server/GameTicking/Commands/RespawnCommand.cs @@ -1,4 +1,6 @@ -using Content.Shared.Mind; +using System.Linq; +using Content.Server.Administration; +using Content.Server.Mind; using Content.Shared.Players; using Robust.Server.Player; using Robust.Shared.Console; @@ -6,57 +8,72 @@ using Robust.Shared.Network; namespace Content.Server.GameTicking.Commands { - sealed class RespawnCommand : IConsoleCommand + sealed class RespawnCommand : LocalizedEntityCommands { - public string Command => "respawn"; - public string Description => "Respawns a player, kicking them back to the lobby."; - public string Help => "respawn [player]"; + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IPlayerLocator _locator = default!; + [Dependency] private readonly GameTicker _gameTicker = default!; + [Dependency] private readonly MindSystem _mind = default!; - public void Execute(IConsoleShell shell, string argStr, string[] args) + public override string Command => "respawn"; + + public override async void Execute(IConsoleShell shell, string argStr, string[] args) { var player = shell.Player; if (args.Length > 1) { - shell.WriteLine("Must provide <= 1 argument."); + shell.WriteError(Loc.GetString("cmd-respawn-invalid-args")); return; } - var playerMgr = IoCManager.Resolve(); - var sysMan = IoCManager.Resolve(); - var ticker = sysMan.GetEntitySystem(); - var mind = sysMan.GetEntitySystem(); - NetUserId userId; if (args.Length == 0) { if (player == null) { - shell.WriteLine("If not a player, an argument must be given."); + shell.WriteError(Loc.GetString("cmd-respawn-no-player")); return; } userId = player.UserId; } - else if (!playerMgr.TryGetUserId(args[0], out userId)) + else { - shell.WriteLine("Unknown player"); - return; - } + var located = await _locator.LookupIdByNameOrIdAsync(args[0]); - if (!playerMgr.TryGetSessionById(userId, out var targetPlayer)) - { - if (!playerMgr.TryGetPlayerData(userId, out var data)) + if (located == null) { - shell.WriteLine("Unknown player"); + shell.WriteError(Loc.GetString("cmd-respawn-unknown-player")); return; } - mind.WipeMind(data.ContentData()?.Mind); - shell.WriteLine("Player is not currently online, but they will respawn if they come back online"); + userId = located.UserId; + } + + if (!_player.TryGetSessionById(userId, out var targetPlayer)) + { + if (!_player.TryGetPlayerData(userId, out var data)) + { + shell.WriteError(Loc.GetString("cmd-respawn-unknown-player")); + return; + } + + _mind.WipeMind(data.ContentData()?.Mind); + shell.WriteError(Loc.GetString("cmd-respawn-player-not-online")); return; } - ticker.Respawn(targetPlayer); + _gameTicker.Respawn(targetPlayer); + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length != 1) + return CompletionResult.Empty; + + var options = _player.Sessions.OrderBy(c => c.Name).Select(c => c.Name).ToArray(); + + return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-respawn-player-completion")); } } } diff --git a/Resources/Locale/en-US/administration/commands/erase.ftl b/Resources/Locale/en-US/administration/commands/erase.ftl new file mode 100644 index 0000000000..e9f995f03e --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/erase.ftl @@ -0,0 +1,7 @@ +# erase +cmd-erase-desc = Erase a player's entity if it exists and all their chat messages +cmd-erase-help = erase +cmd-erase-invalid-args = Invalid number of arguments +cmd-erase-player-not-found = Player not found + +cmd-erase-player-completion = diff --git a/Resources/Locale/en-US/administration/commands/respawn.ftl b/Resources/Locale/en-US/administration/commands/respawn.ftl new file mode 100644 index 0000000000..6aab854ee4 --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/respawn.ftl @@ -0,0 +1,9 @@ +cmd-respawn-desc = Respawns a player, kicking them back to the lobby. +cmd-respawn-help = respawn [player or UserId] + +cmd-respawn-invalid-args = Must provide <= 1 argument. +cmd-respawn-no-player = If not a player, an argument must be given. +cmd-respawn-unknown-player = Unknown player +cmd-respawn-player-not-online = Player is not currently online, but they will respawn if they come back online + +cmd-respawn-player-completion = From 8dbaca33e6acc1d099ba344593be40ecc62e2797 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 31 Aug 2024 11:39:10 +0000 Subject: [PATCH 016/414] Automatic changelog update --- Resources/Changelog/Admin.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index 47b4295472..0e670b5ff4 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -506,5 +506,18 @@ Entries: id: 63 time: '2024-08-31T08:26:52.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31661 +- author: nikthechampiongr + changes: + - message: Respawn verb is now available on players even after they have disconnected. + type: Fix + - message: Erase command is now available on players even after they have disconnected. + type: Fix + - message: You can now erase people with the erase command + type: Add + - message: Respawn command now also accepts user ids + type: Tweak + id: 64 + time: '2024-08-31T11:38:04.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30433 Name: Admin Order: 1 From 417d3a87a22640003fd7ce95771aa470357b33c1 Mon Sep 17 00:00:00 2001 From: Julian Giebel Date: Sat, 31 Aug 2024 16:40:28 +0200 Subject: [PATCH 017/414] Station Anchor (#26098) * Work on abstracting out chargeup functionality/ui from grav gen * Work on station anchor * Finish implementing station anchors * uhh yeah * ok. * fix tests * whoops * Get the last extraneous yaml fail * PJB review * beast mode... ACTIVATE! --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> Co-authored-by: EmoGarbage404 --- .../Ui/AnomalyGeneratorBoundUserInterface.cs | 2 - Content.Client/Gravity/GravitySystem.cs | 5 +- .../UI/GravityGeneratorBoundUserInterface.cs | 38 --- .../Gravity/UI/GravityGeneratorWindow.xaml.cs | 75 ----- .../PowerChargeBoundUserInterface.cs | 38 +++ .../Power/PowerCharge/PowerChargeComponent.cs | 10 + .../PowerCharge/PowerChargeWindow.xaml} | 16 +- .../PowerCharge/PowerChargeWindow.xaml.cs | 72 ++++ .../Tests/Gravity/WeightlessStatusTests.cs | 3 + .../Tests/GravityGridTest.cs | 3 + .../Gravity/GravityGeneratorComponent.cs | 29 -- .../Gravity/GravityGeneratorSystem.cs | 313 +++--------------- .../Power/Components/PowerChargeComponent.cs | 66 ++++ .../Power/EntitySystems/PowerChargeSystem.cs | 283 ++++++++++++++++ .../Components/StationAnchorComponent.cs | 11 + .../Shuttles/Systems/StationAnchorSystem.cs | 86 +++++ .../SharedGravityGeneratorComponent.cs | 146 ++------ Content.Shared/Power/SharedPowerCharge.cs | 77 +++++ .../Power/SharedPowerChargeComponent.cs | 14 + .../Shuttles/Systems/SharedShuttleSystem.cs | 3 +- .../components/station-anchor-component.ftl | 2 + .../components/power-charging-component.ftl | 22 ++ .../Circuitboards/Machine/production.yml | 16 + .../Structures/Machines/gravity_generator.yml | 14 +- .../Entities/Structures/Machines/lathe.yml | 1 + .../Structures/Shuttles/station_anchor.yml | 112 +++++++ .../Prototypes/Recipes/Lathes/electronics.yml | 11 +- .../Machines/station_anchor.rsi/meta.json | 17 + .../station_anchor.rsi/station_anchor.png | Bin 0 -> 3751 bytes .../station_anchor_unlit.png | Bin 0 -> 3330 bytes 30 files changed, 944 insertions(+), 541 deletions(-) delete mode 100644 Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs delete mode 100644 Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs create mode 100644 Content.Client/Power/PowerCharge/PowerChargeBoundUserInterface.cs create mode 100644 Content.Client/Power/PowerCharge/PowerChargeComponent.cs rename Content.Client/{Gravity/UI/GravityGeneratorWindow.xaml => Power/PowerCharge/PowerChargeWindow.xaml} (60%) create mode 100644 Content.Client/Power/PowerCharge/PowerChargeWindow.xaml.cs create mode 100644 Content.Server/Power/Components/PowerChargeComponent.cs create mode 100644 Content.Server/Power/EntitySystems/PowerChargeSystem.cs create mode 100644 Content.Server/Shuttles/Components/StationAnchorComponent.cs create mode 100644 Content.Server/Shuttles/Systems/StationAnchorSystem.cs create mode 100644 Content.Shared/Power/SharedPowerCharge.cs create mode 100644 Content.Shared/Power/SharedPowerChargeComponent.cs create mode 100644 Resources/Locale/en-US/components/station-anchor-component.ftl create mode 100644 Resources/Locale/en-US/power/components/power-charging-component.ftl create mode 100644 Resources/Prototypes/Entities/Structures/Shuttles/station_anchor.yml create mode 100644 Resources/Textures/Structures/Machines/station_anchor.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/station_anchor.rsi/station_anchor.png create mode 100644 Resources/Textures/Structures/Machines/station_anchor.rsi/station_anchor_unlit.png diff --git a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs index 5d1985485c..f088ac1976 100644 --- a/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs +++ b/Content.Client/Anomaly/Ui/AnomalyGeneratorBoundUserInterface.cs @@ -1,7 +1,5 @@ using Content.Shared.Anomaly; -using Content.Shared.Gravity; using JetBrains.Annotations; -using Robust.Client.GameObjects; using Robust.Client.UserInterface; namespace Content.Client.Anomaly.Ui; diff --git a/Content.Client/Gravity/GravitySystem.cs b/Content.Client/Gravity/GravitySystem.cs index 3e87f76ba2..dd51436a1f 100644 --- a/Content.Client/Gravity/GravitySystem.cs +++ b/Content.Client/Gravity/GravitySystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Gravity; +using Content.Shared.Power; using Robust.Client.GameObjects; namespace Content.Client.Gravity; @@ -21,7 +22,7 @@ public sealed partial class GravitySystem : SharedGravitySystem if (args.Sprite == null) return; - if (_appearanceSystem.TryGetData(uid, GravityGeneratorVisuals.State, out var state, args.Component)) + if (_appearanceSystem.TryGetData(uid, PowerChargeVisuals.State, out var state, args.Component)) { if (comp.SpriteMap.TryGetValue(state, out var spriteState)) { @@ -30,7 +31,7 @@ public sealed partial class GravitySystem : SharedGravitySystem } } - if (_appearanceSystem.TryGetData(uid, GravityGeneratorVisuals.Charge, out var charge, args.Component)) + if (_appearanceSystem.TryGetData(uid, PowerChargeVisuals.Charge, out var charge, args.Component)) { var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Core); switch (charge) diff --git a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs b/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs deleted file mode 100644 index 32b40747d5..0000000000 --- a/Content.Client/Gravity/UI/GravityGeneratorBoundUserInterface.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Content.Shared.Gravity; -using JetBrains.Annotations; -using Robust.Client.UserInterface; - -namespace Content.Client.Gravity.UI -{ - [UsedImplicitly] - public sealed class GravityGeneratorBoundUserInterface : BoundUserInterface - { - [ViewVariables] - private GravityGeneratorWindow? _window; - - public GravityGeneratorBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) - { - } - - protected override void Open() - { - base.Open(); - - _window = this.CreateWindow(); - _window.SetEntity(Owner); - } - - protected override void UpdateState(BoundUserInterfaceState state) - { - base.UpdateState(state); - - var castState = (SharedGravityGeneratorComponent.GeneratorState) state; - _window?.UpdateState(castState); - } - - public void SetPowerSwitch(bool on) - { - SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on)); - } - } -} diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs b/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs deleted file mode 100644 index 6f04133b59..0000000000 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Content.Shared.Gravity; -using Robust.Client.AutoGenerated; -using Robust.Client.GameObjects; -using Robust.Client.UserInterface.Controls; -using Robust.Client.UserInterface.XAML; -using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow; - -namespace Content.Client.Gravity.UI -{ - [GenerateTypedNameReferences] - public sealed partial class GravityGeneratorWindow : FancyWindow - { - private readonly ButtonGroup _buttonGroup = new(); - - public event Action? OnPowerSwitch; - - public GravityGeneratorWindow() - { - RobustXamlLoader.Load(this); - IoCManager.InjectDependencies(this); - - OnButton.Group = _buttonGroup; - OffButton.Group = _buttonGroup; - - OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true); - OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false); - } - - public void SetEntity(EntityUid uid) - { - EntityView.SetEntity(uid); - } - - public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state) - { - if (state.On) - OnButton.Pressed = true; - else - OffButton.Pressed = true; - - PowerLabel.Text = Loc.GetString( - "gravity-generator-window-power-label", - ("draw", state.PowerDraw), - ("max", state.PowerDrawMax)); - - PowerLabel.SetOnlyStyleClass(MathHelper.CloseTo(state.PowerDraw, state.PowerDrawMax) ? "Good" : "Caution"); - - ChargeBar.Value = state.Charge; - ChargeText.Text = (state.Charge / 255f).ToString("P0"); - StatusLabel.Text = Loc.GetString(state.PowerStatus switch - { - GravityGeneratorPowerStatus.Off => "gravity-generator-window-status-off", - GravityGeneratorPowerStatus.Discharging => "gravity-generator-window-status-discharging", - GravityGeneratorPowerStatus.Charging => "gravity-generator-window-status-charging", - GravityGeneratorPowerStatus.FullyCharged => "gravity-generator-window-status-fully-charged", - _ => throw new ArgumentOutOfRangeException() - }); - - StatusLabel.SetOnlyStyleClass(state.PowerStatus switch - { - GravityGeneratorPowerStatus.Off => "Danger", - GravityGeneratorPowerStatus.Discharging => "Caution", - GravityGeneratorPowerStatus.Charging => "Caution", - GravityGeneratorPowerStatus.FullyCharged => "Good", - _ => throw new ArgumentOutOfRangeException() - }); - - EtaLabel.Text = state.EtaSeconds >= 0 - ? Loc.GetString("gravity-generator-window-eta-value", ("left", TimeSpan.FromSeconds(state.EtaSeconds))) - : Loc.GetString("gravity-generator-window-eta-none"); - - EtaLabel.SetOnlyStyleClass(state.EtaSeconds >= 0 ? "Caution" : "Disabled"); - } - } -} diff --git a/Content.Client/Power/PowerCharge/PowerChargeBoundUserInterface.cs b/Content.Client/Power/PowerCharge/PowerChargeBoundUserInterface.cs new file mode 100644 index 0000000000..7a36b8ddf5 --- /dev/null +++ b/Content.Client/Power/PowerCharge/PowerChargeBoundUserInterface.cs @@ -0,0 +1,38 @@ +using Content.Shared.Power; +using Robust.Client.UserInterface; + +namespace Content.Client.Power.PowerCharge; + +public sealed class PowerChargeBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private PowerChargeWindow? _window; + + public PowerChargeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + public void SetPowerSwitch(bool on) + { + SendMessage(new SwitchChargingMachineMessage(on)); + } + + protected override void Open() + { + base.Open(); + if (!EntMan.TryGetComponent(Owner, out PowerChargeComponent? component)) + return; + + _window = this.CreateWindow(); + _window.UpdateWindow(this, Loc.GetString(component.WindowTitle)); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + if (state is not PowerChargeState chargeState) + return; + + _window?.UpdateState(chargeState); + } +} diff --git a/Content.Client/Power/PowerCharge/PowerChargeComponent.cs b/Content.Client/Power/PowerCharge/PowerChargeComponent.cs new file mode 100644 index 0000000000..ab5baa4e2f --- /dev/null +++ b/Content.Client/Power/PowerCharge/PowerChargeComponent.cs @@ -0,0 +1,10 @@ +using Content.Shared.Power; + +namespace Content.Client.Power.PowerCharge; + +/// +[RegisterComponent] +public sealed partial class PowerChargeComponent : SharedPowerChargeComponent +{ + +} diff --git a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml b/Content.Client/Power/PowerCharge/PowerChargeWindow.xaml similarity index 60% rename from Content.Client/Gravity/UI/GravityGeneratorWindow.xaml rename to Content.Client/Power/PowerCharge/PowerChargeWindow.xaml index 853f437a2b..4e61255326 100644 --- a/Content.Client/Gravity/UI/GravityGeneratorWindow.xaml +++ b/Content.Client/Power/PowerCharge/PowerChargeWindow.xaml @@ -1,27 +1,26 @@  -