From 919b3ac9e64a18990bd8dbf21eceae782e2b3f77 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:25:57 +0200 Subject: [PATCH 01/13] Change wristwatch meta description (#30036) --- Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 7fbb4aecf6..6359f659b5 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -2,7 +2,7 @@ id: Wristwatch parent: BaseItem name: wristwatch - description: A cheap watch for telling time. How much did you waste playing Space Station 14? + description: A cheap watch for telling time. How much did you waste working on this shift? components: - type: Sprite sprite: Objects/Devices/wristwatch.rsi From 4f479b6c85aec0b775062ece959b34f21171f211 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:26:34 +0200 Subject: [PATCH 02/13] Fix RGB toys color when worn/in-hand (#30023) rgbeeeeeeee --- .../Prototypes/Entities/Objects/Fun/toys.yml | 22 ++++++++++++++++++ .../Textures/Objects/Fun/toys.rsi/meta.json | 8 +++++++ .../toys.rsi/rainbowcarpplush-inhand-left.png | Bin 0 -> 15498 bytes .../rainbowcarpplush-inhand-right.png | Bin 0 -> 15496 bytes 4 files changed, 30 insertions(+) create mode 100644 Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png create mode 100644 Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-right.png diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 310f92e60c..33a322cb25 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -184,6 +184,19 @@ energy: 2 - type: RgbLightController layers: [ 0 ] + - type: Item + inhandVisuals: + left: + - state: bee-inhand-left + shader: unshaded + right: + - state: bee-inhand-right + shader: unshaded + - type: Clothing + clothingVisuals: + head: + - state: bee-equipped-HELMET + shader: unshaded - type: entity parent: BasePlushie @@ -543,6 +556,15 @@ energy: 2 - type: RgbLightController layers: [ 0 ] + - type: Item + heldPrefix: rainbowcarpplush + inhandVisuals: + left: + - state: rainbowcarpplush-inhand-left + shader: unshaded + right: + - state: rainbowcarpplush-inhand-right + shader: unshaded - type: entity parent: PlushieCarp diff --git a/Resources/Textures/Objects/Fun/toys.rsi/meta.json b/Resources/Textures/Objects/Fun/toys.rsi/meta.json index fc92a47936..fa118695c2 100644 --- a/Resources/Textures/Objects/Fun/toys.rsi/meta.json +++ b/Resources/Textures/Objects/Fun/toys.rsi/meta.json @@ -53,6 +53,14 @@ { "name": "rainbowcarpplush" }, + { + "name": "rainbowcarpplush-inhand-left", + "directions": 4 + }, + { + "name": "rainbowcarpplush-inhand-right", + "directions": 4 + }, { "name": "narplush" }, diff --git a/Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png b/Resources/Textures/Objects/Fun/toys.rsi/rainbowcarpplush-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..8f28f41fd8513829dc0f926f9bd0fa46f67c05c4 GIT binary patch literal 15498 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 literal 0 HcmV?d00001 From 07535e8ecfbbba14f2845629306af192d11ffce9 Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Sun, 14 Jul 2024 13:26:56 +0300 Subject: [PATCH 03/13] Clumsy proof grappling gun (#29904) Make grappling gun clumsy proof --- .../Entities/Objects/Weapons/Guns/Launchers/launchers.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 19a0cf30e8..0ecad70a64 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -251,6 +251,7 @@ - type: Gun soundGunshot: /Audio/Weapons/Guns/Gunshots/harpoon.ogg fireRate: 0.5 + clumsyProof: true - type: BasicEntityAmmoProvider proto: GrapplingHook capacity: 1 From f90538cca79340378fdbf5ad44decba2d4a46f68 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 10:28:02 +0000 Subject: [PATCH 04/13] Automatic changelog update --- Resources/Changelog/Changelog.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0a41c2e2e9..d06bda3324 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,19 +1,4 @@ Entries: -- author: Weax - changes: - - message: The CLF3 reaction now requires heating first before you can engulf chemistry - in fiery death. - type: Tweak - id: 6417 - time: '2024-04-22T08:44:14.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27187 -- author: Potato1234_x - changes: - - message: Added Psicodine, Mannitol, Lipolicide and Happiness. - type: Add - id: 6418 - time: '2024-04-22T08:45:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27134 - author: Terraspark4941 changes: - message: Updated the engineering section of the guidebook! @@ -3813,3 +3798,17 @@ id: 6916 time: '2024-07-14T02:59:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29979 +- author: SlamBamActionman + changes: + - message: RGBee and Rainbow Carp plushies now cycle color when held/worn. + type: Fix + id: 6917 + time: '2024-07-14T10:26:34.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30023 +- author: Winkarst-cpu + changes: + - message: Now grappling gun is clumsy proof. + type: Tweak + id: 6918 + time: '2024-07-14T10:26:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29904 From 7d9653fff7f7c415e317c3fab03a2162da7983bf Mon Sep 17 00:00:00 2001 From: osjarw <62134478+osjarw@users.noreply.github.com> Date: Sun, 14 Jul 2024 13:28:46 +0300 Subject: [PATCH 05/13] Fix HTN/NPC better plan selection (#30017) * recording commit * Remove debugging/recording content --- Content.Server/NPC/HTN/HTNPlanJob.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/NPC/HTN/HTNPlanJob.cs b/Content.Server/NPC/HTN/HTNPlanJob.cs index d6d10ad311..8158303524 100644 --- a/Content.Server/NPC/HTN/HTNPlanJob.cs +++ b/Content.Server/NPC/HTN/HTNPlanJob.cs @@ -160,9 +160,9 @@ public sealed class HTNPlanJob : Job { var compound = _protoManager.Index(compoundId.Task); - for (var i = mtrIndex; i < compound.Branches.Count; i++) + for (; mtrIndex < compound.Branches.Count; mtrIndex++) { - var branch = compound.Branches[i]; + var branch = compound.Branches[mtrIndex]; var isValid = true; foreach (var con in branch.Preconditions) From 1c74ffb8e475d619e188864194333ca8890509e4 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:58:48 +0300 Subject: [PATCH 06/13] Ambient music rules refactor (#29921) * refactor * dutypo --- .../Audio/ContentAudioSystem.AmbientMusic.cs | 1 + Content.Shared/Audio/AmbientMusicPrototype.cs | 1 + Content.Shared/Random/Rules/AlwaysTrue.cs | 12 + Content.Shared/Random/Rules/GridInRange.cs | 39 +++ Content.Shared/Random/Rules/InSpace.cs | 18 ++ Content.Shared/Random/Rules/NearbyAccess.cs | 77 ++++++ .../Random/Rules/NearbyComponents.cs | 71 +++++ Content.Shared/Random/Rules/NearbyEntities.cs | 58 ++++ .../Random/Rules/NearbyTilesPercent.cs | 79 ++++++ Content.Shared/Random/Rules/OnMapGrid.cs | 19 ++ Content.Shared/Random/Rules/RulesSystem.cs | 39 +++ Content.Shared/Random/RulesPrototype.cs | 141 ---------- Content.Shared/Random/RulesSystem.cs | 247 ------------------ 13 files changed, 414 insertions(+), 388 deletions(-) create mode 100644 Content.Shared/Random/Rules/AlwaysTrue.cs create mode 100644 Content.Shared/Random/Rules/GridInRange.cs create mode 100644 Content.Shared/Random/Rules/InSpace.cs create mode 100644 Content.Shared/Random/Rules/NearbyAccess.cs create mode 100644 Content.Shared/Random/Rules/NearbyComponents.cs create mode 100644 Content.Shared/Random/Rules/NearbyEntities.cs create mode 100644 Content.Shared/Random/Rules/NearbyTilesPercent.cs create mode 100644 Content.Shared/Random/Rules/OnMapGrid.cs create mode 100644 Content.Shared/Random/Rules/RulesSystem.cs delete mode 100644 Content.Shared/Random/RulesPrototype.cs delete mode 100644 Content.Shared/Random/RulesSystem.cs diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index 84b787a4ec..d60c978ccf 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -4,6 +4,7 @@ using Content.Shared.Audio; using Content.Shared.CCVar; using Content.Shared.GameTicking; using Content.Shared.Random; +using Content.Shared.Random.Rules; using Robust.Client.GameObjects; using Robust.Client.Player; using Robust.Client.ResourceManagement; diff --git a/Content.Shared/Audio/AmbientMusicPrototype.cs b/Content.Shared/Audio/AmbientMusicPrototype.cs index 54f70f5728..219c41527d 100644 --- a/Content.Shared/Audio/AmbientMusicPrototype.cs +++ b/Content.Shared/Audio/AmbientMusicPrototype.cs @@ -1,4 +1,5 @@ using Content.Shared.Random; +using Content.Shared.Random.Rules; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; diff --git a/Content.Shared/Random/Rules/AlwaysTrue.cs b/Content.Shared/Random/Rules/AlwaysTrue.cs new file mode 100644 index 0000000000..98b81fae79 --- /dev/null +++ b/Content.Shared/Random/Rules/AlwaysTrue.cs @@ -0,0 +1,12 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Always returns true. Used for fallbacks. +/// +public sealed partial class AlwaysTrueRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/GridInRange.cs b/Content.Shared/Random/Rules/GridInRange.cs new file mode 100644 index 0000000000..8cbbef1cdc --- /dev/null +++ b/Content.Shared/Random/Rules/GridInRange.cs @@ -0,0 +1,39 @@ +using System.Numerics; +using Robust.Shared.Map; + +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if on a grid or in range of one. +/// +public sealed partial class GridInRangeRule : RulesRule +{ + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform)) + { + return false; + } + + if (xform.GridUid != null) + { + return !Inverted; + } + + var transform = entManager.System(); + var mapManager = IoCManager.Resolve(); + + var worldPos = transform.GetWorldPosition(xform); + var gridRange = new Vector2(Range, Range); + + foreach (var _ in mapManager.FindGridsIntersecting(xform.MapID, new Box2(worldPos - gridRange, worldPos + gridRange))) + { + return !Inverted; + } + + return false; + } +} diff --git a/Content.Shared/Random/Rules/InSpace.cs b/Content.Shared/Random/Rules/InSpace.cs new file mode 100644 index 0000000000..8163e1f6be --- /dev/null +++ b/Content.Shared/Random/Rules/InSpace.cs @@ -0,0 +1,18 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if the attached entity is in space. +/// +public sealed partial class InSpaceRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.GridUid != null) + { + return Inverted; + } + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyAccess.cs b/Content.Shared/Random/Rules/NearbyAccess.cs new file mode 100644 index 0000000000..2a8ad077c6 --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyAccess.cs @@ -0,0 +1,77 @@ +using Content.Shared.Access; +using Content.Shared.Access.Components; +using Content.Shared.Access.Systems; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +/// +/// Checks for an entity nearby with the specified access. +/// +public sealed partial class NearbyAccessRule : RulesRule +{ + // This exists because of door electronics contained inside doors. + /// + /// Does the access entity need to be anchored. + /// + [DataField] + public bool Anchored = true; + + /// + /// Count of entities that need to be nearby. + /// + [DataField] + public int Count = 1; + + [DataField(required: true)] + public List> Access = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + var xformQuery = entManager.GetEntityQuery(); + + if (!xformQuery.TryGetComponent(uid, out var xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + var reader = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform, xformQuery); + var count = 0; + + // TODO: Update this when we get the callback version + var entities = new HashSet>(); + lookup.GetEntitiesInRange(xform.MapID, worldPos, Range, entities); + foreach (var comp in entities) + { + if (!reader.AreAccessTagsAllowed(Access, comp) || + Anchored && + (!xformQuery.TryGetComponent(comp, out var compXform) || + !compXform.Anchored)) + { + continue; + } + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyComponents.cs b/Content.Shared/Random/Rules/NearbyComponents.cs new file mode 100644 index 0000000000..13108e88d6 --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyComponents.cs @@ -0,0 +1,71 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +public sealed partial class NearbyComponentsRule : RulesRule +{ + /// + /// Does the entity need to be anchored. + /// + [DataField] + public bool Anchored; + + [DataField] + public int Count; + + [DataField(required: true)] + public ComponentRegistry Components = default!; + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + var inRange = new HashSet>(); + var xformQuery = entManager.GetEntityQuery(); + + if (!xformQuery.TryGetComponent(uid, out var xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform); + var count = 0; + + foreach (var compType in Components.Values) + { + inRange.Clear(); + lookup.GetEntitiesInRange(compType.Component.GetType(), xform.MapID, worldPos, Range, inRange); + foreach (var comp in inRange) + { + if (Anchored && + (!xformQuery.TryGetComponent(comp, out var compXform) || + !compXform.Anchored)) + { + continue; + } + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (found) + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyEntities.cs b/Content.Shared/Random/Rules/NearbyEntities.cs new file mode 100644 index 0000000000..0754750bc4 --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyEntities.cs @@ -0,0 +1,58 @@ +using Content.Shared.Whitelist; + +namespace Content.Shared.Random.Rules; + +/// +/// Checks for entities matching the whitelist in range. +/// This is more expensive than so prefer that! +/// +public sealed partial class NearbyEntitiesRule : RulesRule +{ + /// + /// How many of the entity need to be nearby. + /// + [DataField] + public int Count = 1; + + [DataField(required: true)] + public EntityWhitelist Whitelist = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.MapUid == null) + { + return false; + } + + var transform = entManager.System(); + var lookup = entManager.System(); + var whitelistSystem = entManager.System(); + + var found = false; + var worldPos = transform.GetWorldPosition(xform); + var count = 0; + + foreach (var ent in lookup.GetEntitiesInRange(xform.MapID, worldPos, Range)) + { + if (whitelistSystem.IsWhitelistFail(Whitelist, ent)) + continue; + + count++; + + if (count < Count) + continue; + + found = true; + break; + } + + if (!found) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/NearbyTilesPercent.cs b/Content.Shared/Random/Rules/NearbyTilesPercent.cs new file mode 100644 index 0000000000..465ac8dc5c --- /dev/null +++ b/Content.Shared/Random/Rules/NearbyTilesPercent.cs @@ -0,0 +1,79 @@ +using Content.Shared.Maps; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Physics.Components; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +public sealed partial class NearbyTilesPercentRule : RulesRule +{ + /// + /// If there are anchored entities on the tile do we ignore the tile. + /// + [DataField] + public bool IgnoreAnchored; + + [DataField(required: true)] + public float Percent; + + [DataField(required: true)] + public List> Tiles = new(); + + [DataField] + public float Range = 10f; + + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + !entManager.TryGetComponent(xform.GridUid, out var grid)) + { + return false; + } + + var transform = entManager.System(); + var tileDef = IoCManager.Resolve(); + + var physicsQuery = entManager.GetEntityQuery(); + var tileCount = 0; + var matchingTileCount = 0; + + foreach (var tile in grid.GetTilesIntersecting(new Circle(transform.GetWorldPosition(xform), + Range))) + { + // Only consider collidable anchored (for reasons some subfloor stuff has physics but non-collidable) + if (IgnoreAnchored) + { + var gridEnum = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices); + var found = false; + + while (gridEnum.MoveNext(out var ancUid)) + { + if (!physicsQuery.TryGetComponent(ancUid, out var physics) || + !physics.CanCollide) + { + continue; + } + + found = true; + break; + } + + if (found) + continue; + } + + tileCount++; + + if (!Tiles.Contains(tileDef[tile.Tile.TypeId].ID)) + continue; + + matchingTileCount++; + } + + if (tileCount == 0 || matchingTileCount / (float) tileCount < Percent) + return Inverted; + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/OnMapGrid.cs b/Content.Shared/Random/Rules/OnMapGrid.cs new file mode 100644 index 0000000000..bea841872e --- /dev/null +++ b/Content.Shared/Random/Rules/OnMapGrid.cs @@ -0,0 +1,19 @@ +namespace Content.Shared.Random.Rules; + +/// +/// Returns true if griduid and mapuid match (AKA on 'planet'). +/// +public sealed partial class OnMapGridRule : RulesRule +{ + public override bool Check(EntityManager entManager, EntityUid uid) + { + if (!entManager.TryGetComponent(uid, out TransformComponent? xform) || + xform.GridUid != xform.MapUid || + xform.MapUid == null) + { + return Inverted; + } + + return !Inverted; + } +} diff --git a/Content.Shared/Random/Rules/RulesSystem.cs b/Content.Shared/Random/Rules/RulesSystem.cs new file mode 100644 index 0000000000..1957beab51 --- /dev/null +++ b/Content.Shared/Random/Rules/RulesSystem.cs @@ -0,0 +1,39 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random.Rules; + +/// +/// Rules-based item selection. Can be used for any sort of conditional selection +/// Every single condition needs to be true for this to be selected. +/// e.g. "choose maintenance audio if 90% of tiles nearby are maintenance tiles" +/// +[Prototype("rules")] +public sealed partial class RulesPrototype : IPrototype +{ + [IdDataField] public string ID { get; } = string.Empty; + + [DataField("rules", required: true)] + public List Rules = new(); +} + +[ImplicitDataDefinitionForInheritors] +public abstract partial class RulesRule +{ + [DataField] + public bool Inverted; + public abstract bool Check(EntityManager entManager, EntityUid uid); +} + +public sealed class RulesSystem : EntitySystem +{ + public bool IsTrue(EntityUid uid, RulesPrototype rules) + { + foreach (var rule in rules.Rules) + { + if (!rule.Check(EntityManager, uid)) + return false; + } + + return true; + } +} diff --git a/Content.Shared/Random/RulesPrototype.cs b/Content.Shared/Random/RulesPrototype.cs deleted file mode 100644 index 20961af8e7..0000000000 --- a/Content.Shared/Random/RulesPrototype.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Content.Shared.Access; -using Content.Shared.Maps; -using Content.Shared.Whitelist; -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; - -namespace Content.Shared.Random; - -/// -/// Rules-based item selection. Can be used for any sort of conditional selection -/// Every single condition needs to be true for this to be selected. -/// e.g. "choose maintenance audio if 90% of tiles nearby are maintenance tiles" -/// -[Prototype("rules")] -public sealed partial class RulesPrototype : IPrototype -{ - [IdDataField] public string ID { get; } = string.Empty; - - [DataField("rules", required: true)] - public List Rules = new(); -} - -[ImplicitDataDefinitionForInheritors] -public abstract partial class RulesRule -{ - -} - -/// -/// Returns true if the attached entity is in space. -/// -public sealed partial class InSpaceRule : RulesRule -{ - -} - -/// -/// Checks for entities matching the whitelist in range. -/// This is more expensive than so prefer that! -/// -public sealed partial class NearbyEntitiesRule : RulesRule -{ - /// - /// How many of the entity need to be nearby. - /// - [DataField("count")] - public int Count = 1; - - [DataField("whitelist", required: true)] - public EntityWhitelist Whitelist = new(); - - [DataField("range")] - public float Range = 10f; -} - -public sealed partial class NearbyTilesPercentRule : RulesRule -{ - /// - /// If there are anchored entities on the tile do we ignore the tile. - /// - [DataField("ignoreAnchored")] public bool IgnoreAnchored; - - [DataField("percent", required: true)] - public float Percent; - - [DataField("tiles", required: true, customTypeSerializer:typeof(PrototypeIdListSerializer))] - public List Tiles = new(); - - [DataField("range")] - public float Range = 10f; -} - -/// -/// Always returns true. Used for fallbacks. -/// -public sealed partial class AlwaysTrueRule : RulesRule -{ - -} - -/// -/// Returns true if on a grid or in range of one. -/// -public sealed partial class GridInRangeRule : RulesRule -{ - [DataField("range")] - public float Range = 10f; - - [DataField("inverted")] - public bool Inverted = false; -} - -/// -/// Returns true if griduid and mapuid match (AKA on 'planet'). -/// -public sealed partial class OnMapGridRule : RulesRule -{ - -} - -/// -/// Checks for an entity nearby with the specified access. -/// -public sealed partial class NearbyAccessRule : RulesRule -{ - // This exists because of doorelectronics contained inside doors. - /// - /// Does the access entity need to be anchored. - /// - [DataField("anchored")] - public bool Anchored = true; - - /// - /// Count of entities that need to be nearby. - /// - [DataField("count")] - public int Count = 1; - - [DataField("access", required: true)] - public List> Access = new(); - - [DataField("range")] - public float Range = 10f; -} - -public sealed partial class NearbyComponentsRule : RulesRule -{ - /// - /// Does the entity need to be anchored. - /// - [DataField("anchored")] - public bool Anchored; - - [DataField("count")] public int Count; - - [DataField("components", required: true)] - public ComponentRegistry Components = default!; - - [DataField("range")] - public float Range = 10f; -} diff --git a/Content.Shared/Random/RulesSystem.cs b/Content.Shared/Random/RulesSystem.cs deleted file mode 100644 index 58d67c268e..0000000000 --- a/Content.Shared/Random/RulesSystem.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System.Numerics; -using Content.Shared.Access.Components; -using Content.Shared.Access.Systems; -using Content.Shared.Whitelist; -using Robust.Shared.Map; -using Robust.Shared.Map.Components; -using Robust.Shared.Physics.Components; - -namespace Content.Shared.Random; - -public sealed class RulesSystem : EntitySystem -{ - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDef = default!; - [Dependency] private readonly AccessReaderSystem _reader = default!; - [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; - [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; - public bool IsTrue(EntityUid uid, RulesPrototype rules) - { - var inRange = new HashSet>(); - foreach (var rule in rules.Rules) - { - switch (rule) - { - case AlwaysTrueRule: - break; - case GridInRangeRule griddy: - { - if (!TryComp(uid, out TransformComponent? xform)) - { - return false; - } - - if (xform.GridUid != null) - { - return !griddy.Inverted; - } - - var worldPos = _transform.GetWorldPosition(xform); - var gridRange = new Vector2(griddy.Range, griddy.Range); - - foreach (var _ in _mapManager.FindGridsIntersecting( - xform.MapID, - new Box2(worldPos - gridRange, worldPos + gridRange))) - { - return !griddy.Inverted; - } - - break; - } - case InSpaceRule: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.GridUid != null) - { - return false; - } - - break; - } - case NearbyAccessRule access: - { - var xformQuery = GetEntityQuery(); - - if (!xformQuery.TryGetComponent(uid, out var xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform, xformQuery); - var count = 0; - - // TODO: Update this when we get the callback version - var entities = new HashSet>(); - _lookup.GetEntitiesInRange(xform.MapID, worldPos, access.Range, entities); - foreach (var comp in entities) - { - if (!_reader.AreAccessTagsAllowed(access.Access, comp) || - access.Anchored && - (!xformQuery.TryGetComponent(comp, out var compXform) || - !compXform.Anchored)) - { - continue; - } - - count++; - - if (count < access.Count) - continue; - - found = true; - break; - } - - if (!found) - return false; - - break; - } - case NearbyComponentsRule nearbyComps: - { - var xformQuery = GetEntityQuery(); - - if (!xformQuery.TryGetComponent(uid, out var xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform); - var count = 0; - - foreach (var compType in nearbyComps.Components.Values) - { - inRange.Clear(); - _lookup.GetEntitiesInRange(compType.Component.GetType(), xform.MapID, worldPos, nearbyComps.Range, inRange); - foreach (var comp in inRange) - { - if (nearbyComps.Anchored && - (!xformQuery.TryGetComponent(comp, out var compXform) || - !compXform.Anchored)) - { - continue; - } - - count++; - - if (count < nearbyComps.Count) - continue; - - found = true; - break; - } - - if (found) - break; - } - - if (!found) - return false; - - break; - } - case NearbyEntitiesRule entity: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.MapUid == null) - { - return false; - } - - var found = false; - var worldPos = _transform.GetWorldPosition(xform); - var count = 0; - - foreach (var ent in _lookup.GetEntitiesInRange(xform.MapID, worldPos, entity.Range)) - { - if (_whitelistSystem.IsWhitelistFail(entity.Whitelist, ent)) - continue; - - count++; - - if (count < entity.Count) - continue; - - found = true; - break; - } - - if (!found) - return false; - - break; - } - case NearbyTilesPercentRule tiles: - { - if (!TryComp(uid, out TransformComponent? xform) || - !TryComp(xform.GridUid, out var grid)) - { - return false; - } - - var physicsQuery = GetEntityQuery(); - var tileCount = 0; - var matchingTileCount = 0; - - foreach (var tile in grid.GetTilesIntersecting(new Circle(_transform.GetWorldPosition(xform), - tiles.Range))) - { - // Only consider collidable anchored (for reasons some subfloor stuff has physics but non-collidable) - if (tiles.IgnoreAnchored) - { - var gridEnum = grid.GetAnchoredEntitiesEnumerator(tile.GridIndices); - var found = false; - - while (gridEnum.MoveNext(out var ancUid)) - { - if (!physicsQuery.TryGetComponent(ancUid, out var physics) || - !physics.CanCollide) - { - continue; - } - - found = true; - break; - } - - if (found) - continue; - } - - tileCount++; - - if (!tiles.Tiles.Contains(_tileDef[tile.Tile.TypeId].ID)) - continue; - - matchingTileCount++; - } - - if (tileCount == 0 || matchingTileCount / (float) tileCount < tiles.Percent) - return false; - - break; - } - case OnMapGridRule: - { - if (!TryComp(uid, out TransformComponent? xform) || - xform.GridUid != xform.MapUid || - xform.MapUid == null) - { - return false; - } - - break; - } - default: - throw new NotImplementedException(); - } - } - - return true; - } -} From a0052c5b0996dd88a4ed2d4fd5c8c15a030e8e93 Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Sun, 14 Jul 2024 10:08:39 -0400 Subject: [PATCH 07/13] Prevent virtual item storage and popups (#30020) * Prevent virtual item storage and popups * fix typo * add comment --- Content.Shared/Interaction/SmartEquipSystem.cs | 11 ++++++----- .../Inventory/VirtualItem/SharedVirtualItemSystem.cs | 8 ++++++++ .../Prototypes/Entities/Virtual/virtual_item.yml | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Content.Shared/Interaction/SmartEquipSystem.cs b/Content.Shared/Interaction/SmartEquipSystem.cs index bba294db28..4feb0445f8 100644 --- a/Content.Shared/Interaction/SmartEquipSystem.cs +++ b/Content.Shared/Interaction/SmartEquipSystem.cs @@ -62,21 +62,22 @@ public sealed class SmartEquipSystem : EntitySystem if (playerSession.AttachedEntity is not { Valid: true } uid || !Exists(uid)) return; - if (!_actionBlocker.CanInteract(uid, null)) - return; - // early out if we don't have any hands or a valid inventory slot if (!TryComp(uid, out var hands) || hands.ActiveHand == null) return; + var handItem = hands.ActiveHand.HeldEntity; + + // can the user interact, and is the item interactable? e.g. virtual items + if (!_actionBlocker.CanInteract(uid, handItem)) + return; + if (!TryComp(uid, out var inventory) || !_inventory.HasSlot(uid, equipmentSlot, inventory)) { _popup.PopupClient(Loc.GetString("smart-equip-missing-equipment-slot", ("slotName", equipmentSlot)), uid, uid); return; } - var handItem = hands.ActiveHand.HeldEntity; - // early out if we have an item and cant drop it at all if (handItem != null && !_hands.CanDropHeld(uid, hands.ActiveHand)) { diff --git a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs index cd0863ec88..8b9c052c8d 100644 --- a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs +++ b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Hands; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Popups; @@ -43,6 +44,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem SubscribeLocalEvent(OnBeingUnequippedAttempt); SubscribeLocalEvent(OnBeforeRangedInteract); + SubscribeLocalEvent(OnGettingInteractedWithAttemptEvent); } /// @@ -72,6 +74,12 @@ public abstract class SharedVirtualItemSystem : EntitySystem args.Handled = true; } + private void OnGettingInteractedWithAttemptEvent(Entity ent, ref GettingInteractedWithAttemptEvent args) + { + // No interactions with a virtual item, please. + args.Cancelled = true; + } + #region Hands /// diff --git a/Resources/Prototypes/Entities/Virtual/virtual_item.yml b/Resources/Prototypes/Entities/Virtual/virtual_item.yml index ed74243550..088de6a6da 100644 --- a/Resources/Prototypes/Entities/Virtual/virtual_item.yml +++ b/Resources/Prototypes/Entities/Virtual/virtual_item.yml @@ -5,4 +5,5 @@ noSpawn: true components: - type: Item + size: Ginormous # no storage insertion visuals - type: VirtualItem From b6115b672aa6a67e693c8ac21ada4083f5eb0871 Mon Sep 17 00:00:00 2001 From: CookieMasterT <124045269+CookieMasterT@users.noreply.github.com> Date: Sun, 14 Jul 2024 16:09:41 +0200 Subject: [PATCH 08/13] Add petting cyborgs (#30037) added petting borgs, adjusted interactions --- .../interaction-popup-component.ftl | 14 ++++++ .../Mobs/Cyborgs/base_borg_chassis.yml | 1 + .../Entities/Mobs/Cyborgs/borg_chassis.yml | 45 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index 55be1fb3b9..10773d6de8 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -60,12 +60,26 @@ petting-success-honkbot = You pet {THE($target)} on {POSS-ADJ($target)} slippery petting-success-mimebot = You pet {THE($target)} on {POSS-ADJ($target)} cold metal head. petting-success-cleanbot = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head. petting-success-medibot = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head. +petting-success-generic-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} metal head. +petting-success-salvage-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dirty metal head. +petting-success-engineer-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} reflective metal head. +petting-success-janitor-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head. +petting-success-medical-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head. +petting-success-service-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dapper looking metal head. +petting-success-syndicate-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} menacing metal head. petting-success-recycler = You pet {THE($target)} on {POSS-ADJ($target)} mildly threatening steel exterior. petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BASIC($target, "honk", "honks")} in refusal! petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping! petting-failure-mimebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy miming! petting-failure-medibot = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} syringe nearly stabs your hand! +petting-failure-generic-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy stating laws! +petting-failure-salvage-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy drilling! +petting-failure-engineer-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy repairing! +petting-failure-janitor-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy cleaning! +petting-failure-medical-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy saving lives! +petting-failure-service-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy serving others! +petting-failure-syndicate-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} treacherous affiliation makes you reconsider. ## Rattling fences diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 6656a7aadb..2618207b7a 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -150,6 +150,7 @@ - type: Lock locked: true breakOnEmag: false + unlockOnClick: false - type: ActivatableUIRequiresLock - type: LockedWiresPanel - type: Damageable diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml index 075ac534c6..3a17869dc8 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml @@ -29,6 +29,11 @@ node: cyborg - type: Speech speechVerb: Robotic + - type: InteractionPopup + interactSuccessString: petting-success-generic-cyborg + interactFailureString: petting-failure-generic-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisMining @@ -85,6 +90,11 @@ access: [["Cargo"], ["Salvage"], ["Command"], ["Research"]] - type: Inventory templateId: borgTall + - type: InteractionPopup + interactSuccessString: petting-success-salvage-cyborg + interactFailureString: petting-failure-salvage-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisEngineer @@ -133,6 +143,11 @@ access: [["Engineering"], ["Command"], ["Research"]] - type: Inventory templateId: borgShort + - type: InteractionPopup + interactSuccessString: petting-success-engineer-cyborg + interactFailureString: petting-failure-engineer-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisJanitor @@ -189,6 +204,11 @@ access: [["Service"], ["Command"], ["Research"]] - type: Inventory templateId: borgShort + - type: InteractionPopup + interactSuccessString: petting-success-janitor-cyborg + interactFailureString: petting-failure-janitor-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisMedical @@ -248,6 +268,11 @@ - type: FootstepModifier footstepSoundCollection: collection: FootstepHoverBorg + - type: InteractionPopup + interactSuccessString: petting-success-medical-cyborg + interactFailureString: petting-failure-medical-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisService @@ -296,6 +321,11 @@ access: [["Service"], ["Command"], ["Research"]] - type: Inventory templateId: borgTall + - type: InteractionPopup + interactSuccessString: petting-success-service-cyborg + interactFailureString: petting-failure-service-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateAssault @@ -325,6 +355,11 @@ noMindState: synd_sec - type: Construction node: syndicateassault + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateMedical @@ -357,6 +392,11 @@ - type: ShowHealthBars damageContainers: - Biological + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg - type: entity id: BorgChassisSyndicateSaboteur @@ -390,3 +430,8 @@ damageContainers: - Inorganic - Silicon + - type: InteractionPopup + interactSuccessString: petting-success-syndicate-cyborg + interactFailureString: petting-failure-syndicate-cyborg + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg From f6d827f5d98c772b38c8fdc960be2f0a4026c6bf Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 14:10:48 +0000 Subject: [PATCH 09/13] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d06bda3324..f0ef8806ad 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Terraspark4941 - changes: - - message: Updated the engineering section of the guidebook! - type: Tweak - id: 6419 - time: '2024-04-22T08:58:54.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26851 - author: eclips_e changes: - message: Slimepeople can now morph into a "geras"--a smaller slime form that can @@ -3812,3 +3805,12 @@ id: 6918 time: '2024-07-14T10:26:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/29904 +- author: HahayesSiH + changes: + - message: It is now possible to pet cyborgs. + type: Add + - message: Clicking on cyborgs and opening the strip menu no longer unlocks them. + type: Tweak + id: 6919 + time: '2024-07-14T14:09:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30037 From 35cd013e88091311fb2c179aa8523f9d68f78bc1 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sun, 14 Jul 2024 15:11:40 +0000 Subject: [PATCH 10/13] make ninja shoes magboots (#28586) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Entities/Clothing/Shoes/specific.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml index 4ae752345a..80d5eab249 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/specific.yml @@ -121,6 +121,7 @@ - type: Clothing sprite: Clothing/Shoes/Specific/spaceninja.rsi - type: NoSlip + - type: Magboots # always have gravity because le suction cups - type: ClothingSpeedModifier # ninja are masters of sneaking around relatively quickly, won't break cloak walkModifier: 1.1 From 3b85b1e43e16a8d183fca4438e8d0eabb57900dc Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 14 Jul 2024 17:12:25 +0200 Subject: [PATCH 11/13] make scarves eatable again (#29959) --- .../Prototypes/Entities/Clothing/Neck/base_clothingneck.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index d2fffb8153..d7f04f49bc 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -38,3 +38,4 @@ - type: Tag tags: - Scarf + - ClothMade From 17c23f11c5c798814c2d948af02f958e6384a779 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 14 Jul 2024 15:13:31 +0000 Subject: [PATCH 12/13] Automatic changelog update --- Resources/Changelog/Changelog.yml | 37 ++++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f0ef8806ad..0b965b1970 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,27 +1,4 @@ Entries: -- author: eclips_e - changes: - - message: Slimepeople can now morph into a "geras"--a smaller slime form that can - pass under grilles, at the cost of dropping all of their inventory. They can - also be picked up with two hands and placed into duffelbags. - type: Add - - message: Slimepeople now have an internal 2x2 storage that they (and anyone around - them) can access. It is not dropped when morphing into a geras! - type: Add - - message: Slimepeople now have slightly increased regeneration and a slightly meatier - punch, but slower attacks. - type: Add - id: 6420 - time: '2024-04-22T10:03:03.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/23425 -- author: FungiFellow - changes: - - message: Syndi-Cats are now 6TC, Insulated, Available to Syndies, Can Move in - Space, Open Doors, and Hit Harder - type: Tweak - id: 6421 - time: '2024-04-22T12:18:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27222 - author: Tayrtahn changes: - message: Ghosts can no longer trigger artifacts by examining them. @@ -3814,3 +3791,17 @@ id: 6919 time: '2024-07-14T14:09:41.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30037 +- author: deltanedas + changes: + - message: Fixed ninja shoes not working as magboots. + type: Fix + id: 6920 + time: '2024-07-14T15:11:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28586 +- author: lzk228 + changes: + - message: Scarves are eatable again. + type: Fix + id: 6921 + time: '2024-07-14T15:12:25.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/29959 From b7d3964c5672bc3fe0ee683ad168cb3f8d74b335 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 15 Jul 2024 00:07:48 +0200 Subject: [PATCH 13/13] Fix AccessLevelControl breaking (#30045) #29987 did an oopsie This broke the ID computer, station records, and maybe some others too. --- Content.Client/Access/UI/AccessLevelControl.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs index 9f09eceec0..12487b2e5c 100644 --- a/Content.Client/Access/UI/AccessLevelControl.xaml.cs +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -21,6 +21,7 @@ public sealed partial class AccessLevelControl : GridContainer public AccessLevelControl() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); _sawmill = _logManager.GetSawmill("accesslevelcontrol"); }