From 277f3320f5d89a52fd5d5a1311cd2b3daa3cfc3d Mon Sep 17 00:00:00 2001 From: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Date: Tue, 28 Dec 2021 19:23:16 -0800 Subject: [PATCH 01/12] Update submodule --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index c07eaecacb..e3dc446e9e 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit c07eaecacb654307262a28cb24c14c839a82f8ed +Subproject commit e3dc446e9ea75d6802686397cf19023bd4433e64 From 299c4be3287f50dbedd7e7a5f4223ee3e4014b35 Mon Sep 17 00:00:00 2001 From: CrudeWax <75271456+CrudeWax@users.noreply.github.com> Date: Wed, 29 Dec 2021 06:58:48 +0300 Subject: [PATCH 02/12] Guardians (Holoparasites) (#5140) Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Co-authored-by: Metal Gear Sloth --- Content.Client/Entry/IgnoredComponents.cs | 3 + .../Actions/Actions/GuardianToggleAction.cs | 38 ++ Content.Server/Guardian/GuardianComponent.cs | 39 ++ .../Guardian/GuardianCreatorComponent.cs | 39 ++ .../Guardian/GuardianHostComponent.cs | 27 ++ Content.Server/Guardian/GuardianSystem.cs | 349 ++++++++++++++++++ Content.Shared/Actions/ActionType.cs | 1 + .../MobState/Components/MobStateComponent.cs | 2 +- .../MobState/EntitySystems/MobStateSystem.cs | 4 +- Resources/Audio/Effects/guardian_inject.ogg | Bin 0 -> 22763 bytes Resources/Audio/Effects/guardian_warn.ogg | Bin 0 -> 30782 bytes .../Audio/Voice/Human/malescream_guardian.ogg | Bin 0 -> 18748 bytes Resources/Locale/en-US/guardian/guardian.ftl | 22 ++ .../Prototypes/Actions/guardian_actions.yml | 12 + .../Catalog/Fills/Paper/manuals.yml | 29 ++ .../Prototypes/Catalog/uplink_catalog.yml | 20 +- .../Entities/Clothing/Head/soft.yml | 22 ++ .../Entities/Mobs/Player/guardian.yml | 73 ++++ .../Syndicate_Gadgets/guardian_activators.yml | 26 ++ .../Soft/bizarresoft.rsi/equipped-HELMET.png | Bin 0 -> 423 bytes .../Head/Soft/bizarresoft.rsi/icon.png | Bin 0 -> 386 bytes .../Head/Soft/bizarresoft.rsi/inhand-left.png | Bin 0 -> 411 bytes .../Soft/bizarresoft.rsi/inhand-right.png | Bin 0 -> 412 bytes .../Head/Soft/bizarresoft.rsi/meta.json | 26 ++ .../equipped-HELMET.png | Bin 0 -> 418 bytes .../Soft/bizarresoft_flipped.rsi/icon.png | Bin 0 -> 392 bytes .../bizarresoft_flipped.rsi/inhand-left.png | Bin 0 -> 411 bytes .../bizarresoft_flipped.rsi/inhand-right.png | Bin 0 -> 458 bytes .../Soft/bizarresoft_flipped.rsi/meta.json | 26 ++ .../Textures/Interface/Actions/manifest.png | Bin 0 -> 1922 bytes .../Textures/Interface/Actions/meta.json | 3 + .../Aliens/Guardians/guardians.rsi/magic.png | Bin 0 -> 924 bytes .../Guardians/guardians.rsi/magic_base.png | Bin 0 -> 1329 bytes .../Guardians/guardians.rsi/magic_flare.png | Bin 0 -> 1099 bytes .../Aliens/Guardians/guardians.rsi/meta.json | 57 +++ .../Aliens/Guardians/guardians.rsi/miner.png | Bin 0 -> 681 bytes .../Guardians/guardians.rsi/miner_base.png | Bin 0 -> 2776 bytes .../Guardians/guardians.rsi/miner_flare.png | Bin 0 -> 801 bytes .../Aliens/Guardians/guardians.rsi/tech.png | Bin 0 -> 854 bytes .../Guardians/guardians.rsi/tech_base.png | Bin 0 -> 1694 bytes .../Guardians/guardians.rsi/tech_flare.png | Bin 0 -> 930 bytes .../Misc/guardian_info.rsi/guardian_info.png | Bin 0 -> 1551 bytes .../Objects/Misc/guardian_info.rsi/icon.png | Bin 0 -> 952 bytes .../Objects/Misc/guardian_info.rsi/meta.json | 25 ++ 44 files changed, 836 insertions(+), 7 deletions(-) create mode 100644 Content.Server/Actions/Actions/GuardianToggleAction.cs create mode 100644 Content.Server/Guardian/GuardianComponent.cs create mode 100644 Content.Server/Guardian/GuardianCreatorComponent.cs create mode 100644 Content.Server/Guardian/GuardianHostComponent.cs create mode 100644 Content.Server/Guardian/GuardianSystem.cs create mode 100644 Resources/Audio/Effects/guardian_inject.ogg create mode 100644 Resources/Audio/Effects/guardian_warn.ogg create mode 100644 Resources/Audio/Voice/Human/malescream_guardian.ogg create mode 100644 Resources/Locale/en-US/guardian/guardian.ftl create mode 100644 Resources/Prototypes/Actions/guardian_actions.yml create mode 100644 Resources/Prototypes/Entities/Mobs/Player/guardian.yml create mode 100644 Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/guardian_activators.yml create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json create mode 100644 Resources/Textures/Interface/Actions/manifest.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/magic.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/magic_base.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/magic_flare.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner_base.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner_flare.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech_base.png create mode 100644 Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech_flare.png create mode 100644 Resources/Textures/Objects/Misc/guardian_info.rsi/guardian_info.png create mode 100644 Resources/Textures/Objects/Misc/guardian_info.rsi/icon.png create mode 100644 Resources/Textures/Objects/Misc/guardian_info.rsi/meta.json diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index db6bf409f9..5741ee1b8f 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -314,6 +314,9 @@ namespace Content.Client.Entry "NukeCodePaper", "GhostRadio", "Armor", + "Guardian", + "GuardianCreator", + "GuardianHost", "Udder", "PneumaticCannon", "Spreader", diff --git a/Content.Server/Actions/Actions/GuardianToggleAction.cs b/Content.Server/Actions/Actions/GuardianToggleAction.cs new file mode 100644 index 0000000000..5343e72284 --- /dev/null +++ b/Content.Server/Actions/Actions/GuardianToggleAction.cs @@ -0,0 +1,38 @@ +using Content.Server.Guardian; +using Content.Shared.Actions.Behaviors; +using Content.Shared.Cooldown; +using Content.Shared.Popups; +using JetBrains.Annotations; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Actions.Actions +{ + /// + /// Manifests the guardian saved in the action, using the system + /// + [UsedImplicitly] + [DataDefinition] + public class ToggleGuardianAction : IInstantAction + { + [DataField("cooldown")] public float Cooldown { get; [UsedImplicitly] private set; } + + public void DoInstantAction(InstantActionEventArgs args) + { + var entManager = IoCManager.Resolve(); + + if (entManager.TryGetComponent(args.Performer, out GuardianHostComponent? hostComponent) && + hostComponent.HostedGuardian != null) + { + EntitySystem.Get().ToggleGuardian(hostComponent); + args.PerformerActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown)); + } + else + { + args.Performer.PopupMessage(Loc.GetString("guardian-missing-invalid-action")); + } + } + } +} diff --git a/Content.Server/Guardian/GuardianComponent.cs b/Content.Server/Guardian/GuardianComponent.cs new file mode 100644 index 0000000000..a8ebedf22c --- /dev/null +++ b/Content.Server/Guardian/GuardianComponent.cs @@ -0,0 +1,39 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Guardian +{ + /// + /// Given to guardians to monitor their link with the host + /// + [RegisterComponent] + [ComponentProtoName("Guardian")] + public class GuardianComponent : Component + { + /// + /// The guardian host entity + /// + public EntityUid Host; + + /// + /// Percentage of damage reflected from the guardian to the host + /// + [ViewVariables] + [DataField("damageShare")] + public float DamageShare { get; set; } = 0.85f; + + /// + /// Maximum distance the guardian can travel before it's forced to recall, use YAML to set + /// + [ViewVariables] + [DataField("distanceAllowed")] + public float DistanceAllowed { get; set; } = 5f; + + /// + /// If the guardian is currently manifested + /// + public bool GuardianLoose = false; + + } +} diff --git a/Content.Server/Guardian/GuardianCreatorComponent.cs b/Content.Server/Guardian/GuardianCreatorComponent.cs new file mode 100644 index 0000000000..d581ddc351 --- /dev/null +++ b/Content.Server/Guardian/GuardianCreatorComponent.cs @@ -0,0 +1,39 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Guardian +{ + /// + /// Creates a GuardianComponent attached to the user's GuardianHost. + /// + [RegisterComponent] + [ComponentProtoName("GuardianCreator")] + public sealed class GuardianCreatorComponent : Component + { + /// + /// Counts as spent upon exhausting the injection + /// + /// + /// We don't mark as deleted as examine depends on this. + /// + public bool Used = false; + + /// + /// The prototype of the guardian entity which will be created + /// + [ViewVariables] + [DataField("guardianProto", customTypeSerializer:typeof(PrototypeIdSerializer), required: true)] + public string GuardianProto { get; set; } = default!; + + /// + /// How long it takes to inject someone. + /// + [DataField("delay")] + public float InjectionDelay = 5f; + + public bool Injecting = false; + } +} diff --git a/Content.Server/Guardian/GuardianHostComponent.cs b/Content.Server/Guardian/GuardianHostComponent.cs new file mode 100644 index 0000000000..e9aecdae2a --- /dev/null +++ b/Content.Server/Guardian/GuardianHostComponent.cs @@ -0,0 +1,27 @@ +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Guardian +{ + /// + /// Given to guardian users upon establishing a guardian link with the entity + /// + [RegisterComponent] + [ComponentProtoName("GuardianHost")] + public sealed class GuardianHostComponent : Component + { + /// + /// Guardian hosted within the component + /// + /// + /// Can be null if the component is added at any time. + /// + public EntityUid? HostedGuardian; + + /// + /// Container which holds the guardian + /// + [ViewVariables] public ContainerSlot GuardianContainer = default!; + } +} diff --git a/Content.Server/Guardian/GuardianSystem.cs b/Content.Server/Guardian/GuardianSystem.cs new file mode 100644 index 0000000000..7373a6c079 --- /dev/null +++ b/Content.Server/Guardian/GuardianSystem.cs @@ -0,0 +1,349 @@ +using Content.Server.Actions; +using Content.Server.DoAfter; +using Content.Server.Hands.Components; +using Content.Server.Inventory.Components; +using Content.Server.Popups; +using Content.Shared.Actions; +using Content.Shared.Actions.Components; +using Content.Shared.Audio; +using Content.Shared.Damage; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.MobState; +using Content.Shared.MobState.EntitySystems; +using Robust.Server.GameObjects; +using Robust.Shared.Audio; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Log; +using Robust.Shared.Player; +using Robust.Shared.Utility; + +namespace Content.Server.Guardian +{ + /// + /// A guardian has a host it's attached to that it fights for. A fighting spirit. + /// + public sealed class GuardianSystem : EntitySystem + { + [Dependency] private readonly DoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly DamageableSystem _damageSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnCreatorUse); + SubscribeLocalEvent(OnCreatorInteract); + SubscribeLocalEvent(OnCreatorExamine); + SubscribeLocalEvent(OnCreatorInject); + SubscribeLocalEvent(OnCreatorCancelled); + + SubscribeLocalEvent(OnGuardianMove); + SubscribeLocalEvent(OnGuardianDamaged); + SubscribeLocalEvent(OnGuardianPlayer); + SubscribeLocalEvent(OnGuardianUnplayer); + + SubscribeLocalEvent(OnHostInit); + SubscribeLocalEvent(OnHostMove); + SubscribeLocalEvent(OnHostStateChange); + SubscribeLocalEvent(OnHostShutdown); + } + + private void OnGuardianUnplayer(EntityUid uid, GuardianComponent component, PlayerDetachedEvent args) + { + var host = component.Host; + + if (!TryComp(host, out var hostComponent)) return; + + RetractGuardian(hostComponent, component); + } + + private void OnGuardianPlayer(EntityUid uid, GuardianComponent component, PlayerAttachedEvent args) + { + var host = component.Host; + + if (!HasComp(host)) return; + + _popupSystem.PopupEntity(Loc.GetString("guardian-available"), host, Filter.Entities(host)); + } + + private void OnHostInit(EntityUid uid, GuardianHostComponent component, ComponentInit args) + { + component.GuardianContainer = uid.EnsureContainer("GuardianContainer"); + } + + private void OnHostShutdown(EntityUid uid, GuardianHostComponent component, ComponentShutdown args) + { + if (component.HostedGuardian == null) return; + EntityManager.QueueDeleteEntity(component.HostedGuardian.Value); + } + + public void ToggleGuardian(GuardianHostComponent hostComponent) + { + if (hostComponent.HostedGuardian == null || + !TryComp(hostComponent.HostedGuardian, out GuardianComponent? guardianComponent)) return; + + if (guardianComponent.GuardianLoose) + { + RetractGuardian(hostComponent, guardianComponent); + } + else + { + ReleaseGuardian(hostComponent, guardianComponent); + } + } + + /// + /// Adds the guardian host component to the user and spawns the guardian inside said component + /// + private void OnCreatorUse(EntityUid uid, GuardianCreatorComponent component, UseInHandEvent args) + { + if (args.Handled) return; + args.Handled = true; + UseCreator(args.User, args.User, component); + } + + private void OnCreatorInteract(EntityUid uid, GuardianCreatorComponent component, AfterInteractEvent args) + { + if (args.Handled || args.Target == null) return; + args.Handled = true; + UseCreator(args.User, args.Target.Value, component); + } + + private void OnCreatorCancelled(GuardianCreatorInjectCancelledEvent ev) + { + ev.Component.Injecting = false; + } + + private void UseCreator(EntityUid user, EntityUid target, GuardianCreatorComponent component) + { + if (component.Used) + { + _popupSystem.PopupEntity(Loc.GetString("guardian-activator-empty-invalid-creation"), user, Filter.Entities(user)); + return; + } + + // If user is already a host don't duplicate. + if (HasComp(target)) + { + _popupSystem.PopupEntity(Loc.GetString("guardian-already-present-invalid-creation"), user, Filter.Entities(user)); + return; + } + + // Can't work without actions + EntityManager.EnsureComponent(target); + + if (component.Injecting) return; + + component.Injecting = true; + + _doAfterSystem.DoAfter(new DoAfterEventArgs(user, component.InjectionDelay, target: target) + { + BroadcastFinishedEvent = new GuardianCreatorInjectedEvent(user, target, component), + BroadcastCancelledEvent = new GuardianCreatorInjectCancelledEvent(target, component), + BreakOnTargetMove = true, + BreakOnUserMove = true, + }); + } + + private void OnCreatorInject(GuardianCreatorInjectedEvent ev) + { + var comp = ev.Component; + + if (comp.Deleted || + comp.Used || + !TryComp(ev.User, out var hands) || + !hands.IsHolding(comp.Owner) || + HasComp(ev.Target) || + !TryComp(ev.Target, out var actions)) + { + comp.Injecting = false; + return; + } + + var hostXform = EntityManager.GetComponent(ev.Target); + var host = EntityManager.EnsureComponent(ev.Target); + // Use map position so it's not inadvertantly parented to the host + if it's in a container it spawns outside I guess. + var guardian = EntityManager.SpawnEntity(comp.GuardianProto, hostXform.MapPosition); + + host.GuardianContainer.Insert(guardian); + host.HostedGuardian = guardian; + + if (TryComp(guardian, out GuardianComponent? guardianComponent)) + { + guardianComponent.Host = ev.Target; + + // Grant the user the recall action and notify them + actions.Grant(ActionType.ManifestGuardian); + SoundSystem.Play(Filter.Entities(ev.Target), "/Audio/Effects/guardian_inject.ogg", ev.Target); + + _popupSystem.PopupEntity(Loc.GetString("guardian-created"), ev.Target, Filter.Entities(ev.Target)); + // Exhaust the activator + comp.Used = true; + } + else + { + Logger.ErrorS("guardian", $"Tried to spawn a guardian that doesn't have {nameof(GuardianComponent)}"); + EntityManager.QueueDeleteEntity(guardian); + } + } + + /// + /// Triggers when the host receives damage which puts the host in either critical or killed state + /// + private void OnHostStateChange(EntityUid uid, GuardianHostComponent component, MobStateChangedEvent args) + { + if (component.HostedGuardian == null) return; + + if (args.CurrentMobState.IsCritical()) + { + _popupSystem.PopupEntity(Loc.GetString("guardian-critical-warn"), component.HostedGuardian.Value, Filter.Entities(component.HostedGuardian.Value)); + SoundSystem.Play(Filter.Entities(component.HostedGuardian.Value), "/Audio/Effects/guardian_warn.ogg", component.HostedGuardian.Value); + } + else if (args.CurrentMobState.IsDead()) + { + SoundSystem.Play(Filter.Pvs(uid), "/Audio/Voice/Human/malescream_guardian.ogg", uid, AudioHelpers.WithVariation(0.20f)); + EntityManager.RemoveComponent(uid); + } + } + + /// + /// Handles guardian receiving damage and splitting it with the host according to his defence percent + /// + private void OnGuardianDamaged(EntityUid uid, GuardianComponent component, DamageChangedEvent args) + { + if (args.DamageDelta == null) return; + + _damageSystem.TryChangeDamage(component.Host, args.DamageDelta * component.DamageShare); + _popupSystem.PopupEntity(Loc.GetString("guardian-entity-taking-damage"), component.Host, Filter.Entities(component.Host)); + + } + + /// + /// Triggers while trying to examine an activator to see if it's used + /// + private void OnCreatorExamine(EntityUid uid, GuardianCreatorComponent component, ExaminedEvent args) + { + if (component.Used) + { + args.PushMarkup(Loc.GetString("guardian-activator-empty-examine")); + } + } + + /// + /// Called every time the host moves, to make sure the distance between the host and the guardian isn't too far + /// + private void OnHostMove(EntityUid uid, GuardianHostComponent component, ref MoveEvent args) + { + if (component.HostedGuardian == null || + !TryComp(component.HostedGuardian, out GuardianComponent? guardianComponent) || + !guardianComponent.GuardianLoose) return; + + CheckGuardianMove(uid, component.HostedGuardian.Value, component); + } + + /// + /// Called every time the guardian moves: makes sure it's not out of it's allowed distance + /// + private void OnGuardianMove(EntityUid uid, GuardianComponent component, ref MoveEvent args) + { + if (!component.GuardianLoose) return; + + CheckGuardianMove(component.Host, uid, guardianComponent: component); + } + + /// + /// Retract the guardian if either the host or the guardian move away from each other. + /// + private void CheckGuardianMove( + EntityUid hostUid, + EntityUid guardianUid, + GuardianHostComponent? hostComponent = null, + GuardianComponent? guardianComponent = null, + TransformComponent? hostXform = null, + TransformComponent? guardianXform = null) + { + if (!Resolve(hostUid, ref hostComponent, ref hostXform) || + !Resolve(guardianUid, ref guardianComponent, ref guardianXform)) + { + return; + } + + if (!guardianComponent.GuardianLoose) return; + + if (!guardianXform.Coordinates.InRange(EntityManager, hostXform.Coordinates, guardianComponent.DistanceAllowed)) + { + RetractGuardian(hostComponent, guardianComponent); + } + } + + private bool CanRelease(GuardianHostComponent host, GuardianComponent guardian) + { + return HasComp(guardian.Owner); + } + + private void ReleaseGuardian(GuardianHostComponent hostComponent, GuardianComponent guardianComponent) + { + if (guardianComponent.GuardianLoose) + { + DebugTools.Assert(!hostComponent.GuardianContainer.Contains(guardianComponent.Owner)); + return; + } + + if (!CanRelease(hostComponent, guardianComponent)) + { + _popupSystem.PopupEntity(Loc.GetString("guardian-no-soul"), hostComponent.Owner, Filter.Entities(hostComponent.Owner)); + return; + } + + DebugTools.Assert(hostComponent.GuardianContainer.Contains(guardianComponent.Owner)); + hostComponent.GuardianContainer.Remove(guardianComponent.Owner); + DebugTools.Assert(!hostComponent.GuardianContainer.Contains(guardianComponent.Owner)); + + guardianComponent.GuardianLoose = true; + } + + private void RetractGuardian(GuardianHostComponent hostComponent, GuardianComponent guardianComponent) + { + if (!guardianComponent.GuardianLoose) + { + DebugTools.Assert(hostComponent.GuardianContainer.Contains(guardianComponent.Owner)); + return; + } + + hostComponent.GuardianContainer.Insert(guardianComponent.Owner); + DebugTools.Assert(hostComponent.GuardianContainer.Contains(guardianComponent.Owner)); + _popupSystem.PopupEntity(Loc.GetString("guardian-entity-recall"), hostComponent.Owner, Filter.Pvs(hostComponent.Owner)); + guardianComponent.GuardianLoose = false; + } + + private sealed class GuardianCreatorInjectedEvent : EntityEventArgs + { + public EntityUid User { get; } + public EntityUid Target { get; } + public GuardianCreatorComponent Component { get; } + + public GuardianCreatorInjectedEvent(EntityUid user, EntityUid target, GuardianCreatorComponent component) + { + User = user; + Target = target; + Component = component; + } + } + + private sealed class GuardianCreatorInjectCancelledEvent : EntityEventArgs + { + public EntityUid Target { get; } + public GuardianCreatorComponent Component { get; } + + public GuardianCreatorInjectCancelledEvent(EntityUid target, GuardianCreatorComponent component) + { + Target = target; + Component = component; + } + } + } +} diff --git a/Content.Shared/Actions/ActionType.cs b/Content.Shared/Actions/ActionType.cs index 0cb60f42f0..4eb19eaf34 100644 --- a/Content.Shared/Actions/ActionType.cs +++ b/Content.Shared/Actions/ActionType.cs @@ -18,6 +18,7 @@ namespace Content.Shared.Actions DebugTargetEntity, DebugTargetEntityRepeat, SpellPie, + ManifestGuardian, PAIMidi } diff --git a/Content.Shared/MobState/Components/MobStateComponent.cs b/Content.Shared/MobState/Components/MobStateComponent.cs index 697849abe5..90f9dfeaed 100644 --- a/Content.Shared/MobState/Components/MobStateComponent.cs +++ b/Content.Shared/MobState/Components/MobStateComponent.cs @@ -5,6 +5,7 @@ using System.Linq; using Content.Shared.Alert; using Content.Shared.Damage; using Content.Shared.FixedPoint; +using Content.Shared.MobState.EntitySystems; using Content.Shared.MobState.State; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; @@ -318,7 +319,6 @@ namespace Content.Shared.MobState.Components var message = new MobStateChangedEvent(this, old, state); entMan.EventBus.RaiseLocalEvent(Owner, message); - Dirty(); } } diff --git a/Content.Shared/MobState/EntitySystems/MobStateSystem.cs b/Content.Shared/MobState/EntitySystems/MobStateSystem.cs index 91dac34ca2..c4c2126f4d 100644 --- a/Content.Shared/MobState/EntitySystems/MobStateSystem.cs +++ b/Content.Shared/MobState/EntitySystems/MobStateSystem.cs @@ -111,7 +111,7 @@ namespace Content.Shared.MobState.EntitySystems private void OnStartPullAttempt(EntityUid uid, MobStateComponent component, StartPullAttemptEvent args) { - if(component.IsIncapacitated()) + if (component.IsIncapacitated()) args.Cancel(); } @@ -135,7 +135,7 @@ namespace Content.Shared.MobState.EntitySystems private void OnStandAttempt(EntityUid uid, MobStateComponent component, StandAttemptEvent args) { - if(component.IsIncapacitated()) + if (component.IsIncapacitated()) args.Cancel(); } } diff --git a/Resources/Audio/Effects/guardian_inject.ogg b/Resources/Audio/Effects/guardian_inject.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3dca7114a1849e78c9b7d6c60362b1667a03f751 GIT binary patch literal 22763 zcmafabzB`iv+y1`xLa{6uEiaSyHmWlYw;q*-CBx6@uDqI+}+*X-HSUEzC)kqeeb=0 zefj0=&W&bEC@}sE;X>27s5=*DXkm`%ezMu)WJv_ z5zxg__bLd?NgEZg#nLwwh$I@88YshgOAurs;{NKNGAKo)V*+7C`tX7zMIbeR<*maG z8Wbrc2%_hOCk-OwFvS6403a)eHX?@>5uKm{5$FQ|bYT_jUPq$-uSEUjL`d)`+Axrg z0N^2f(h<4RpSPrADYav%{^p(VAB=+)e>2-(acKZhRza3<#D@DTX9@uDSv(PWS`m4c z5xZfZ;e$eop#VPs07Hu55K|M7iWeV!r#@R_xA?!ZZlW3fUvY>H(I>3Ti(tc8pz&e< z_5-9Eei#ufU4H*DvLBu-Y7RmP?`qm+mNsgtY&kD+nsl{C?6-(|-rY3kk^Y@D))5Gl zlctTF3gO#L>&ntb{0E{b_ZUm1f5AD9>>H+G^gtl$5|5bF=xPWAQ)2ZwRjwQYN!NR* zev^B_Ilrj-dpYRdCrZP5c`R(MPy9C44S|$;_E*x-|I6~1@2`;|?G;83i8flIgP+*7 zB$LE2CScnax!GeuAP7toJs97!%#G)Rr%G^Cm8JQ|;81`tJb5s-s`P&@#$n_kcuoU! z1z7>I^hJd^QEY>Zl|z3od`HEVsQk#RUFc#AC0(j&cAPU>HpjfXsex4*IyNQMs z@v4Y_?MDW&y(lccX^hH?X5%orf;1;Y`oe$AN%qn;0HAbEG>$?1KlzMk6oX0y6Ox%G z**GWFB-CBaW)oetYrS>ng7t2^mm&Gq)krJRO#A=jf0_>Qax%zZ|ED2zJ$TMTynB@K z=>KUZq(cD*Y^lHFO{RiUZh~@nf>G&$LkUYz1zTd0Lwy`aPlek~h0AP`Q%{XcPhG=K zGto}B#&t2tZ1Ki>^?zkOxW7%r1OUER3cA?Wbg`Q}pDAU8E&J#JVb~XsjM$+4yvY+w zDHBU&6>H&b^VZEtV`6%N-5#QI5@%aPaDUv1R)01bopn}__qT9 z0J*;mdvKgc0h4N4l}TNVX98gM(@X{0K_3%m+ zeV#|YfP?&yvd3a@K*HDn;E$||NEaM$ zJVLh{qdLI5Lu4GmTaacl!b_VTKfp_q9*0Sn2YIC1O^Y9q*-49=kfDW)k2VnGCrZm< zDgmI=0Ba6J3UM3?*i;Hw5=z*5vse<-2^_;5oGS0s6|fbi->GZAQczE%Qean5z*bko zl2FG{S4&h-uQnUyu$zCUzWhpky2ecR+FLWxb(vjZ{^b!ub%i|Y)z~d3{a2Ox>^t>E zE(n!V#YIm=-Ao&z*-cM-R$X((8=`qyO<^8KT|H5Ke%eeu(bd33eOW_qepX$3#(Qxl z*kH!Hqwq(A{Xl8y&x+!Q3g(A~--q!slkzVWnif}4SJ14sQ**V`#gdrCQJ+qfP;-T7 z@iuTZo1YaQca>02FncL7!A$R?nPx3S#7^DKd(}lxFUeI;%Ut&+c+%BXFTre8(@guu zOs{vwb@fJmvPNNc+I3Rhb#=ydJH>AC79!@Vo)~NZ;hPO!_po2a%}`NyU5?i?fQaGR z8*neQ*bDr!Gg%a>_(g#%)l$Z&x5(AdqLA#myhkXu&K<%rS!D;&x9p;4kmR~-dDx)* zPF+vaZ2m@F^V%CyiS=vmRXp|C8;Hq6rW4bRZoKo3krLEvf+027O}5k1^4Z*bY+-Y8 z)rH8G54DsEG&;J32tj-vmIwf#576?RU`2NV|b~loE2qhv-6Z?<+6ijMCrC}g73VWjKU;-#Sq{45Jco);@CPnCx!Mqi!~ zZww*K>DbnHCp**Tb;ruuQsrss%JbIXIe&gBoaS%gdDW__HVMwE5LITVvh)yDva+m@ zT0vByipoM%smVfWWz0Y~ttD$+4pAk?I-{%_2_eYIvO-kZmv7IASTf~en$S}9yfP^* zsU{Gk`={{fS0*LRFNIU}#L7m$6dqj$~S{?CP&loyUr*b=2hRUusnk zqwRd$95@DPdAG7`R7tgtZWM3mzlBFsLsZ$6Uqc8GRdTYNHF!3kIj>W7enJQ~*5x~? z&L^xpb80r6wRkp=GISuSc4kZ<(GN5#WO|^E_lNjB)QjJP$z@q#vqi#KcXK)5S$ERn zBUpFIa#dM(h=NqvcFE#nRbL=g#Jt>CRh#U1RaNT}h~GoK_&p&9)hjrN+fo5Bh=8F3 z(crm&3Wxf<8)N^4_&5i|vxxsAmpOxa#6*Ouu04bh$%xXI+-u;49OkaGF7 zj`QhDFd4~uvlMs=2{7MB@$QlYowman0l>#VXh1w5n!T7Z9p^JF?n`Uo5dboDV@L<5 zLHrQXYzQ|IWO1gYQvHiV6@{lV{SPiLKI$JnguM9JfB7JB1lw*FL>7WmmHjIV{{rp* z7f1IJ+5V-{QT-Rn3qqHrec^-H7F`r_`Pa(-!NvX;r>goN9HguM<%?I9frOw$JdmM^ zCqjd-{>tb(0xpT)-|;I90N7m`YT@Z3L#!4>i;R6(L!QPU7<4n}Y&Tmpc>iUUwm({4ct z2X{*>bi=sduLUq4^P!8P2cUOt0Ep6U?FifgXCX98YvA-8Rk)W81pw)NGyv#@LB|*; zk__pAl?v^JlZHgYkkkjX!2xaLP~zeopK$wsq<=+Gbga1O1aR`9H|7>rB z|K0YyY;Ruh%|z6pEc9?>) zv<&x-PW1M)P6P@365q$)V55`1cn)2=?nL{|kL;8o*Mz8XKvGcUW<_N0RZ}HsdfbW_ zC29n3g66F|FT()yD#qt~UcqxCn)}J_q6L#V>rLIKl+CM-3tNX84Uc>W^J3^A**3rO zKtBFeiNmGuU#hVgZ#lcR1-AKj{#<(!k&Sb0+}pmT(qHi9HXCe&Gsu4pa?!v6XMLSF z>1l_J{Mxp3d#x@Y55lu&4ZPNH*tm%N7%DkSQM_>8i1-T>_3nv|+3X+-f37PK#(cap zjSHBt=%0Q2r5x=^@JHyVT(#k%W6PT^8KxR8NicBFi9+3%83%%O@V43TimPo|4x1GE zWp)Tlv}Z&;d`St*scwGc{FU0N=G(FLYZEJrh3I0sbMLsQykEU-^Sv@^@fV+)MM;)= zBo>~CWs{BjHbrq~b0aXHPo9Y%{fB0_LX8CXhOL{`ht|uir`)iNKA=KtU+%^oU)k0C z5sXA>(4J;rFfzS92w%L{w4e%EmKvXeAGa-Mjp1Eh1+B56XxA6d z@YF0#izB}4w%@OXZM-+w5dZNr`m_10m<`BBa#(VRzy%0bZqJvTcjZzrzb1*mM~u&S zz+8-ZBsQ3!_s%%?t-qVio3>vihAV)@$u+s2z}`%|6nD(#gMGyo>W8oMu146~7Zxdtd28rh5N2V@gS7pp9`DZr zLq+Ya7qE72aK9}YX6UPKP|ata4lY>dzh=lFx~9SWmJ?W;4&sK3a~#l#JpcLqZS)=& z8^KO{&8ky{1D0e^O(i~S1ge?feC%uEVf8Zd75{V|lVmAPM4KO+gUp-a>{e1qg_sgL zp{Sb8QyJmcnv?h+TsX6)^Ytaz@*=Ako!7WIHsH?1`o!~6#BDoPY<;V9m4D%h70)$2 z5gGeR6Vrv8$?8SEMR>|v2E&Mc&H}Vn$=kl}UI|3N*fes^v&&^W1we6fud*y(JKH@k zyY`@0R62Vq-PuYvB*tC2m)KF=AU_i^?YS>qyq|0=tQv2#(5vv%D)3Iee4||Jwb*JnpTT@iZrOq(v99Pv~(8o|K_@!(L6l zG53Md=OvwMAKq4tH=0)AMqbq_sH;Y%&SsInxCl44yq&*oGt7hMd{RQAIMF@6{v1t_ zrXB&cxGg8cSZWB1fNc3c%r%8;z)~s5;M1@cBCsA9xOq4a3#HwV+7GwBS+dm(Px`J( zJqYWorA;qePhLl!yJf+Ndp+Mj+scd4rmj*`=PRxyrgNrUhKpTy-{ zKVubW0+v=LJ%L`wIKvgmNiqdfhbNoW@)OERd zH@R3-HsA=yH|)Bo#aMO-5Lflzo}lsTI!80bmDT7^Yl@b9731#VBJAlWwBm>$AFP@f zS#9*TBr?bO9a$PLqlph585_v|O`sF!G{u$^Yls`y)c3Tr%n}sC2$YS=>mTA39x6(I z9jmYinM#`TC-@nu)tcVflkzBVqPpCaj?H-De6#Q;za*hN=c;Y#5_!JVc>z4&=E6d` z&RFp%N7g6vo%Q3-;s`(ZY;t4Rx%_fzA0mWwZEot7jx-|X*|$Y88ApiYo+ve#Aig6g=CrwHE^n!k7Orlrn} z>iZ@IT~q)?J6O=JIa^^zpJ8oFZ=DleKVCOL)(8RCm#$JrR7NyBZ zfs@ZBfWBo7f(U?(E;MJp<*2}w_SQRB=4}-*p|V<0jhmVkpUyBly;Dwnqj{yao84wL zm*xj!%PLUN;dia)IG!~AcnX$w69Q%zn`o7Jye~$-k#gR)^x!GlNDS0YuK76Vr1*|; zed;wmhGJoawQSOM_!Rm&nLj5nxDl3@Rx{1Rgp8(^NrZQ|;pl7<nx7;`{JA7ftV)U~a0wb`6C@AJNNvqZ0NdV?in0-l|17fhyX5hEQU`_~ zC)-o{#fbbmvEvV|2Nr<*M8-A?9DV5CD=)+|WY+iSy`uaKQSX~bDdMnA*8>!wnwMK3*uq>M<|>2{*@Wu^bUYp(O(~9hQZD zcdiuU!BnLn*1lIH0}bp=1wg4gqb!b|Om^ZiFqFq%wLBBt(#PXoatDw}_kQ?ciY<$j zVnrF9o{tqo7>76xcPp0f^A^6sI~qMDGoP(3&4z%s+zWk4spEKC!Wz{3s~Qe@OKC(n zip77}=L6Xv@u8t5KhgBjfa;pzDnI`+RBU%~KR8N50+itQ$oR7u^}cU^C+>QGTA6Hb zfVQt6Yjlk5cMve5g(^aS-}afZ>YAF-ROVc_P$^{{O2}#i3SkW>J3dO`;`&B(B?3KEQK$ijR%Q(pY;+bZ~eA?sS1q-om(jKXEsdJCm+ ze&s&@oM%Nw^F=~5Rzos^0 zRF;0%kH15ijAJ$>O%lxgNoHxC735H_KtkFhP@pUzYDYt8}B_O7m?;ONR_ja*#jKR0xZv0i8uO_phIy-wFPV zwc$ zF%2~%=BsU0FRW+t>7|0zw`|dWz_;eN0DP@j%K3#^vwA_$srr-lrOpWgw&L%+srcyT z<)X+)!EwZ@4sWQ!O1M0jD*^BC-%?PxH+=$ZDyDYm!;7QDY1PxoD?zCaO-Q%D zT~01t;Y6h`j^DJzy-N7FD|epGFw7tJhyS%$6^&EdB_SrlI*KjTH`?o6?8cp8+v(sp z!`B@(;JE!N$1i|>*h&~xd#6Z8*q@R7xnkU9S$}kdiX>LH+^T%AvdK2*GcVi3hgfId z1GdAmpJMXzO?cREuN?8=`NH=;ydmtn$u$e*&K_$ac)d)bh#F&*%S!OwB{ zyCZqoOy_sHRX<40=pOp@cjjBMZI_xMih4Yu+1SZnp=AuyzO?WmSrcB=q@Fq$VY~pFE!vgpyjk=fL@7 zTB{hSD?|3xRfXTGS$`Mxs$Vg->@xv*{m$$H9JLZx8uf!d2;U~#nuYyBk%lgw2)-g# z4#A*gQzW;0g~b%|xqyocd5F9T306z~b8>A_PUXYf5FU=n>*Uk(81vZOUjJr9ViSD) zPrSdi>ABprWDzr8C+GP(3jP*=d0S~GPfcI|&)$S$XWSW}!f%4WzQ5Gb481Zp!Uj#7 z<;P<1>-WHHN`18Po-~wJ8Z=bQJUgKb>Qo&g=QsS7kd(vAmC%_FE7d3hHXos@1(n3I z2hiOR5rTZu;QYvE#ohN)$d-1F2cGtvW5)CyYFntlu0PV=RLw(n3_ysCPyDHQ5)GUA1c0nn%>-Ejn&N-##cYo;zjPiJKr7?X! zKD+mBOM7k7!CYgRPhsVYjr)d8EBSt-vY|~S^$&nsJ{=(P$CUJtQPkjMj$yS4&_+;o-(Gr*}5jVf=XWPoS+$tw& zWbda;Td%Np=9G8aLS3wO^$Nyh>14N1W)z_og}es|w;5Eqy(5B~gDwU>ugFcp`HSXe zQJ06;H{?&sZr}MDC7yj<@P_(R`th4Fn`K&Z(AhZoWw8QqCw1ZMXa`0iJkWwk;Gx&x&6tCqPrucdfOjr|5_~u_-+7GEu|o zLBfEPXU+r|OLkqH(};Y7{Joloe$>oyBp}(MFR}s41tIFW=y{ zy7aL2_}t)<%3P*(YdY(T(|s6r0|-|Vz}`ry$ODES;e$p?Uo%Uw$C*~VWl3=co(i$* z8?mY5n9EI0&)9oobf-(Yf3U8|)V=;4YZvoNG$gNI2@G5QldaA*j8b_Jz>|P(uU~n+ zM2g7m$bZC!GeC|apYjQ4OYL&_)#^4UnzTrtC?|v5St2*-C48t-6|vUY>oPfCTp<(S zCaSB*qa#^QiA4~@CIIzRR0D!`0JMBbWo8MNY3~zZ7U#Gm)h6bmDbBqz- z_A{oSGTzcpede8sAjoH72OruN)aGMfCiu#Q#5r~mX6{&9HXny?(Vw94NyF3Wx8;U& zZ+gUS%1w*^jNvST3$7ZnAhIU-hxtM)Nxm7v047eU<#59D&GnWFV?va#?ouQo=u zbk)L&Hj7!_c6!V6Jm6mo-VHf@bN!-pL;=%ct^@n6oEr^xepB@PO@3`|e9J9HW0T>k zJo4L8Xw&qk{t;!6r6G=Atw}tQe`@pvOQn~QCngN%?w>JEX1iUEThiy#=Whd72ie@N z)$!HdAN}wMvXQ265wQrd^B|ujh+>v@om$4pWKPc=@7_ygE$$f(-rIMZCEDlduHgtT zn-h#V3v)b48CrRCXwVc47lbHZU?A)`5*yFAk)st^M!YwD6krE&TxQb?v}P4vv^{Xx z)a6PT%*Yoe70J;C$zc^O+NYdE${peupZv1C@)xu|zQ){ zYXGp6S;oKze{#P5=2aA16jR0tW0`bD*d?nRR;uMT29A>t%s_L=iI=*S;GNk>IB&@?yHAXOB3+rLxJ z_ktD3-T*`K=^DEFW4PBK$|WQex}3b0Znc0K%Vb7yG7z0C(uKaq6Lu!fwWaw8RbD?2 z7s^_z_|~0VE-!p* zn>0)gO^Qw-853r^Pcre;Mz{X3yz|6Zvfp6vY_^8c-k_jV3XqsV6sf`nX*?M>y;np} zBwE(08KxR}#1Z;XQ?Ty6$U&S&Sj&y!+(4Wev$SdK`Yk>Lfek|xWHd^hHTo@$m1*v0 z`;grUhO+fgok-}>cTh>8MMR+K=?wrfq3yE9zrB4MazuPSc9ERIk7~|i%kR(qwokak zGgjhID4`ZPP_gYXRM|7S-_+rVGxga? z-d4}6GOqtv9JW;T-U*TzuV9slHOK2bH8FO-Z$TIZKw$uA&G(i6r$sp@Q$@f?B#N>7 zJ2M|atT8dKtWz9`Y_sW-hs-d>12dD`J-dFe!4+I4_K;3An3})swlaY&mvqBO%#41C z@LtK(BYlz;^_#d6&8ZD;|ADEnHOkkSsgGE6n+J9x{TB03Tl09fN*|!Uz*rH0&wIaz;O5G=d4_rR>`r=T^t{xDBM6U~%+Kxt z9}Cr97tZ}SaU?lLb5u?GG;1_)_OzhP4)$rN;RqDrlWu#YD0fYpNEASsk_lMxIvKyo zv5VVSjMX2hDQv3OnY>ZDusye!lKSQF!G9)=0RH-cA-#TUYR>?_m>T@2GaF?psr-nY z_MMI9F}CGvrTf#V34ClA(&;pe$;s~rUl0}%xt5J=({_XV4A1w^G zYVvoqv4u(E=d)FZ-J4O+WcNq_Wju_S=Xa+)d-0^Y8xzpGH)7A6CD&JA5q1yRtC(r_ zA{>vF4vRl<><^!gN@3gXV9a}J!6C##1hoLn9+^q-jT46#mKvs`D>omm*7sUJm_0#c zy?ANX{wa*68Et#7A6Aomv!>0VR3STN#2@ukvPNp3ptnvG_cbc|qL%&HyiRze?6#ru z|JVUa&3anatQ-zFA3)!mPw-ki$6&(plfVX4-NHJr%_ZUaqmyHRJYzmSDbZwb5Y0nGaEly25NwK@(+BvzP7daFz=%}<`Lb{P+fOl$B(~b z;c2A^$aFgKTWtnSHF8rXr@AXQVLS!wb{yF0E$u@^y8`AQBxHl$poA_@l>5lc-WU~9jlhMdBC+j0*$%5_WG*hY z=j#MEq&TY5i(m~gl6E_o_O9nwMXn1OF}WJ7J9FSc$rwDr!mpbWT@K|Sur0Hiu5kBr zs6;H6^Y`W@KlMp*N~&$~A-@S|M2h!Gd*G&fe3bU&Y9IPKs=z>K+X61cjSQ`Wj2dsVly0ruERtYERVmmF2Em|PJcUts8q#;;&4Y_ z*DRbGrT2j8zu+>K0sDYb=jKX-#v1#laN@xZw>jqZnUivs4`>Cywmj%P036->S4oXE zb`B0v@`rF0%J9}QXIFD7#X8z&Sh}GsK7@9T2)Oz-F;+VIG8s;%(<(n8GT~YDJd-zf zZJ;gnGSk4LZ7@tpnTK@zsv+OB77j|Ba`i3S2lg`&wN`l)QnS~JToXxTld$`4@rgL+ z-Yn`-DzkJ1M#CYG4yAm#c8dLGS6t$)1Y&>zCb69o9BBsHGRK@+$KTT}Bz{)HiArdN z!MEq_IyFjs?~r51i;o;%s~#6Jjz%r5zkuow`961>=0cIVn5q}voUTM4Ki`!g6J5t4n+4|3_xzw@w(P%z z;qdgZ!^3YOK=T6}(96u9t4&)I-YnX>jRx4GxP1luR4hIg(IWmZ>?(h4QyTIoLtLhr zX4M`lx3a=APfp@Z-X)_hG_LAwY%=WmnWdl`&0!ZIAifIiI#7pEr#C_)Yz8|l)CPjt&!BYnJKXc7Mz*n3cqO^8vZ@2ylU0nF*I$bT zLHw>YzAG$41D49lOxU2vC@ z1V=^#Lb{qo04?DDMbQl}QScIjkr;*5^FFWqJDiHWFtk&-c#;%5px2U z-McOuC$}#>q%>`|N#Hp7j%(gfE1>eVjx^PGgFh}u!qe%S|z z0*7?AUQLVJXn3Y`o+%)O(rBWK1>T4|3}`MGW#7!t`&MEZ1gP=SWGozz;z0B!9fR-!CKxH*h|T^oSA3-?~Z zZ#(?fx5%O_VAp6fn*y~P+0A4?U! zS!cVD#g4;|h}?fa&n+20;7jH=0rxkCmpW?*0DZ|$4i;*C%A^{8yRA`3m%SVLW(`x~~i>kxe7b^sDt%`O??xoqy6??+O<8e4$LV~oJl15xg2#u zUw)(8JgetE7vr?H$hG6sK+O+Q^L#KQ1Ufd(sgw#IPyJ-#$@Ngq3y^z2R$Uw2{fwHC z6|UYrUlbPllDv3=kVH?9f_G3QY1srB2r7DxC};|CCnxl}bP}3-uJ7DzpJlo=5q<<` z%}nVL;83UVKA6(RTGErvPj98xKGcH}SAYE!Jx&8Z?bkr2U*L9TnJB$IV&2k?N}9q; zM#^C*9y?sqSL%dL>g^1%LLPgHh?KEzUpvvZUiMl2w#PN)rV~Nl&9}a!{T6w+YH9>> zPW<&yb@nPQCN)|EEVf8@@-0Z1GQQ|ODOP)&#Rx*HUkbw7z`_$SXHOX*pk|}#vI`BU zJf1SUFCgB=>5qC9PJecnvFB&UW_~$4(_u@F)7VJ&PTBM0+vd{__FbXGG><)nMH1Js}A-XbaASg$n#2KBe{?fbI5TNP^nk-M(aj% zZ&0l?^EtP>+Gmc9<%p(3OXTN%6?9*gKKWSWK?`ilGg~kM`-Sei4Y%Yn!v}2T_w4@H zKgyAmnR~hT{4y(s`A3aKD~K4^VP0u65g}wR>U{5p@=VR53A!hz*ZmOO=UA~UU!KmI z9+xec6LID|{tYMCK74!Vf#TouEARgviUD5EuRufk=cibp8RN+4EHa8|zsgvg0>F8V??uAB@JW4^c%ivWmV~<9D<YF1Lzm!y*Tt1Y zjppf9-B!(?t;pq!*#w;vBY?qhv5#}@l;*LuB63g1dwb~5De=m*FR!ZJ#%qQdiNs)D`P%9@!T-3l_^L95))wHZt-n=r-v)Sywgeipj#+ZxhrFwl(O=yT=yOhvP3~4)CGcXXq9WD~rvB%}g22C3#O4wq%JdUmK2R%KK3TNE}pD9?H!xnm7r^=(@kcYOsCqGp{ z11~;Vd;NQZ>QR)|Q%LlTmsJMM z$dTp+aV5aXe$%mH;>Ft7o2?r2v2!AF3NAzTVt~1oKcb?2V>EGe6cC)e@Ils!xMRc4 z!;q*3lNOEWf)DnCuNsSkT`j4R`_pfra1$6UmXf9V?a>3X)dIbCI4OdT6NY~7Q%UCA z=)LSmCxIaMI4|lDnGZEIAaD5l+t;iNih#Xvs#`P#4!kt#O+3}SjPl2(pTF77JBDi? zDprp0s6T|%vQ_lL^fBLN{)v(vvh}SMoSdU3!lbVP``p*~gR#c|AC4n|*)sj%vG1RS z55MESVG3`TVXf9Ak|EvyTwV1x9je#ri34Z#xy9A+?)DaDjmx=e@tPcJJVJbAQKTf} zTXEai6|eX4nv(=(n%6Pjls9z4{ar=>F8fE#H>~;ozYOf!`>5Q&v#pc1k43ccLLEp? zu+$}Prq%{h0z+P+16b)B4b4^DUj_Nthc3O(-w4@K@`{vdGCoft#6;lL+Dc8#m{um4 z;{IA}EIM&0fI_{HVp$4cmA4CK(B=a@;nxC?>BF5Q(EWH9IjT9l=eXRkx3Cwl+7w~x z(*>QI4(Uo&D!0e>2ko8IvtLZEZuw)Ec6zW2?XL` zQxVeED{GjZ5mG6Jc%)6?`EgqC(f)1}7Ww9c_>#;qHTcN*D=qRBFbGto4VsnaDS~8I zJ~0VhFHrspAFWT5Y&*0CiO~N+Z7V>OSELT-TuSMny8=1wT0ZZYx>2~^x25fFt95kp z^@()8m!`v_MuwsDtK&A1$$iTabC&eE^KjOkbe9(hQNmp68YX}_xP5%4={kYdCY z$e`Es2a2KEE;Ha?E6L2E#1DWvgPy6G=TT1#g`*6*;}rvd?Z$>J*dl& zfu&;o#Z(Bcg#)Ng`H|IAQzY}jxyjYNB%mX~Kwsp@IUm_QR4cW%-d2P~e_ ze$Rm%enUD!;Xu4~OVzK4Q^{tpo_SlbRe7bJYvLao@-Y(Y<;Nv|%4S%4pcQECD>zb@ zU1*mzS9i_?{MnpyBQz|B97(v&R5!FP)FDU6jB`*K$rF}r^@3^Zq}YfWqaKP)-n*8E z7f@|M-n*Wc*81(70P}8fEN(BGAn~(T&DFK<0(Q1GOwLqA8(z&)K~^W?Yt#~MovMM> z?x|ol%lP0wViz_D*ZM4+VvfjYG$Ir^ch$pv;0Jr}6-=?ZGQ0|4g^vavnGMGd<~Adm z#~9{%Tgb2xmj@lBewe2rS#-$2=O&@VrOn1*{qNyWtL{$@mGredln{e^(v;N01oN@iqK*W!rZd zs-qlBxsdsL)zD_<=k}@DTo+2*%Pd=_@9>;w^?O8M3HjrW2s!-+*vrn3 zs4{8{cecZV8MG|Ed#uPB4qf;l_!1X{G%ad^lIesMo8nm9e>iBhmYo<-`WnDXP#je zUC#XSyIl;K@`bnVC*+JmtNonS*LvG$cjlU(Ccf0NLsk>4Ah7lfnP#RA6PbYTBfGRp z=J;|JfP8)LsSY21ldXC+!PE6|WKs7(Ys5ZSa~p1q!4dH^Gz`x5ZBqDhf_PfPcf zw(QiGq_w&UcBw1ZBNV#?*2h)NNVn|EX162Rds4KRKTA`~r|)UKoQ`&>s0r4Q@1P!1 zkRPkc^d)|lK`TEJ%f8A$Kzmt3=H8U?Ns4$+dFQUOi^*h}lj?Jmv>q8KY9Buz@L44K z9+>l7`q=Cs6tft{rOAC1x2+M#ux<%XM(X?#jaW%71RMqaPWxmp8Gr&E3LJLLMGnXveg@v!NVHIS?nDM>o{Xn*En*XP)fNL?W$xSx{j4M^t}S99+N|v?WcldjQtA7OrXRkJatqJMlCVZ(c($}yu6nceE?IT=RN4cZ_iCNFPx`4WF==85GwZ(Solu$b<-!Wz zJY0~2*0x0>&AZZRlx;`&Xx(OZ-U~3Fml-v_iZNY`N3#-jUHi4A;YJf(d&>w%%J{|P zXJkg79ovAACt|#2aWDfKckd~IYCh-8`zflJ7N#Wu{c{1-BA=${fn$cqJLRoinvQ{n zcP$OA4VHcAWfS%kQQPpE7Lq)}^6pm0YhT=B(YkbCpMJ_o836hRsQ!@fckVgOaH9|- zsR?QaCQ3hbWv+%6MxDr*+VztfJGnvJPTpyho-G33eQbvsQc`|gb%)iR~3O2Xy_q1fRkq9ZXj6U&8?>)IzqEzb3R;R0=0wvQES z!VyhH{^AKGSs3<(9hLOOu=jcIbZNX3*3vCK2RT#7wPH`+b$`gNI#k{^pF-f~pKbO4 zJ)*$+vrYxgoiJ%l*M$jx0I6BoikeaH<#vd-SpaGIP>lsUd~H}h_Zt2$+u@We{zRTG z0cBEtf*f28b9{yT@A4wi2KRZQ=@vi8D-I8^yE{e0_u$A?(_gbGeUBz0JvCLlH>SvH zRSq}WL#papacq5OEo1YL!?@~$N#@f6h39KbOlp{}^-B1s52<;=qJ6x6bv33kNjk?` z3Dy7@#7#N1MdLwRti1EI&gmEQMk4-hx}#$Qr!EdF%1n`;$D*`hT9k#iqykx2i+ZQ? zGBds&QD>qdsC0Bw`54?-xl(BPiReteJnX@s>!%+*WHyHU{{{sh?KRBcX5S}CCuFkR zW0l-9Qz+WYw&p$SIMC={QNV01_^iIv*QX|B?cf zvQ1Quj0gSTEfm|la__M=n2&ObiHr?z`%X5Yc`gEsZ}l+lJ?zo_ph^Yil@S%e9%{61 z-TCcl-Re5BS&RBNF z-8I4;gQB8PeV`;X@tpl0n0rU-FC;Apy8yIN)_XwUU|TgP_W>-8G=pdKnZ(5jbqd+$ zZ2ZEKd;os1c4fxVpoGSobR{3#g(6H29RbS2u!JTFlNW#YYF>9SXkK%Y2GoMva5PW9 z@gyM`GqK8lyh(*Ds7@`gCI{uygyJAAtiobl&+6X5?%XH#<4k%N%K+D|-R*U)Su){I zAaO9e0P@wQ5+31cqwaFm@_P-Rb$AX&$LG8>!6yZgY*PZex{nwqd0+OJk6}NdiA<|R zdl~Vfq9ptLu&X;-yt*30CfP?t0O7NMPTAVUO${}4jX`cvLY~Rw(Ij;CPK5{8ER(Nv zkG#bDJoB&d>+NbTs?g60(Jy3oiIwYDBBTk}j6{8Tll+sGkXKRg6Q!{V_hu@?>o!NdTgfWZGO3V1aZl9WpX>_YmDqs>x z=1?vojRHTiGEVL_x@WVrBIaYnTV1bOq!eZ8+LHQ*uat9hbvmLG`C`JE70*?jz8%`0Vim5U>OsG&gJHK5lClOfoH6zo=81hO@^Ze7`{})6RyXxty1k?QA zNSsnOF-(U7re~2C3vKHasNEV|6&Q}fv?$<~0LD;Q`9LI}kC?c_bZ?0y7|Ulrl1O&I#1S;O*@Gh|zp$GnLI7kmpnAF?kDFTb`2@Y!>`0B*rPp#4Lgmy6$E7)iH> z0w0w!XUL)U2si#t5IzITqeO>-QwpL-2IdIhQz$DHUe|n+M$3`p$sWem`vIC)8Huuf zRPE_&FtGukY|7?U48FO}0STZ0upgZv<0uW<$oW7Woghp0(Tv8H1Zr%FuHle1xuD&b zzEa^&)75AhX)}b)n^Vbw;jJeWR}H{tHB8Jfnu=s~ydADjv<;4Y9~qgg1@!K4?%Db- zz$icQ1nx@ElSIlxg&9SiFjbEdlvMn9K%p8+H~+bWyc!iUh|s7&_ElRzt~>!yCnEsY zmMJj9VifD$@J0uFzsVkv)VUAQ$(tx|PSLt)EjEs{r5DQ*ARe}lQzD_}l|LVH{t`}Ymh|oOzfEF~M4#Pd z8XFsL&FUFnZ3edZw5~VkS7La`6y#v}?PHtig)-e~5{h2dR z`ruMMDIfT`7C^3o$jWW zJQmFK7JGs?EqGKOWJv709!*HIooYmFW1tgZ!OZm&S+2FP?gUmWW+q=*a6T6Jy0w2; z1||W1L`x&=c@5@3BG+$AN0*3Cu-_an@`88+E+g+)6=0e*^ae6Ly-o0|UiID9y#l@% z&jSqz2L%h$=dWGurT{U<1eOJ4>7#hQY#CC-xUAJ)^%mZ(Y?6Ki#Lu;sr1oc=9R0Uv znT6-@#0p~^m1O{|`*V;aFaGEbfd&8s zfVZSyij#mgC#=p5D|3wOV+cA3YR+>2{mvS7%=gKp45HY7Ep1`1vUP_9VA5{Ch!>`6ha zDo~Of=5=p$V2G`g_Ha)0o}+e6|mDp7rzg#Esr2DWMtAb10g596GcgA1mtSXM`8TLzw)&H@3r1HgVUryk-&vh|Yz zEdc3f2}6%E6(~Owxc=IC8XIR0XL?Y6+CB#{q%T$49rXlu(?0-AeN{);lyYA*Q)Iklu(rap)z}HfFh4pus zkFDe|d-&i?ynCEJyPXpdmD7{x7eyO&CM2o|N>ZzDKYP2LgyxXGNNymxFT znH)N_W`yn@+o2Q#o|(=70T2N2J`Z|NMAP$p^ulInuxFqK2ur#qln4Tq9P4uZPmdO) zZC}$kL}yH-hPctbcnON#PXWz#0O=Z8K(Z}Ssdi}Kq0J;6CHd_U=FYCa1F$Q>9)1ljcpuu9*LxWj|B>i}2 zgCFCCfm%gl8Z-@<{Mr+s#D2`|HDa<)da2qrXIRq9?CCLNfy(+>Z{{tl^T5N!iq722z&t-cv;A-qmIez5%dtY8 zU!QjxeaedjCvRk?DX;mJ4~85D%_Nu0k29oy-5M*$GqP|IZDl)M6~knLmT>EK90KWg z3A)ZCRwq7PFvWI;p=FeX!I?>!h*)^|EV@G(U;YD%BqPn}S4q58 zzzV)^(ljYobSytXg=z!Vfj=hCB|Ej(0=^ixfB*;pn4YIN`sL^uJ+{$DZy@Qr0f6qK zC#6)BG=KoUEc7G|$(`c8u6@S%nUqZ$tnCyRXn0!$w%$z;qDQJjZ4EiVim`DH4e0|R zzcM@J@UJxnW+@Z=LOW_PYiS1ONc0A1Qav`y+#$5YTlkfzg}nO&BsE1T{n% z)0>WG(Iw6iHu|isPerQP_6(Edhudud@r}YxX8fayV4t-K^yNGxDc>&LWM&$Op{@=S zhVUty*|Q7f8>e3wqVRfMg5W*E%|c@91Jxx_w||eWIE?qkQuY-O9)%UL9&p#b1myNH zdTMn+;ZbY^6v^N=rTlIyOdsmu;~|3V2Q#O$YY&-Dmfj-kiOJ9zG0tHbc=`}j78`IQ zCd2i~iX6%+L^X%Mx}j$%-U!YC3IG7GzZydg`h4!;2-6QmZ3oIFNfz4h)Sj`%4Uccc z$iDeHc<8}6^Y7=EQxUoSyI)PP?@2^g>Uyx{8GCqWnMAPpKpBn@(s>FYwgL~um`5YqR!$IWzo#NN9L}MS(x{v+ky26iVpr_cpCqQLzOYm6|N*b?NKYZH!Mdgq`UsMKxfa>)pws0x@p zMQf+2((nRF(qkBso#gc9G`{Q{iL}L1k|TNh2clSM?Mfge7^Rn{*wjS_s>BRse5;Wm%d5cq26i-+CDx)=eUvjkga$rw zsu<#Pb{npI9uK}4H)UT=_W}3gHEl4d0dl=>NtmnkVjy))3cvcb1+My+)FQ^ySRENl1eaT?)dTuL6|hsIg#5YzH?d7l)Sdhe%{(?j%jz z_Y0McLT&^mk@xW_CA??r?z>SkBC??_y5GID?dT*>jv;ur_Kuf^G`-FKc6PbNZu*gc{htkQ0y)S{C{~tHO79P9b)ny_c7y_?jeU~_G57xf6tWEl=X5BU;8_hHAJy&kw$6& zHcpy=SvcL}XHx(K8hZf%00000sk6uY1ONa4JB{+o2*<^|#>mFKwEkDNfdBvi_#}1? z^9}Un9^C*&8Kd_on<1z%`FzV?Yj|QKi^OAUeIv)X_R_wmm(XS7^g0+=stOtZ?3>WB zx|0Rw-LUmxd^9u^|4_mKqG8Yt>DfLPknyGgaBhP!*|Nn<=E-#$Q09Tq?4@VRO!^Te z;P=1@Ypr#hR2B})7f}Xs`o{&>rgqWNIui%e5_Y^cvF|4Z{F&{h(Y}kIowP|_ltjvuH-!X+9lgbfiVBrU38zs?Kb_RBiUe+2?**uL3wx?mqBhug5t zO7KaGP+Ud=AH54R#SVnOCua=bA!7llLTGL4^8-Mo77MZNfLKQQG;i6p2P6(ad*$=z zoHt5KdjB=dJ~u-$n4=0d;!in{9UiE*p#dTo0QRE}8&`ckLn{hF?*Rz2Wbq}50IK7( zI&*1XO6C1#$z}PvE&|oF`bC2O9G{N6_pfj*Iq8Exi=aC|eF-Ci4NQ>#P}Kphe*?R& z8%!=DIiyN@jIK_x;$cccuHojLb+PJFECZ_?-)Iy;eSB5{%8>+&j-gN4v%?hT^uSE- zqkUT1RUyx>0=ekDJS4a#ky)`)+qETYSo}}gay58E=7kaxt)$(RiH*wT0o04{A z3!ZpYAO<51jSAf71|1nku(ETZ4~f-#DW#Jm3X= zzB>)H6?UHM91RWVo;fmfLCTaAFHEVp`}J#gPSX25NPGLAf!F%WW#`=cmKEs1yh=@+ zhzX3o6(Ao5SVR_`4Dky=@bGvfmwTPX>VM#y*nK_ZeE~% zQ2PKuW=;oJc&tpOm)Ec?OH;XyewMx+`eR|XP9}>g#$m#%T*I>z^oneI< zAUMoffbT(lS1BNXx@;3NHDGbrhJ0iy_kLvK$g~kGF|a^#UWUiZmOgPh-TEPJC-Ti- zEhjad?^~!-uz^0K-E=?5cw-=`#}(@Q1YY*b0s@dZNEo>88#D2o#0Gg{Phee%*3HP$ zZ6~BmiulB0LrhmIQKAzX7;oX{LUs)XmsS0meX-DQ z6kI>g&X)MW2uV+Nl3@Fqww>geh249BS;L=d$Wgko<0TYAa^IEv0sfQ#$v7}!Fc+E* zlXF^z^Z}k#1YR&9Kmz_VlAY%{>}(hV=1w4cW{h$|fs!q=kw}bb3@k62va-*8mpj@w z#17?4wyt^D`WB&U$P%yWa9js>=x~1fj#WQiZ3j&y)LBhJCHy5L0D$G2vz_R&ekS52 zUf92*HSiZzRULgP1I?QK;Bk^a=4D%D*8~zO=<_ivk6=!Ihh=zXg@h$Dcjgt6;i)C> h4`K2McpR9QL5nl^8qUny2P`YJWOhr2WY`}9-T{bf#x(!{ literal 0 HcmV?d00001 diff --git a/Resources/Audio/Effects/guardian_warn.ogg b/Resources/Audio/Effects/guardian_warn.ogg new file mode 100644 index 0000000000000000000000000000000000000000..617563b6449b8a04e0eaa8a2b8adad98094fe3e7 GIT binary patch literal 30782 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Voice/Human/malescream_guardian.ogg b/Resources/Audio/Voice/Human/malescream_guardian.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a854335da78a4b0a5aa9bc8c5f03b56f7dec2dbf GIT binary patch literal 18748 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 literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/guardian/guardian.ftl b/Resources/Locale/en-US/guardian/guardian.ftl new file mode 100644 index 0000000000..7aca501bd2 --- /dev/null +++ b/Resources/Locale/en-US/guardian/guardian.ftl @@ -0,0 +1,22 @@ + +## Guardian host specific + +guardian-created = You feel... Haunted. +guardian-missing-invalid-action = There is no guardian under your control! +guardian-already-present-invalid-creation = You are NOT re-living that haunting experience! +guardian-no-actions-invalid-creation = You don't have the ability to host a guardian! +guardian-activator-empty-invalid-creation = The injector is spent. +guardian-activator-empty-examine = [color=#ba1919]The injector is spent.[/color] +guardian-no-soul = Your guardian has no soul. +guardian-available = Your guardian now has a soul. + +## Guardian entity specific + +guardian-entity-recall = The guardian vanishes into thin air! +guardian-entity-taking-damage = Your guardian is taking damage! + +## Health warnings +guardian-host-critical-warn = YOUR HOST IS WOUNDED! +guardian-host-death-warn = YOUR FORM SUCCUMBS TO NONEXISTENCE! +guardian-death-warn = YOUR BODY IS PIERCED BY SUBATOMIC PAIN AS IT DISINTEGRATES! + diff --git a/Resources/Prototypes/Actions/guardian_actions.yml b/Resources/Prototypes/Actions/guardian_actions.yml new file mode 100644 index 0000000000..1725cf62b8 --- /dev/null +++ b/Resources/Prototypes/Actions/guardian_actions.yml @@ -0,0 +1,12 @@ +#This is the action the host gets to control the guardian +- type: action + actionType: ManifestGuardian + icon: Interface/Actions/manifest.png + name: "Toggle guardian manifestation" + description: "Either manifests the guardian or recalls it back into your body" + filters: + - guardian + behaviorType: Instant + behavior: !type:ToggleGuardianAction + cooldown: 2 + diff --git a/Resources/Prototypes/Catalog/Fills/Paper/manuals.yml b/Resources/Prototypes/Catalog/Fills/Paper/manuals.yml index d0ed9631a2..4978d16bb0 100644 --- a/Resources/Prototypes/Catalog/Fills/Paper/manuals.yml +++ b/Resources/Prototypes/Catalog/Fills/Paper/manuals.yml @@ -16,3 +16,32 @@ Higher will burn the engine out and eventually make it explode. Don't. Don't forget to refuel it, it tends to stop at the worst possible time. +- type: entity + parent: BaseItem + id: HoloparasiteInfo + name: "Holoparasite terms and conditions" + description: A tiny volumetric display for documents, makes one wonder if Cybersun's legal budget is way too high. + components: + - type: Sprite + netsync: false + sprite: Objects/Misc/guardian_info.rsi + state: guardian_info + - type: UserInterface + interfaces: + - key: enum.PaperUiKey.Key + type: PaperBoundUserInterface + - type: Paper + content: | + Thanks for choosing our holoparasite package! + At cybersun, we pride ourselves on cutting-edge military and industrial technology, and greatly appreciate your contribution to our establishment! + Guardians are helpful and intelligent beings which nest within your body, completely immune to common hazards such as pressure, temperature and even bullets! + You have purchased the holoparasite package, which contains a holoparasite activator, an instruction booklet, and our softcap merchandise. + Instructions for use: + 1. Activate the holoparasite injector (preferably in a secluded area). + 2. Wait for the tingling and/or painful metaphysical sensation. + 3. Check your holoparasite for the ability to communicate and cooperate, and capacity to understand your orders. + 4. Use your recall-manifest ability to summon or recall the holoparasite back into your body. + 5. Keep the holoparasite within a short distance from yourself, otherwise it will be recalled by force! + WARNING: Guardians are metaphysical beings, but draw from your HEALTH in order to exist. Direct damage done to guardians will be partially transferred to you! + Cybersun inc. is not responsible for complete annihilation following the misuse of Holoparasite technology. + diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 776635b834..56c4b6281e 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -107,6 +107,18 @@ price: 2 icon: /Textures/Objects/Weapons/Guns/Ammunition/SpeedLoaders/Magnum/magnum_sl.rsi/icon.png +#Utility + +- type: uplinkListing + id: UplinkHoloparaKit + category: Utility + itemId: BoxHoloparasite + listingName: Holoparasite Kit + description: The pride and joy of Cybersun. Contains an injector that hosts a sentient metaphysical guardian made of hard light which resides in the user's body when not active. The guardian can punch rapidly and is immune to hazardous environments and bullets, but shares any damage it takes with the user. + icon: /Textures/Objects/Misc/guardian_info.rsi/icon.png + price: 16 + + # Bundles - type: uplinkListing @@ -209,6 +221,8 @@ id: UplinkDecoyDisk category: Misc itemId: NukeDiskFake + listingName: Decoy nuclear disk + description: A piece of plastic with a lenticular printing, made to look like a nuclear auth disk. price: 1 - type: uplinkListing @@ -235,16 +249,14 @@ itemId: lanternextrabright price: 2 -# Pointless - - type: uplinkListing id: UplinkCostumeCentcom - category: Pointless + category: Misc itemId: ClothingBackpackDuffelSyndicateCostumeCentcom price: 4 - type: uplinkListing id: UplinkCostumeClown - category: Pointless + category: Misc itemId: ClothingBackpackDuffelSyndicateCostumeClown price: 4 diff --git a/Resources/Prototypes/Entities/Clothing/Head/soft.yml b/Resources/Prototypes/Entities/Clothing/Head/soft.yml index a3d22355dc..7eff28e36c 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/soft.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/soft.yml @@ -239,3 +239,25 @@ sprite: Clothing/Head/Soft/yellowsoft_flipped.rsi - type: Clothing sprite: Clothing/Head/Soft/yellowsoft_flipped.rsi + +- type: entity + parent: ClothingHeadBase + id: ClothingHeadHatBizarreSoft + name: troublemaker's soft + description: A truly.. bizarre accessory. + components: + - type: Sprite + sprite: Clothing/Head/Soft/bizarresoft.rsi + - type: Clothing + sprite: Clothing/Head/Soft/bizarresoft.rsi + +- type: entity + parent: ClothingHeadBase + id: ClothingHeadHatBizarreSoftFlipped + name: troublemaker's soft flipped + description: A truly.. bizarre accessory, flipped. + components: + - type: Sprite + sprite: Clothing/Head/Soft/bizarresoft_flipped.rsi + - type: Clothing + sprite: Clothing/Head/Soft/bizarresoft_flipped.rsi diff --git a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml new file mode 100644 index 0000000000..0261ad243b --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml @@ -0,0 +1,73 @@ +# Does not inherit from simplemob +- type: entity + name: Holoparasite + id: MobHoloparasite + description: A mesmerising whirl of hard-light patterns weaves a marvelous, yet oddly familiar visage. It stands proud, tuning into its owner's life to sustain itself. + components: + - type: GhostTakeoverAvailable + makeSentient: true + name: Holoparasite + description: Listen to your owner. Don't tank damage. Punch people hard. + - type: Input + context: "human" + - type: PlayerMobMover + - type: PlayerInputMover + - type: MovementSpeedModifier + baseWalkSpeed : 7 + baseSprintSpeed : 7 + - type: DamageOnHighSpeedImpact + damage: + types: + Blunt: 5 + soundHit: + path: /Audio/Effects/hit_kick.ogg + # TODO: Randomise sprites and randomise the layer color + - type: Sprite + drawdepth: Mobs + sprite: Mobs/Aliens/Guardians/guardians.rsi + layers: + - state: tech_base + - state: tech_flare + color: "#40a7d7" + shader: unshaded + noRot: true + - type: Clickable + - type: InteractionOutline + - type: Physics + bodyType: KinematicController + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeCircle + radius: 0.35 + mass: 10 + mask: + - Impassable + - SmallImpassable + - MobImpassable + layer: + - Opaque + - type: Damageable + damageContainer: Biological + - type: MobState + thresholds: + 0: !type:NormalMobState {} + - type: HeatResistance + - type: CombatMode + - type: Internals + - type: Examiner + - type: Speech + - type: Pullable + - type: UnarmedCombat + range: 2 + arcwidth: 30 + arc: fist + cooldownTime: 0.7 + arcCooldownTime: 0.7 + damage: + types: + Blunt: 40 + - type: Actions + innateActions: + - CombatMode + - type: Guardian diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/guardian_activators.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/guardian_activators.yml new file mode 100644 index 0000000000..37ff027f9a --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/guardian_activators.yml @@ -0,0 +1,26 @@ +- type: entity + name: holoparasite injector + id: HoloparasiteInjector + parent: BaseItem + description: A complex artwork of handheld machinery allowing the user to host a holoparasite guardian. + components: + - type: Sprite + sprite: Objects/Specific/Medical/hypospray.rsi + state: combat_hypo + netsync: false + - type: GuardianCreator + guardianProto: MobHoloparasite + +- type: entity + name: holoparasite box + parent: BoxBase + id: BoxHoloparasite + description: A box containing a holoparasite injector + components: + - type: StorageFill + contents: + - id: HoloparasiteInjector + - id: HoloparasiteInfo + - type: Sprite + layers: + - state: box diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..210ee84379e34b5d56d745bc5e7c8c1294f35df6 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z6FprVLn`LH zy>-^>u!9KegUcmtW=^~>7YQz53DMg1fwzXEcGJ5W&eEIj?(Wdh(3l#e@o15ri13n$ zVe7eb7arR$d8whoPQpoV=FY=sRc1>z{M+8-yF6;8qI~jp|M0Nnn;%MTr~a?2$(r>mdKI;Vst E0Fd&x?*IS* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a9b5f6decb0e5c69ec20e4c7c7974bb3e352d907 GIT binary patch literal 386 zcmV-|0e$|7P)Px$JV``BR9J=Wlfg>EKoEw%O?R7AC{hm=5$(;Rui~5dJU&ImSMksyh*+f9o+Rxd zps?gx9BOy>KUWx?a|cs&0db;!@B;g#F085IFAP9H_HYX>Mw+l}td z9_vzOcEZQB%d)l z2x$e!C2^9)TfI^_Kp^g14NkJSbf)PO&-X7F6|E1zus`_y0C|X_bbe>HdWQW0y_+-9 zJnLqG#CFT?e35lhMOFj0zv~AgfyMRxTF>XzQ-i zs#&U8x7g~-d+NwRcm*bCVN`@xAu~H+GtfTb9MJ{-#6IY5H_!~bW3rW-cKW(YX1FnG1doTH|-YSX)_?p?RHe&L7}Y2|S%*{H`QcJa`~ z?cKNZmg#06pY`THv!K20@yE~0_XIF1K|z%6RwJvgYXZ`e`SZ88p1*2xd*(O)m$913 zp}VYeW;QZ3WdC4jc=D8K-`?(Nk|&aH{r;vjD=qrkRko0`^NzV0u`p`-EMSKt|a8yx@VcQawSVb(oU}ClHHPCa@lUe>&@B=zDsi0g;gK_y+b}uY!$=i zcPWov{?69CykN?tqN($DMxS5&@6&XB!HcUd{!8h598o^K*fnrV!0%nl3PZ$%Kip?l zfI0eC^weK*)4$(m{II#6KP~jx+y&{am*np$SiU@D`sd}NE7I|5%Q{YlG^Dpqnp0l< z{jE&y-(6hO>=-BezwNs?qxz20<%SL*2)iipUN7atk@vF|fT7Lc>FVdQ&MBb@00jKF A#{d8T literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..4e0fb568725464f3b83138c41a88048b829176b7 GIT binary patch literal 412 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z!#rIaLn`LH zy>-y*uz>{ohyS};@|>o=+rVYSr6p?ngUu=4asHXv{tJ&+>h5b;ut39E;!&cUh}Dsk zZS&dh9#Cb?KDhPAe@BhK9Ev|ZG<=x^1R>z!|DesRxARm!Z#=#|I{U8Cr_$pu{(t^) z?^eC3e8$TFh6AhF85-`LmTWpE7G*VMdEx#qo*zoxr(M+wS!>wso5I2{X=+RUC1urI zb0NWry-RIp?pq$4nzFU0=I+ETt9z1Wi#DWkt}!ip`s)eTi+a{W=Z}9o$S3C}K6M7; ztxTzpAAhedm5gA2vhu)*YXwFce;;&qbZAUJReyW3%Fn{P7Ja=lKI%_cesGN&P#g@j zblfa9zVN*_khq(owycNiY{Tit z#mZ(jR~fE#oBUqRrJ7J|U%lY6a+%y}VW9T|Eo&K~zomcZ=4`751~-GJtDnm{r-UW| D{wB5S literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json new file mode 100644 index 0000000000..b3513bb5cd --- /dev/null +++ b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Taken from civstation at commit https://github.com/Civ13/Civ13/commit/ec52cbb95d59b717d4d8c480b35ac133e5b58088#diff-fba188fb2db5d16e5d41985147336a8f96085f761b903e016fffd869b63e497d", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HELMET", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..fc6c43c930706110a1cb5f5135eb2f49b3fd1fec GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zV?13PLn`LH zz2)!CIGRy#dF-_~AYTJ6o5AB$Z+X^osTTcrid^cDHG@^@tYFDJ+Y%B zXT9vH7kh)lXGTW0ZQ@%3WEf?Ko;h4`#H^dWsJxDQ%YNpE*OT8@$oIee>J`>dcE_jY z!^O?F*urG>H0_OV-A&xIsh&X)8AwLo_{)$`TFxRi^ZrK9c}skcY!&mWtdEH~{(EC` zcZjabBddEZ?{-{snq;>2lXUz9hK6^oY)%Ubt4sy&Ti)7~dG5y9$mFv53G?dTsTx}e xm4Cjs{=ROt^dHmHd%uS>*sN1mLV!h?^Vw&YonpTb;Ry_M22WQ%mvv4FO#sk{tXlv8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bb759bf4f2ca6118e3da720c001a08d71144d583 GIT binary patch literal 392 zcmV;30eAk1P)Px$LP{%=gg5Y2d^8hRKE?Pp5REYzXJK&Rgv^4! z4%Y>O1!km-y0RzfruWP3p``^327|%y-(kAJOXrFJprmY2d&?iS`}E;DAz#diGaH;a zaNrFCHt0~9(XcP(bbRE4GaCTFne%OavyCT7Sh~TqN&o*2wnYy@^ zz`9&9NyT0XRVKO#5iP=-7?sez1;E!AsUm$&`8g!zC@F*74kh~>{Di6!!gAqS-52t`eCbI4x_~OO mYo4$)Xus+fN0000#e8& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..4cec5427a9cf232a857dafcbe6f525b60e8a5940 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zLp@y_Ln`LH zy>-#6IY5H_!~bW3rW-cKW(YX1FnG1doTH|-YSX)_?p?RHe&L7}Y2|S%*{H`QcJa`~ z?cKNZmg#06pY`THv!K20@yE~0_XIF1K|z%6RwJvgYXZ`e`SZ88p1*2xd*(O)m$913 zp}VYeW;QZ3WdC4jc=D8K-`?(Nk|&aH{r;vjD=qrkRko0`^NzV0u`p`-EMSKt|a8yx@VcQawSVb(oU}ClHHPCa@lUe>&@B=zDsi0g;gK_y+b}uY!$=i zcPWov{?69CykN?tqN($DMxS5&@6&XB!HcUd{!8h598o^K*fnrV!0%nl3PZ$%Kip?l zfI0eC^weK*)4$(m{II#6KP~jx+y&{am*np$SiU@D`sd}NE7I|5%Q{YlG^Dpqnp0l< z{jE&y-(6hO>=-BezwNs?qxz20<%SL*2)iipUN7atk@vF|fT7Lc>FVdQ&MBb@00jKF A#{d8T literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..ec0fb5b2c89f182502610d1fb42e9e0367c3ce9f GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zTRdGHLn`LH zz2)eAs6gWQ$MsJybZ}W`2r6|*eC6A9B+fDMy>^G+zQ#Vqxvw;0cd1ISw6zGxy%92W zQcjgM>6~L$Qrxwl|IMcZn{BJV-LK#9U)}`@QZ}~yvB*5*ajQN#KVJWDwrKa!g*%sJ z3iYS3e~P!C@8nmxEVD0OLtvi9ZAYN0*AI0MEzGdLwk?|B+j}*h&6!Jb8r)VprF|7( zSbh0NXZ61WHu($(4yR@+OtZRIHZ^+ps>vspZv4bn;PCbFG?$X;w<_mW_rGSDFE!!h zQrShm;XA9B7GGYDT@4F#Ynb7FyXce4d5YWb zH`{{U44$rjF6*2Ung9$_$nyXI literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json new file mode 100644 index 0000000000..b3513bb5cd --- /dev/null +++ b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Taken from civstation at commit https://github.com/Civ13/Civ13/commit/ec52cbb95d59b717d4d8c480b35ac133e5b58088#diff-fba188fb2db5d16e5d41985147336a8f96085f761b903e016fffd869b63e497d", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HELMET", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Interface/Actions/manifest.png b/Resources/Textures/Interface/Actions/manifest.png new file mode 100644 index 0000000000000000000000000000000000000000..7db153e9f276d7680aeb5fc7a907d6de4484ce84 GIT binary patch literal 1922 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/magic_flare.png b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/magic_flare.png new file mode 100644 index 0000000000000000000000000000000000000000..3639229c4feaf1d02a0dd23d970a74010511b6fb GIT binary patch literal 1099 zcmV-R1ho5!P)a@(*zJt=L0VH%Q#xew%*eWsjEK*_qc%x}SMz)4Xryd-GwC8T$pVnru;Nz>0OdiB zbs4bYR||l$TgJ&-^EZEn%Kk8GI%%f(n$_>B!i&GO0A)AzNZym*^a?ybKc}<^xK z{2K8qUx7}ivo;=&KSZGN!CRS21whodx3`o$AwQBwT$+7VJpg354kX{(+vAIgv|25< z3OG7C%6Y)YN~kNkN&p1YZnuSH-|co~dwW~@{l0i456t#WXRpA*>i{w8h^`Ue>WTs<5vIxQYg=0uzEE>f|Uopjg5`G;_CLC$^tOS zUayxT2nK^SMg@et5CflYZ*SMM;#U@6Uh)V+A^=YpAmpu+JfQ9Y zB#oUsLEgHR*Zdup6-Oh0tT-A0tT*(W7x38IQ~+3KUh@LsOoFBTW-0&z^O_g%vfs=E zV0n64WZc{GDwqfm(;c4YP-|f#00PO7&^`8Sg0$(au9?{tKwzGg5T5*h+XTZ(5Mx-M zJYoJA#3^~q2zl*o{uuP?0bYBXzX@h{RJ`D^x48hGLz5nRH-Cm?#nA{*<;S$gJxx$8 zw6Uq|aS&z5M^U^+V#@0v0{F853i4tpNCew5da< zHfAO8Ajr*FG+v>~8Vd&%NE}`ZaRkd9oZ&%e`;y8Wg(=Bv5C#&X0%ja(C_G}(&Iyzf zAoTx2a}*^QGkGEu0Wn}cq3BMR^(?;>fXRktD4ki{Kc0fuXv}BexD2b0E^*PiFJqi8 z6aX7CX%0Y;nAZTS=V;7l2q#4l1Cqsr3Sz_e{EXjyRS63P2+KZv(crxU5$1zpKLQyO z9)*L!Ag_RV4e_gksX8i~hARSCM)Cwl_Bgdxh_MtZzXyctGLt75Lov3p_zS)hx`hq0 RNu&S(002ovPDHLkV1lyd_16FZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/meta.json new file mode 100644 index 0000000000..28c17164ad --- /dev/null +++ b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/meta.json @@ -0,0 +1,57 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "taken from /tg/ station at commit https://github.com/tgstation/tgstation/commit/02756c2bc2cf3000080d030955e994242bab39b5", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "magic_flare", + "directions": 4 + }, + { + "name": "magic_base", + "directions": 4 + }, + { + "name": "miner_flare", + "directions": 4 + }, + { + "name": "miner_base", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "tech_flare", + "directions": 4 + }, + { + "name": "tech_base", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner.png b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner.png new file mode 100644 index 0000000000000000000000000000000000000000..f4dd065628c5f3c145587bf4779fbd01ba7b56a6 GIT binary patch literal 681 zcmV;a0#^NrP)wrPBEi zrKN*2fFKBhz{eQ#FZ|ppyQv?w*3N%#+xG2TW6b$@JpSeOqmpZc1_a&0Pgquv;BI#PL8P7+ErEcJU$!_0D#l!#J+=T>Ay7& zjQ~L3_W*$Xejjzh_Y2PrNjd*1{Xb()cq1X!T3BnN7x8F!0HBl_wLxV~{pb>i2$0x% ze}RfI=DcDmh%ulQk>v!g&)=T`zXVSV)j0vKRN>dplO=q$c;sTLvg>Kb6HFO zWgGMz!r)^r-qynrmkMOo)_4K35Ff4wNOfNv|sT3IfF1Kg3Ph`G6UMS-C1j&$4aTm@H2+D6Am85PN*M#=IT@I zBtzlNzRwr5BM5>Z2!bF8f*=SH)~XXItyA(5IrV>)wc z5=iOloLv1{%&kdCmdJ2&^_R=VEj2LSm%6TZ!?rm!38VD^A)H)&UDvzZ|M4k=7Y~%F zNgyqOVcR!M{UKZN^Z#Y7T7l9!(bU)&vGvW#)z2ZNv*hz9nP>m>4B*xwu<-&@B8%RE z3Hub^Vvv?Vn75xwb5n{Ma!D0Cc;C1_ke>mRynV^ShLjJU+&Tmg>mdlt%iEWxL>)ph z67*06mdNdM?C0o{W&kzco|DU`GOS(T_%#K~*>BCaf2&`DAP9mW2w%-F)RzF?z@@hg P00000NkvXXu0mjfu%1i` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner_base.png b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/miner_base.png new file mode 100644 index 0000000000000000000000000000000000000000..f22a027edc10aa7fd10ac3d88f3ec0a928874bdd GIT binary patch literal 2776 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech.png b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech.png new file mode 100644 index 0000000000000000000000000000000000000000..ada4a5ca142ea07c9ac8200bdbb330bbaf95f45c GIT binary patch literal 854 zcmV-c1F8IpP)uLYX6LOZ}f+4}=g{YJ`+h3n6BW-CIATl)7!( z*>B?2$1f7Hit>&0f0^o_l)4MYG)>QAih*1BDy2ef-c7$V2aqyj42q(F?^+Te}Bj2a&Zc+>snV;g*c8EPu`{9H8Clrj-m*m`nx4yuNT+g z{^aYr)^^+Faye&NHn{Glc$?J*>~EKBED zAN^4jJ&dC^azu#!yCq;NNs{Dlz|dRiM?hZ=DOF0r7~_=Vqo3p{rH~}aZva05`~vVD zzz?O=w zqe)Oosh1?PHO2!sN5pa5IpAM}d{957)El)MW4ivpwBx;Yfg$R;?$+0w2nm5QJb=yt zeeCv-EqL@Cus8G}BZNRzRoyyvVT?glRo%hKCvkf_z;_o|<15ZKo(?v4NcSCKzwtPZ z?+#8=j+k5mKKt{M{zGFal)Bw^I@Y;I#`m4Vp{Hc=~{$kC-+73D|OM*><1V zNpNkJM9vZ9GYrEp48t%C!!Z91Yu4%az{mc{Ut(+2>GxpK-GIKJHA>xEvbxQ$$muvI{hBZxtkF5Q2_rhZE|O*1OgE}N~z zluVaRQ*&|VfT3D_6h+AM8~{)h#gxsP(KJnGmr^R|Uc#UQ`WF(0YV}8j%HzPz8DsYw zfPm7NU8^sO0@v&H5bK}FvP|cB?tL$S@J@oZBaSwCBFi$pdxCyO0(_?I)yv~YU{_mT zEdrd3dGUzRFxTFPZO}ebw{5FWr_&)5o-b|NY5>k}80SG~Y|lT+5!l9M(<_`^7=~dO ghG7_nVVJG?3r-daAX5AsTmS$707*qoM6N<$f>4!~1poj5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech_base.png b/Resources/Textures/Mobs/Aliens/Guardians/guardians.rsi/tech_base.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0a59725450d4b544f4c83242b10b7b72192bdd GIT binary patch literal 1694 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 Eg1WP%YXATM literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/guardian_info.rsi/guardian_info.png b/Resources/Textures/Objects/Misc/guardian_info.rsi/guardian_info.png new file mode 100644 index 0000000000000000000000000000000000000000..8de21319c178f1862d6682cbbe99634a77e2baa2 GIT binary patch literal 1551 zcmV+q2JrcbP)Px)$w@>(RCt{2nmue&R~Uw$6WjRbIyOl#Rzj>K!~ukfgBpWdiJ=lwhp4J5v2^HC zsjAeW9Xe&`(4j;24pd#bmZ3|BE>H;s11`5}3dKsvk4Y1!*daDa9LG+seL6Tv`3dA+ z$Hutacd~sxpZ7h--*Yi4S? z!?77Gk(U4#Twuqe*q_PeM7!I)^W6(wx|2+|j%u_#Plw(NkN|d@RZJxQ64~Uu zJlKCwo(~NJ@XOubWH$MT2~iS(uAZHE43wAw)Kp80PEr97PtH%B=sPZz%?EgM+RmUi zr=e^<;6&eX8Bfkny@;>|sHqmc8$dFf5uH{MjE`Rv0Fh`EH5NmS#fU_s0K~_yiB78s zCbJm$pkpqf{&0;~6%4KE~2@b#Y1^}~( z1m$v>-ebpv&F+xPZmaaWJT=RIzsp0473s}sw6(X3d@jepV3=jMl^n>~M1nwnP&l1V zW)lgy;}tZEhE`%zykY52NqCv**0J4ne=-Mbk8)#$vb>MOeznWw#ZwdC2Bj zc3ZKOkuF6MYAlAPX~M5~_qXDg#IGv@Mtb~Qym}KrSXwH37WM^53~2(O&lixhxddBd zA~`q5r*FSm&02Rw=HWwDS65|EUmuCt1hgQ+zJQz^)M#yO6(0_Vc49AHy=jQwaGm~e z`yTxR0}^0md07B>yj}?~Jvk{p2p=;#WkWd)-3tIXolewPjGn$e9<4qCpja$2n@G@g zTz{t6!_zL8 zRw`Fn+poWTZ)9I$8o_C}1OSvnhsd`e>`os5c`1c*;LyH=G>X%328^jH7OR7jR*;W> zZm~KhERo8#)7qPM>38e1eizkVI)h8`uu&|^k1t&!x4QDgxVzQEw-?^W=~Tq}`Wkotyk$s8qxf}gz|iS)9I)HT zudT@LKtJ6eF$z8i?Tb=Pe(^59UYx7jD7IW{GNAV zMo}+*-5YS=fL+Y}JtOyuoBMkPMQIfq8%4cSHW1o67#CT=<|RnAUJwsa?hUp z{-r&MdifKY${$b<{-*E;)RVti`~h|2Zx(+*-S~B%0b4zJ;^WtVN)Jwr#ehnGesX@Q z(vxrRCYjA}q^-TC{(yS%H-$f-p8UE>U`$o%INA$awYB9BKuOP_q-R)6r?>q9Q1J&a zrmDIGG@4&mj(#7%M=D?G&u@v{Y)aTq=o@w#k-10Kdy4J~~;OK4Cri zbw3sl`vOFwQEYaHlr{@c>CbQX=%vkq&F+wqXq2!oP|Z3U!vEU)19WY`NROZ7+#EdR z59l8Xi~gao*xvES{Q)CA{wkLG^7)&>A5c&Jrtk;UlfNna0rli>8h=2&_?yNbP%nPd zA7CWd^aq&!0Mj2}`UCcgGyMTg<_|Do!o=&1e*t36f=yYN`w9R6002ovPDHLkV1mpC B>eT=M literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/guardian_info.rsi/icon.png b/Resources/Textures/Objects/Misc/guardian_info.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ec276cc88d8deb06efb55f34e4736344cc6c4f2f GIT binary patch literal 952 zcmV;p14sOcP)Px&a!Eu%R9J1Y~BMbMBdY?-&g~aC>`8k1)K)5CF2>rxkt?Lwj9yz4*Jx z9mnWh(<&g_eOi(7E-=Q_81f{^dV?9|K${pLg!ZfCy#fgHzutvoj)NQ_@?+L(P=zXr zdJ_H&7-LG^1d-zy;Q#!KZ1QSU9t}D$2EOkr0GOK7i^v-ShLWz2e7oIhLI~~Km%oFq zb%ysC(yvtj04(3W566n}eP7uR@6>j?)m+zA>-AazXhdHpbsPh2CE1w+%eU{tr;i^h z8yRD&EAw5~RcV^Swr%Y9d#IZr0#FeiGliVz0M7f1-nOCPJ%&k=HO7Px+H$#6Pft%8 zks5}9EX$ClDJ;u+*-+OZpQGT_>o*bQLmTm+19i-1Gj%*38_|;^j4`!XEUNLMC~!C& zAf<%538JB799@RK?<>;2lw~)007Q803b;cNGW?87SM47 zbx`zi97ET2_`a`_Bsp8hIj=}{{bgHS*L!mZ=;#CWK2O#QAv7r^+Q@0i8M_CpsE7-90j_rza*xVRbX{T zI&*+pYdwh=V`{ZpwYuOq4#F^OY;Jguq4pdF0I*uEz&S@8$HM~F>$N)F>{LWi6v*=& z)9Dn~*Vkv{ZR-z*1JX2Yth+j0?EAjjY&M-qBZSbxFhri`FijJAp7)Z|bDrmC96$g*Z*BeWiY z>$(a6CX)&F`+X&jF{UU%P1CH_Q|(jTlNj5!QI;hDv_{`4pdJmqL>+HBonp7!RfHtS z^E~8v-bk{xeNNHZ2ZRt>{RPIDvTYl{%UOD!S4AtOtjH=n9t_`0K+g4$8m4_y;uN&Y`%1^52L>csf>!EXq~6=u5# am*77W*-HfmHs8?z0000 Date: Tue, 28 Dec 2021 22:59:51 -0500 Subject: [PATCH 03/12] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 54bca6d51d..9d7a3a3ec1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Seth - changes: - - {message: Added Makeshift Handcuffs into the construction list, type: Add} - id: 283 - time: '2021-07-25T15:30:42.0000000+00:00' - author: metalgearsloth changes: - {message: Shuttle-relative movement for when we get shuttle rotation., type: Add} @@ -2872,3 +2867,10 @@ Entries: - {message: Chaplain no longer spawns with an empty backpack., type: Fix} id: 784 time: '2021-12-29T02:48:58.0000000+00:00' +- author: CrudeWax + changes: + - {message: Syndiecorp Cybersun invites you to try out their magnum opus- holoparasites! + Look for the "Utility" section in your uplink. And ghosts - be on the lookout + for a role prompt!, type: Add} + id: 785 + time: '2021-12-29T03:58:49.0000000+00:00' From e5e144d99c7d2eef76c627a537ce3f541a5c26ca Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 29 Dec 2021 15:57:20 +1100 Subject: [PATCH 04/12] Rollerbeds (#5681) --- Content.Client/Entry/IgnoredComponents.cs | 1 + .../Morgue/Visualizers/BodyBagVisualizer.cs | 4 + .../Storage/Visualizers/StorageVisualizer.cs | 22 ++- .../Visualizer/FoldableVisualizer.cs | 36 +++++ .../Visualizer/RollerbedVisualizer.cs | 29 ++++ .../Buckle/Components/BuckleComponent.cs | 15 +- .../Buckle/Components/StrapComponent.cs | 75 +++++++++- Content.Server/Buckle/Systems/BuckleSystem.cs | 12 +- Content.Server/Buckle/Systems/StrapSystem.cs | 38 ++--- Content.Server/Foldable/FoldableComponent.cs | 25 ++++ Content.Server/Foldable/FoldableSystem.cs | 131 ++++++++++++++++++ .../Components/EntityStorageComponent.cs | 20 ++- .../Buckle/Components/SharedStrapComponent.cs | 6 +- .../Hands/Components/SharedHandsComponent.cs | 11 +- Content.Shared/Item/PickupAttemptEvent.cs | 13 ++ Content.Shared/Item/SharedItemComponent.cs | 1 - .../components/foldable-component.ftl | 5 + .../Objects/Specific/Medical/morgue.yml | 20 ++- .../Entities/Structures/Furniture/chairs.yml | 1 + .../Structures/Furniture/rollerbeds.yml | 94 +++++++++++++ .../Storage/Closets/Lockers/lockers.yml | 40 ++++++ .../Storage/Closets/base_structureclosets.yml | 1 + .../Structures/Storage/Closets/closets.yml | 18 ++- .../Structures/Storage/Closets/wardrobe.yml | 11 ++ .../Prototypes/Recipes/Lathes/medical.yml | 6 +- .../Textures/Interface/VerbIcons/fold.svg | 3 + .../Interface/VerbIcons/fold.svg.192dpi.png | Bin 0 -> 2619 bytes .../VerbIcons/fold.svg.192dpi.png.yml | 2 + .../bodybags.rsi/{item.png => bag_folded.png} | Bin .../Medical/Morgue/bodybags.rsi/meta.json | 2 +- .../rollerbeds.rsi/cheap_rollerbed.png | Bin 0 -> 326 bytes .../cheap_rollerbed_buckled.png | Bin 0 -> 490 bytes .../rollerbeds.rsi/cheap_rollerbed_folded.png | Bin 0 -> 403 bytes .../rollerbeds.rsi/emergency_rollerbed.png | Bin 0 -> 449 bytes .../emergency_rollerbed_buckled.png | Bin 0 -> 618 bytes .../emergency_rollerbed_folded.png | Bin 0 -> 582 bytes .../Furniture/rollerbeds.rsi/meta.json | 38 +++++ .../Furniture/rollerbeds.rsi/rollerbed.png | Bin 0 -> 402 bytes .../rollerbeds.rsi/rollerbed_buckled.png | Bin 0 -> 565 bytes .../rollerbeds.rsi/rollerbed_folded.png | Bin 0 -> 401 bytes 40 files changed, 627 insertions(+), 53 deletions(-) create mode 100644 Content.Client/Visualizer/FoldableVisualizer.cs create mode 100644 Content.Client/Visualizer/RollerbedVisualizer.cs create mode 100644 Content.Server/Foldable/FoldableComponent.cs create mode 100644 Content.Server/Foldable/FoldableSystem.cs create mode 100644 Resources/Locale/en-US/foldable/components/foldable-component.ftl create mode 100644 Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml create mode 100644 Resources/Textures/Interface/VerbIcons/fold.svg create mode 100644 Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png create mode 100644 Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png.yml rename Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/{item.png => bag_folded.png} (100%) create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_buckled.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_folded.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_buckled.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_folded.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/meta.json create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_buckled.png create mode 100644 Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_folded.png diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 5741ee1b8f..452f5be09f 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -299,6 +299,7 @@ namespace Content.Client.Entry "IncreaseDamageOnWield", "TabletopGame", "LitOnPowered", + "Foldable", "TriggerOnSignalReceived", "ToggleDoorOnTrigger", "DeviceNetworkComponent", diff --git a/Content.Client/Morgue/Visualizers/BodyBagVisualizer.cs b/Content.Client/Morgue/Visualizers/BodyBagVisualizer.cs index 1aeff3e8c8..b64ce7d8d8 100644 --- a/Content.Client/Morgue/Visualizers/BodyBagVisualizer.cs +++ b/Content.Client/Morgue/Visualizers/BodyBagVisualizer.cs @@ -23,6 +23,10 @@ namespace Content.Client.Morgue.Visualizers { sprite.LayerSetVisible(BodyBagVisualLayers.Label, labelVal); } + else + { + sprite.LayerSetVisible(BodyBagVisualLayers.Label, false); + } } } diff --git a/Content.Client/Storage/Visualizers/StorageVisualizer.cs b/Content.Client/Storage/Visualizers/StorageVisualizer.cs index cd1a73927e..a48e0535db 100644 --- a/Content.Client/Storage/Visualizers/StorageVisualizer.cs +++ b/Content.Client/Storage/Visualizers/StorageVisualizer.cs @@ -10,6 +10,9 @@ namespace Content.Client.Storage.Visualizers [UsedImplicitly] public sealed class StorageVisualizer : AppearanceVisualizer { + /// + /// Sets the base sprite to this layer. Exists to make the inheritance tree less boilerplate-y. + /// [DataField("state")] private string? _stateBase; [DataField("state_open")] @@ -41,9 +44,24 @@ namespace Content.Client.Storage.Visualizers } component.TryGetData(StorageVisuals.Open, out bool open); - var state = open ? _stateOpen ?? $"{_stateBase}_open" : _stateClosed ?? $"{_stateBase}_door"; - sprite.LayerSetState(StorageVisualLayers.Door, state); + if (sprite.LayerMapTryGet(StorageVisualLayers.Door, out _)) + { + sprite.LayerSetVisible(StorageVisualLayers.Door, true); + + if (open && _stateOpen != null) + { + sprite.LayerSetState(StorageVisualLayers.Door, _stateOpen); + } + else if (!open && _stateClosed != null) + { + sprite.LayerSetState(StorageVisualLayers.Door, _stateClosed); + } + else + { + sprite.LayerSetVisible(StorageVisualLayers.Door, false); + } + } if (component.TryGetData(StorageVisuals.CanLock, out bool canLock) && canLock) { diff --git a/Content.Client/Visualizer/FoldableVisualizer.cs b/Content.Client/Visualizer/FoldableVisualizer.cs new file mode 100644 index 0000000000..6b2861dc7b --- /dev/null +++ b/Content.Client/Visualizer/FoldableVisualizer.cs @@ -0,0 +1,36 @@ +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Client.Visualizer; + + +public sealed class FoldableVisualizer : AppearanceVisualizer +{ + [DataField("key")] + private string _key = default!; + + public override void OnChangeData(AppearanceComponent appearance) + { + base.OnChangeData(appearance); + + var entManager = IoCManager.Resolve(); + + if (!entManager.TryGetComponent(appearance.Owner, out SpriteComponent? sprite)) return; + + if (appearance.TryGetData("FoldedState", out bool folded) && folded) + { + sprite.LayerSetState(FoldableVisualLayers.Base, $"{_key}_folded"); + } + else + { + sprite.LayerSetState(FoldableVisualLayers.Base, $"{_key}"); + } + } + + public enum FoldableVisualLayers : byte + { + Base, + } +} diff --git a/Content.Client/Visualizer/RollerbedVisualizer.cs b/Content.Client/Visualizer/RollerbedVisualizer.cs new file mode 100644 index 0000000000..053d521d57 --- /dev/null +++ b/Content.Client/Visualizer/RollerbedVisualizer.cs @@ -0,0 +1,29 @@ +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Client.Visualizer +{ + [UsedImplicitly] + public sealed class RollerbedVisualizer : AppearanceVisualizer + { + [DataField("key")] + private string _key = default!; + + public override void OnChangeData(AppearanceComponent appearance) + { + base.OnChangeData(appearance); + + var entManager = IoCManager.Resolve(); + + if (!entManager.TryGetComponent(appearance.Owner, out SpriteComponent? sprite)) return; + + if (appearance.TryGetData("StrapState", out bool strapped) && strapped) + { + sprite.LayerSetState(0, $"{_key}_buckled"); + } + } + } +} diff --git a/Content.Server/Buckle/Components/BuckleComponent.cs b/Content.Server/Buckle/Components/BuckleComponent.cs index 0c40c6c768..d140e264fb 100644 --- a/Content.Server/Buckle/Components/BuckleComponent.cs +++ b/Content.Server/Buckle/Components/BuckleComponent.cs @@ -133,7 +133,7 @@ namespace Content.Server.Buckle.Components break; } - ownTransform.LocalPosition = Vector2.Zero + BuckleOffset; + ownTransform.LocalPosition = Vector2.Zero + strap.BuckleOffset; } public bool CanBuckle(EntityUid user, EntityUid to, [NotNullWhen(true)] out StrapComponent? strap) @@ -317,10 +317,17 @@ namespace Content.Server.Buckle.Components BuckledTo = null; - if (_entMan.GetComponent(Owner).Parent == _entMan.GetComponent(oldBuckledTo.Owner)) + var entManager = IoCManager.Resolve(); + var xform = entManager.GetComponent(Owner); + var oldBuckledXform = entManager.GetComponent(oldBuckledTo.Owner); + + if (xform.ParentUid == oldBuckledXform.Owner) { - _entMan.GetComponent(Owner).AttachParentToContainerOrGrid(); - _entMan.GetComponent(Owner).WorldRotation = _entMan.GetComponent(oldBuckledTo.Owner).WorldRotation; + xform.AttachParentToContainerOrGrid(); + xform.WorldRotation = oldBuckledXform.WorldRotation; + + if (oldBuckledTo.UnbuckleOffset != Vector2.Zero) + xform.Coordinates = oldBuckledXform.Coordinates.Offset(oldBuckledTo.UnbuckleOffset); } Appearance?.SetData(BuckleVisuals.Buckled, false); diff --git a/Content.Server/Buckle/Components/StrapComponent.cs b/Content.Server/Buckle/Components/StrapComponent.cs index 3d06c638e0..21d1588225 100644 --- a/Content.Server/Buckle/Components/StrapComponent.cs +++ b/Content.Server/Buckle/Components/StrapComponent.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Linq; +using Content.Shared.ActionBlocker; using Content.Shared.Acts; using Content.Shared.Alert; +using Content.Shared.Buckle; using Content.Shared.Buckle.Components; using Content.Shared.DragDrop; using Content.Shared.Interaction; @@ -9,6 +11,8 @@ using Content.Shared.Sound; using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -21,8 +25,6 @@ namespace Content.Server.Buckle.Components { [ComponentDependency] public readonly SpriteComponent? SpriteComponent = null; - [Dependency] private readonly IEntityManager _entMan = default!; - private readonly HashSet _buckledEntities = new(); /// @@ -37,6 +39,50 @@ namespace Content.Server.Buckle.Components [ViewVariables] [DataField("size")] private int _size = 100; private int _occupiedSize; + /// + /// The buckled entity will be offset by this amount from the center of the strap object. + /// If this offset it too big, it will be clamped to + /// + [DataField("buckleOffset", required: false)] + private Vector2 _buckleOffset = Vector2.Zero; + + private bool _enabled = true; + + /// + /// If disabled, nothing can be buckled on this object, and it will unbuckle anything that's already buckled + /// + public bool Enabled + { + get => _enabled; + set + { + _enabled = value; + if (_enabled == value) return; + RemoveAll(); + } + } + + /// + /// The distance above which a buckled entity will be automatically unbuckled. + /// Don't change it unless you really have to + /// + [DataField("maxBuckleDistance", required: false)] + public float MaxBuckleDistance = 1f; + + /// + /// You can specify the offset the entity will have after unbuckling. + /// + [DataField("unbuckleOffset", required: false)] + public Vector2 UnbuckleOffset = Vector2.Zero; + + /// + /// Gets and clamps the buckle offset to MaxBuckleDistance + /// + public Vector2 BuckleOffset => Vector2.Clamp( + _buckleOffset, + Vector2.One * -MaxBuckleDistance, + Vector2.One * MaxBuckleDistance); + /// /// The entity that is currently buckled here, synced from /// @@ -96,6 +142,8 @@ namespace Content.Server.Buckle.Components /// True if added, false otherwise public bool TryAdd(BuckleComponent buckle, bool force = false) { + if (!Enabled) return false; + if (!force && !HasSpace(buckle)) { return false; @@ -110,6 +158,12 @@ namespace Content.Server.Buckle.Components buckle.Appearance?.SetData(StrapVisuals.RotationAngle, _rotation); + // Update the visuals of the strap object + if (IoCManager.Resolve().TryGetComponent(Owner, out var appearance)) + { + appearance.SetData("StrapState", true); + } + #pragma warning disable 618 SendMessage(new StrapMessage(buckle.Owner, Owner)); #pragma warning restore 618 @@ -126,6 +180,11 @@ namespace Content.Server.Buckle.Components { if (_buckledEntities.Remove(buckle.Owner)) { + if (IoCManager.Resolve().TryGetComponent(Owner, out var appearance)) + { + appearance.SetData("StrapState", false); + } + _occupiedSize -= buckle.Size; #pragma warning disable 618 SendMessage(new UnStrapMessage(buckle.Owner, Owner)); @@ -147,9 +206,11 @@ namespace Content.Server.Buckle.Components private void RemoveAll() { + var entManager = IoCManager.Resolve(); + foreach (var entity in _buckledEntities.ToArray()) { - if (_entMan.TryGetComponent(entity, out var buckle)) + if (entManager.TryGetComponent(entity, out var buckle)) { buckle.TryUnbuckle(entity, true); } @@ -166,7 +227,9 @@ namespace Content.Server.Buckle.Components bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) { - if (!_entMan.TryGetComponent(eventArgs.User, out var buckle)) + var entManager = IoCManager.Resolve(); + + if (!entManager.TryGetComponent(eventArgs.User, out var buckle)) { return false; } @@ -176,7 +239,9 @@ namespace Content.Server.Buckle.Components public override bool DragDropOn(DragDropEvent eventArgs) { - if (!_entMan.TryGetComponent(eventArgs.Dragged, out BuckleComponent? buckleComponent)) return false; + var entManager = IoCManager.Resolve(); + + if (!entManager.TryGetComponent(eventArgs.Dragged, out BuckleComponent? buckleComponent)) return false; return buckleComponent.TryBuckle(eventArgs.User, Owner); } } diff --git a/Content.Server/Buckle/Systems/BuckleSystem.cs b/Content.Server/Buckle/Systems/BuckleSystem.cs index 0135e3aea0..8ec67713a6 100644 --- a/Content.Server/Buckle/Systems/BuckleSystem.cs +++ b/Content.Server/Buckle/Systems/BuckleSystem.cs @@ -42,10 +42,12 @@ namespace Content.Server.Buckle.Systems if (!args.CanAccess || !args.CanInteract || !component.Buckled) return; - Verb verb = new(); - verb.Act = () => component.TryUnbuckle(args.User); - verb.Text = Loc.GetString("verb-categories-unbuckle"); - verb.IconTexture = "/Textures/Interface/VerbIcons/unbuckle.svg.192dpi.png"; + Verb verb = new() + { + Act = () => component.TryUnbuckle(args.User), + Text = Loc.GetString("verb-categories-unbuckle"), + IconTexture = "/Textures/Interface/VerbIcons/unbuckle.svg.192dpi.png" + }; if (args.Target == args.User && args.Using == null) { @@ -81,7 +83,7 @@ namespace Content.Server.Buckle.Systems var strapPosition = EntityManager.GetComponent(strap.Owner).Coordinates.Offset(buckle.BuckleOffset); - if (ev.NewPosition.InRange(EntityManager, strapPosition, 0.2f)) + if (ev.NewPosition.InRange(EntityManager, strapPosition, strap.MaxBuckleDistance)) { return; } diff --git a/Content.Server/Buckle/Systems/StrapSystem.cs b/Content.Server/Buckle/Systems/StrapSystem.cs index 9acd58d2db..c1d8ebe784 100644 --- a/Content.Server/Buckle/Systems/StrapSystem.cs +++ b/Content.Server/Buckle/Systems/StrapSystem.cs @@ -27,7 +27,7 @@ namespace Content.Server.Buckle.Systems private void AddStrapVerbs(EntityUid uid, StrapComponent component, GetInteractionVerbsEvent args) { - if (args.Hands == null || !args.CanAccess || !args.CanInteract) + if (args.Hands == null || !args.CanAccess || !args.CanInteract || !component.Enabled) return; // Note that for whatever bloody reason, buckle component has its own interaction range. Additionally, this @@ -41,9 +41,12 @@ namespace Content.Server.Buckle.Systems if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target, range: buckledComp.Range)) continue; - Verb verb = new(); - verb.Act = () => buckledComp.TryUnbuckle(args.User); - verb.Category = VerbCategory.Unbuckle; + Verb verb = new() + { + Act = () => buckledComp.TryUnbuckle(args.User), + Category = VerbCategory.Unbuckle + }; + if (entity == args.User) verb.Text = Loc.GetString("verb-self-target-pronoun"); else @@ -64,10 +67,12 @@ namespace Content.Server.Buckle.Systems component.HasSpace(buckle) && _interactionSystem.InRangeUnobstructed(args.User, args.Target, range: buckle.Range)) { - Verb verb = new(); - verb.Act = () => buckle.TryBuckle(args.User, args.Target); - verb.Category = VerbCategory.Buckle; - verb.Text = Loc.GetString("verb-self-target-pronoun"); + Verb verb = new() + { + Act = () => buckle.TryBuckle(args.User, args.Target), + Category = VerbCategory.Buckle, + Text = Loc.GetString("verb-self-target-pronoun") + }; args.Verbs.Add(verb); } @@ -82,14 +87,15 @@ namespace Content.Server.Buckle.Systems if (!_interactionSystem.InRangeUnobstructed(@using, args.Target, usingBuckle.Range, predicate: Ignored)) return; - Verb verb = new(); - verb.Act = () => usingBuckle.TryBuckle(args.User, args.Target); - verb.Category = VerbCategory.Buckle; - verb.Text = EntityManager.GetComponent(@using).EntityName; - - // If the used entity is a person being pulled, prioritize this verb. Conversely, if it is - // just a held object, the user is probably just trying to sit down. - verb.Priority = EntityManager.HasComponent(@using) ? 1 : -1; + Verb verb = new() + { + Act = () => usingBuckle.TryBuckle(args.User, args.Target), + Category = VerbCategory.Buckle, + Text = EntityManager.GetComponent(@using).EntityName, + // just a held object, the user is probably just trying to sit down. + // If the used entity is a person being pulled, prioritize this verb. Conversely, if it is + Priority = EntityManager.HasComponent(@using) ? 1 : -1 + }; args.Verbs.Add(verb); } diff --git a/Content.Server/Foldable/FoldableComponent.cs b/Content.Server/Foldable/FoldableComponent.cs new file mode 100644 index 0000000000..514d4eddb5 --- /dev/null +++ b/Content.Server/Foldable/FoldableComponent.cs @@ -0,0 +1,25 @@ +#nullable enable + +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Foldable +{ + + /// + /// Used to create "foldable structures" that you can pickup like an item when folded. Used for rollerbeds and wheelchairs + /// + [RegisterComponent] + public class FoldableComponent : Component + { + public override string Name => "Foldable"; + + [DataField("folded")] + [ViewVariables] + public bool IsFolded = false; + + public bool CanBeFolded = true; + } +} diff --git a/Content.Server/Foldable/FoldableSystem.cs b/Content.Server/Foldable/FoldableSystem.cs new file mode 100644 index 0000000000..380b9f29b5 --- /dev/null +++ b/Content.Server/Foldable/FoldableSystem.cs @@ -0,0 +1,131 @@ +using System.Linq; +using Content.Server.Buckle.Components; +using Content.Server.Storage.Components; +using Content.Shared.Interaction; +using Content.Shared.Item; +using Content.Shared.Verbs; +using JetBrains.Annotations; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; + +namespace Content.Server.Foldable +{ + [UsedImplicitly] + public sealed class FoldableSystem : EntitySystem + { + [Dependency] private SharedContainerSystem _container = default!; + + private const string FoldKey = "FoldedState"; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnFoldableInit); + SubscribeLocalEvent(OnFoldableOpenAttempt); + SubscribeLocalEvent(OnPickedUpAttempt); + SubscribeLocalEvent(AddFoldVerb); + } + + private void OnFoldableOpenAttempt(EntityUid uid, FoldableComponent component, StorageOpenAttemptEvent args) + { + if (component.IsFolded) + args.Cancel(); + } + + private void OnFoldableInit(EntityUid uid, FoldableComponent component, ComponentInit args) + { + SetFolded(component, component.IsFolded); + } + + private bool TryToggleFold(FoldableComponent comp) + { + return TrySetFolded(comp, !comp.IsFolded); + } + + /// + /// Try to fold/unfold + /// + /// + /// Folded state we want + /// True if successful + private bool TrySetFolded(FoldableComponent comp, bool state) + { + if (state == comp.IsFolded) + return false; + + if (_container.IsEntityInContainer(comp.Owner)) + return false; + + // First we check if the foldable object has a strap component + if (EntityManager.TryGetComponent(comp.Owner, out StrapComponent? strap)) + { + // If an entity is buckled to the object we can't pick it up or fold it + if (strap.BuckledEntities.Any()) + return false; + } + + SetFolded(comp, state); + return true; + } + + /// + /// Set the folded state of the given + /// + /// + /// If true, the component will become folded, else unfolded + private void SetFolded(FoldableComponent component, bool folded) + { + component.IsFolded = folded; + component.CanBeFolded = !_container.IsEntityInContainer(component.Owner); + + // You can't buckle an entity to a folded object + if (EntityManager.TryGetComponent(component.Owner, out StrapComponent? strap)) + strap.Enabled = !component.IsFolded; + + // Update visuals only if the value has changed + if (EntityManager.TryGetComponent(component.Owner, out AppearanceComponent? appearance)) + appearance.SetData(FoldKey, folded); + } + + #region Event handlers + + /// + /// Prevents foldable objects to be picked up when unfolded + /// + /// + /// + /// + private void OnPickedUpAttempt(EntityUid uid, FoldableComponent component, AttemptItemPickupEvent args) + { + if (!component.IsFolded) + args.Cancel(); + } + + #endregion + + #region Verb + + private void AddFoldVerb(EntityUid uid, FoldableComponent component, GetAlternativeVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract) + return; + + Verb verb = new() + { + Act = () => TryToggleFold(component), + Text = component.IsFolded ? Loc.GetString("unfold-verb") : Loc.GetString("fold-verb"), + IconTexture = "/Textures/Interface/VerbIcons/fold.svg.192dpi.png", + + // If the object is unfolded and they click it, they want to fold it, if it's folded, they want to pick it up + Priority = component.IsFolded ? 0 : 2, + }; + + args.Verbs.Add(verb); + } + + #endregion + } +} diff --git a/Content.Server/Storage/Components/EntityStorageComponent.cs b/Content.Server/Storage/Components/EntityStorageComponent.cs index 7ff590084a..bada7c58ca 100644 --- a/Content.Server/Storage/Components/EntityStorageComponent.cs +++ b/Content.Server/Storage/Components/EntityStorageComponent.cs @@ -193,12 +193,18 @@ namespace Content.Server.Storage.Components return false; } - return true; + var @event = new StorageOpenAttemptEvent(); + IoCManager.Resolve().EventBus.RaiseLocalEvent(Owner, @event); + + return !@event.Cancelled; } public virtual bool CanClose(EntityUid user, bool silent = false) { - return true; + var @event = new StorageCloseAttemptEvent(); + IoCManager.Resolve().EventBus.RaiseLocalEvent(Owner, @event); + + return !@event.Cancelled; } public void ToggleOpen(EntityUid user) @@ -479,4 +485,14 @@ namespace Content.Server.Storage.Components } } } + + public sealed class StorageOpenAttemptEvent : CancellableEntityEventArgs + { + + } + + public sealed class StorageCloseAttemptEvent : CancellableEntityEventArgs + { + + } } diff --git a/Content.Shared/Buckle/Components/SharedStrapComponent.cs b/Content.Shared/Buckle/Components/SharedStrapComponent.cs index d396eacf32..38aeb1f341 100644 --- a/Content.Shared/Buckle/Components/SharedStrapComponent.cs +++ b/Content.Shared/Buckle/Components/SharedStrapComponent.cs @@ -57,11 +57,13 @@ namespace Content.Shared.Buckle.Components } [Serializable, NetSerializable] - public enum StrapVisuals + public enum StrapVisuals : byte { - RotationAngle + RotationAngle, + BuckledState } + // TODO : Convert this to an Entity Message. Careful, it will Break ShuttleControllerComponent (only place where it's used) [Serializable, NetSerializable] #pragma warning disable 618 public abstract class StrapChangeMessage : ComponentMessage diff --git a/Content.Shared/Hands/Components/SharedHandsComponent.cs b/Content.Shared/Hands/Components/SharedHandsComponent.cs index 67028d1353..398aec3203 100644 --- a/Content.Shared/Hands/Components/SharedHandsComponent.cs +++ b/Content.Shared/Hands/Components/SharedHandsComponent.cs @@ -615,11 +615,14 @@ namespace Content.Shared.Hands.Components protected bool CanInsertEntityIntoHand(Hand hand, EntityUid entity) { var handContainer = hand.Container; - if (handContainer == null) - return false; + if (handContainer == null) return false; - if (!handContainer.CanInsert(entity)) - return false; + if (!handContainer.CanInsert(entity)) return false; + + var @event = new AttemptItemPickupEvent(); + _entMan.EventBus.RaiseLocalEvent(entity, @event); + + if (@event.Cancelled) return false; return true; } diff --git a/Content.Shared/Item/PickupAttemptEvent.cs b/Content.Shared/Item/PickupAttemptEvent.cs index 1d922a6d04..e52c0722a9 100644 --- a/Content.Shared/Item/PickupAttemptEvent.cs +++ b/Content.Shared/Item/PickupAttemptEvent.cs @@ -2,6 +2,9 @@ namespace Content.Shared.Item { + /// + /// Raised on a *mob* when it tries to pickup something + /// public class PickupAttemptEvent : CancellableEntityEventArgs { public PickupAttemptEvent(EntityUid uid) @@ -11,4 +14,14 @@ namespace Content.Shared.Item public EntityUid Uid { get; } } + + /// + /// Raised on the *item* when tried to be picked up + /// + /// + /// Doesn't just handle "items" but calling it "PickedUpAttempt" is too close to "Pickup" for the sleep deprived brain. + /// + public sealed class AttemptItemPickupEvent : CancellableEntityEventArgs + { + } } diff --git a/Content.Shared/Item/SharedItemComponent.cs b/Content.Shared/Item/SharedItemComponent.cs index bd86f8e983..5c83bb95c7 100644 --- a/Content.Shared/Item/SharedItemComponent.cs +++ b/Content.Shared/Item/SharedItemComponent.cs @@ -9,7 +9,6 @@ using Robust.Shared.GameStates; using Robust.Shared.IoC; using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; diff --git a/Resources/Locale/en-US/foldable/components/foldable-component.ftl b/Resources/Locale/en-US/foldable/components/foldable-component.ftl new file mode 100644 index 0000000000..d3e4ecefb5 --- /dev/null +++ b/Resources/Locale/en-US/foldable/components/foldable-component.ftl @@ -0,0 +1,5 @@ +# Foldable + +foldable-deploy-fail = You can't deploy the {$object} here. +fold-verb = Fold +unfold-verb = Unfold diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index f9d3b4f2b3..201928f6d2 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -9,6 +9,7 @@ sprite: Objects/Specific/Medical/Morgue/bodybags.rsi layers: - state: bag + map: ["enum.FoldableVisualLayers.Base"] - state: open_overlay map: ["enum.StorageVisualLayers.Door"] - state: label_overlay @@ -27,13 +28,18 @@ !type:PhysShapeAabb bounds: "-0.5,-0.45,0.5,0.1" mass: 5 + mask: + - Impassable + - SmallImpassable - type: BodyBagEntityStorage CanWeldShut: false Capacity: 1 + IsCollidableWhenOpen: true closeSound: path: /Audio/Misc/zip.ogg openSound: path: /Audio/Misc/zip.ogg + - type: Foldable - type: PaperLabel labelSlot: insertVerbText: Attach Label @@ -45,20 +51,20 @@ visuals: - type: StorageVisualizer state_open: open_overlay - state_closed: bag + - type: FoldableVisualizer + key: bag - type: BodyBagVisualizer - type: Pullable - type: entity - id: BodyBag_Item + id: BodyBag_Folded name: body bag description: A plastic bag designed for the storage and transportation of cadavers. - parent: BaseItem + parent: BodyBag_Container + suffix: Folded components: - - type: Sprite - netsync: false - sprite: Objects/Specific/Medical/Morgue/bodybags.rsi - state: item + - type: Foldable + folded: true # - type: BodyBagItem #TODO: we need some kind of generic placable, like thus: # - type: Placeable # prototype: someId diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index 1ea3b3c08e..10081edb36 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -24,6 +24,7 @@ noRot: true - type: Strap position: Stand + buckleOffset: "0,0.15" - type: Pullable - type: Damageable damageContainer: Inorganic diff --git a/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml new file mode 100644 index 0000000000..524c812043 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Furniture/rollerbeds.yml @@ -0,0 +1,94 @@ +- type: entity + id: RollerBed + parent: BaseItem + name: rollerbed + description: Used to carry patients around without damaging them. + components: + - type: Transform + noRot: true + - type: Item + size: 5 + - type: Sprite + sprite: Structures/Furniture/rollerbeds.rsi + netsync: false + noRot: true + layers: + - state: rollerbed + map: ["enum.FoldableVisualLayers.Base"] + - type: MovedByPressure + - type: DamageOnHighSpeedImpact + soundHit: /Audio/Effects/bang.ogg + - type: InteractionOutline + - type: Physics + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeCircle + radius: 0.35 + mass: 30 + mask: + - Impassable + - SmallImpassable + layer: + - Opaque + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 1 + - type: Pullable + - type: Strap + position: Down + rotation: -90 + buckleOffset: "0,0.15" + unbuckleOffset: "0,0.15" + - type: Foldable + - type: Appearance + visuals: + - type: FoldableVisualizer + key: rollerbed + - type: RollerbedVisualizer + key: rollerbed + +- type: entity + id: CheapRollerBed + name: rollerbed + parent: RollerBed + description: A run-down rollerbed. Used to carry patients around. + components: + - type: Sprite + layers: + - state: cheap_rollerbed + map: [ "enum.FoldableVisualLayers.Base" ] + - type: Appearance + visuals: + - type: FoldableVisualizer + key: cheap_rollerbed + - type: RollerbedVisualizer + key: cheap_rollerbed + +- type: entity + id: EmergencyRollerBed + name: rollerbed + parent: RollerBed + description: A robust looking rollerbed used for emergencies. + components: + - type: Sprite + layers: + - state: emergency_rollerbed + map: [ "enum.FoldableVisualLayers.Base" ] + - type: Appearance + visuals: + - type: FoldableVisualizer + key: emergency_rollerbed + - type: RollerbedVisualizer + key: emergency_rollerbed diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml index d8073e3104..e2b05bd992 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml @@ -8,6 +8,9 @@ visuals: - type: StorageVisualizer state: cabinet + state_open: cabinet_open + state_closed: cabinet_door + - type: AccessReader access: [["Bar"]] - type: EntityStorage @@ -26,6 +29,8 @@ visuals: - type: StorageVisualizer state: qm + state_open: qm_open + state_closed: qm_door - type: AccessReader access: [["Cargo"]] # TODO access [["Quartermaster"]] @@ -39,6 +44,8 @@ visuals: - type: StorageVisualizer state: cap + state_open: cap_open + state_closed: cap_door - type: AccessReader access: [["Captain"]] @@ -51,6 +58,8 @@ visuals: - type: StorageVisualizer state: hop + state_open: hop_open + state_closed: hop_door - type: AccessReader access: [["HeadOfPersonnel"]] @@ -64,6 +73,8 @@ visuals: - type: StorageVisualizer state: ce + state_open: ce_open + state_closed: ce_door - type: AccessReader access: [ [ "Engineering", "Command" ] ] @@ -77,6 +88,7 @@ visuals: - type: StorageVisualizer state: eng + state_open: eng_open state_closed: eng_elec_door - type: AccessReader access: [ [ "Engineering" ] ] @@ -91,6 +103,7 @@ visuals: - type: StorageVisualizer state: eng + state_open: eng_open state_closed: eng_weld_door - type: AccessReader access: [ [ "Engineering" ] ] @@ -105,6 +118,8 @@ visuals: - type: StorageVisualizer state: atmos + state_open: atmos_open + state_closed: atmos_door - type: AccessReader access: [ [ "Engineering" ] ] @@ -118,6 +133,8 @@ visuals: - type: StorageVisualizer state: eng_secure + state_open: eng_secure_open + state_closed: eng_secure_door - type: AccessReader access: [ [ "Engineering" ] ] @@ -131,6 +148,8 @@ visuals: - type: StorageVisualizer state: freezer + state_open: freezer_open + state_closed: freezer_door - type: AccessReader access: [ [ "Service" ] ] @@ -144,6 +163,8 @@ visuals: - type: StorageVisualizer state: hydro + state_open: hydro_open + state_closed: hydro_door - type: AccessReader access: [ [ "Service" ] ] @@ -158,6 +179,8 @@ visuals: - type: StorageVisualizer state: med + state_open: med_open + state_closed: med_door - type: AccessReader access: [ [ "Medical" ] ] @@ -171,6 +194,8 @@ visuals: - type: StorageVisualizer state: med_secure + state_open: med_secure_open + state_closed: med_secure_door - type: AccessReader access: [ [ "Medical" ] ] @@ -184,6 +209,7 @@ visuals: - type: StorageVisualizer state: med + state_open: med_open state_closed: chemical_door - type: AccessReader access: [ [ "Chemistry" ] ] @@ -198,6 +224,8 @@ visuals: - type: StorageVisualizer state: cmo + state_open: cmo_open + state_closed: cmo_door - type: AccessReader access: [ [ "Medical", "Command" ] ] @@ -211,6 +239,8 @@ visuals: - type: StorageVisualizer state: rd + state_open: rd_open + state_closed: rd_door - type: AccessReader access: [ [ "Research", "Command" ] ] @@ -223,6 +253,8 @@ visuals: - type: StorageVisualizer state: science + state_open: science_open + state_closed: science_door - type: AccessReader access: [ [ "Research" ] ] @@ -236,6 +268,8 @@ visuals: - type: StorageVisualizer state: hos + state_open: hos_open + state_closed: hos_door - type: AccessReader access: [["Security", "Command"]] @@ -249,6 +283,8 @@ visuals: - type: StorageVisualizer state: warden + state_open: warden_open + state_closed: warden_door - type: AccessReader access: [["Security", "Armory"]] # TODO access [["Brig"]] @@ -262,6 +298,8 @@ visuals: - type: StorageVisualizer state: sec + state_open: sec_open + state_closed: sec_door - type: AccessReader access: [["Security"]] @@ -286,3 +324,5 @@ visuals: - type: StorageVisualizer state: syndicate + state_open: syndicate_open + state_closed: syndicate_door diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml index 4df4cb70cb..a68b891b68 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml @@ -65,5 +65,6 @@ - type: Appearance visuals: - type: StorageVisualizer + state: generic state_open: generic_open state_closed: generic_door diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/closets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/closets.yml index 41c491a005..0deada2727 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/closets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/closets.yml @@ -9,6 +9,7 @@ visuals: - type: StorageVisualizer state: eng + state_open: eng_open state_closed: eng_tool_door # Radiation suit closet @@ -22,6 +23,7 @@ visuals: - type: StorageVisualizer state: eng + state_open: eng_open state_closed: eng_rad_door # Emergency closet @@ -35,6 +37,8 @@ visuals: - type: StorageVisualizer state: emergency + state_open: emergency_open + state_closed: emergency_door # Fire safety closet - type: entity @@ -47,6 +51,8 @@ visuals: - type: StorageVisualizer state: fire + state_open: fire_open + state_closed: fire_door # EOD closet - type: entity @@ -59,6 +65,8 @@ visuals: - type: StorageVisualizer state: bomb + state_open: bomb_open + state_closed: bomb_door # Biohazard @@ -73,6 +81,8 @@ visuals: - type: StorageVisualizer state: bio + state_open: bio_sec_open + false: bio_sec_door # Virology variant - type: entity @@ -83,6 +93,8 @@ visuals: - type: StorageVisualizer state: bio_viro + state_open: bio_viro_open + state_closed: bio_viro_door # Security variant - type: entity @@ -93,6 +105,8 @@ visuals: - type: StorageVisualizer state: bio_sec + state_open: bio_sec_open + state_closed: bio_sec_door # Janitor variant - type: entity @@ -103,11 +117,13 @@ visuals: - type: StorageVisualizer state: bio_jan + state_open: bio_jan_open + state_closed: bio_jan_door # Maintenance closet - type: entity id: ClosetMaintenance - name: maintenance closet + name: maintenance closet parent: ClosetBase description: It's a storage unit. components: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/wardrobe.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/wardrobe.yml index c288d5641a..4404185472 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/wardrobe.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/wardrobe.yml @@ -17,6 +17,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: blue_door # Pink wardrobe @@ -29,6 +30,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: pink_door # Black wardrobe @@ -41,6 +43,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: black_door # Green wardrobe @@ -53,6 +56,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: green_door # Prison wardrobe @@ -65,6 +69,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: orange_door # Yellow wardrobe @@ -77,6 +82,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: yellow_door # White wardrobe @@ -89,6 +95,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: white_door # Grey wardrobe @@ -101,6 +108,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: grey_door # Mixed wardrobe @@ -113,6 +121,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: mixed_door # Jobs @@ -126,6 +135,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: red_door - type: entity @@ -137,6 +147,7 @@ visuals: - type: StorageVisualizer state: generic + state_open: generic_open state_closed: atmos_wardrobe_door - type: entity diff --git a/Resources/Prototypes/Recipes/Lathes/medical.yml b/Resources/Prototypes/Recipes/Lathes/medical.yml index 05d6931950..24d6431f47 100644 --- a/Resources/Prototypes/Recipes/Lathes/medical.yml +++ b/Resources/Prototypes/Recipes/Lathes/medical.yml @@ -73,9 +73,9 @@ Steel: 200 - type: latheRecipe - id: BodyBag_Item - icon: Objects/Specific/Medical/Morgue/bodybags.rsi/item.png - result: BodyBag_Item + id: BodyBag_Folded + icon: Objects/Specific/Medical/Morgue/bodybags.rsi/bag_folded.png + result: BodyBag_Folded completetime: 300 materials: Plastic: 200 diff --git a/Resources/Textures/Interface/VerbIcons/fold.svg b/Resources/Textures/Interface/VerbIcons/fold.svg new file mode 100644 index 0000000000..b931cd45ae --- /dev/null +++ b/Resources/Textures/Interface/VerbIcons/fold.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png b/Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png new file mode 100644 index 0000000000000000000000000000000000000000..c0afa2c5259406986825094cda1acc06c3e6ca05 GIT binary patch literal 2619 zcmai0dt4J&8odechZF@7rP45f*dj>?f-)o^COiTJ0Z|^JNeB}dLNYNKOwcHZx<#uz zVnKXXx==x>TEyxKuKA&&t|*Eux+;R8#rgtVf5n!lI|&wR)$SiNlY7tk&V1kb?!A+Z zaj_8-tfyH6048uFISIsbp5d}IC+_>v<#zxuZ9o%~@nl{MEW)HzVFs3tP}Nd7fdjw{ zQOkuQ34&A7kxW#^f(DyTK@>ED1tt0O=sYVRx#Yn*=EGU^5M`2?MgyK*2r_!NdYYJ15A%+t;;ctS8 z5ev$~aXCz*sZ=Ve%8!aEGHJenfq^tSgT`R^5DXt>o(vbNePl{^gT$By2T_U?s2oQz z8O5L}OviF@76cJE<&8L^M&GK-lyAx>jG!41nlF`3`y(Ak#UG&?koV~FEDXn#S(tph zfOlRo4!;*j*!STOwNU;cGLQGybgA^6GL(4O3c`ptroNNY?=Mg$=E)IS0;0rn6(S^T z1tP=UjZPSRf#Xm$l9S9qrHD*PxXXe9X8#FH`3T6yaxle0Vo@P1$k!NSa1Q25g_%ea znt^AHYrUP1L1dYK1`L_y)Rg^I-}VP_tN*g9yY z3{g;gsdK4gR*c7}vJgV=x!;px(%ws-X(aq%lM-=bbHwH+P7&JpF+vQ+ z4hOR@<9p=FRo-nMFIdJ@$Ti&uAqL-GqqQlbX&1UA3B|D_O^Fbv}CzoMw#5`)d{~ zPP{Opzt>(`o)#u9Cr|VCh}53;%wD$toJVU|$%V*x`snLphgNE?EZKkOp2e-L!sc9d zx0BE;~U9Cm=c6!UUR({XH$9|V| zj)E!W?YkTn@3}*+jQY>Pr7JXG4cjE&=aBi|YHEWf+*ra4>N_6Zq9W_NYaTLBn$NY; zo6Ir`uBZPb5qMuoV|Vxaez&TCt-BpnWx~^?_cE_6J9Mbi(WL0ORU_GiQQK5o{q!5% z2-ka44_4tc#T^;}&{MLvBxShr#LI%+FQVH#H$URrz6{@NcLYEuhIjTpFmJn+X8WtG zMgJ3t<5;jzH!!trPNQ?SYE#}L>%DcyAdy`A9ruK#-Y%y0D0nr}BIeHV_`YnmhiJ>| zt3@CREyJDWTErX-aDLsNwXgb-c1`K?__o7d+8-ltZrh*>x3C|ssphXeRgiMuVr_fD zYAx)!+N&-c|2Kh znRPie?hc8wxg2kNaiT*ySW$gR`wKj<$3LoQ5lBG#w|PpnxGr#{;VLxCWadC&^%kvN z(7>|${&l&a-E((EBfDebK$;sysvxD6&!(1KV{UAgty}I`e<}J$QuCDcpx!Lmfqd9W zz_Zk)7WlgX390KtlP3iNr?6Kl5;#&I(%x*S&3w5p>x-e1wo}^1s1Dm`H)TPwi`(q4P8`U%UZPY z?*-j8adwC8d;AiU4AlF&C+mmJdNcQ)?T|paX2%0lu5QHYq+b6JKI02Q=yz`Nvxj!x zula)1Z0hRqX+G&OsWo}D&PB6Czv1gl&Y6XRAo{;j^Tohn_{lRa69kk-oZB~9r`A}c zRGoRj(g)LTr1E9p8*;?Z^s4QeeV>?;*UqEZTXvq8SbN@;0mqgU!+$<*SS;t@d_m#= E0Cd{ncK`qY literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png.yml b/Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png.yml new file mode 100644 index 0000000000..5c43e23305 --- /dev/null +++ b/Resources/Textures/Interface/VerbIcons/fold.svg.192dpi.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true diff --git a/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/item.png b/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/bag_folded.png similarity index 100% rename from Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/item.png rename to Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/bag_folded.png diff --git a/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/meta.json b/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/meta.json index fab67ad463..b6feb49959 100644 --- a/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Medical/Morgue/bodybags.rsi/meta.json @@ -11,7 +11,7 @@ "name": "bag" }, { - "name": "item" + "name": "bag_folded" }, { "name": "label_overlay" diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed.png new file mode 100644 index 0000000000000000000000000000000000000000..c5dbd975b9736fb72d3b88845eec05738696959e GIT binary patch literal 326 zcmV-M0lEH(P)f@5TNq>PJkQ>R@;pD4*Y`c*I0mJZ0KokyUzWwYfwMS=F~(9# z$xR4hj~iFuTtWzYyUhB6(7@h+*7`E((RFtV&N-A)-bJ%4J1ys&@83iSVHsl|f(e=kqIiFbf$eZ4Ndm1kq?BG0`Hs4-cgLUM Y4W(pg3D@y#rT_o{07*qoM6N<$f^zAKn*aa+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_buckled.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_buckled.png new file mode 100644 index 0000000000000000000000000000000000000000..61330875a56334ad9e5008c9c7052a62a96a9170 GIT binary patch literal 490 zcmVaBksZRvVS(LE z8eV1W@q2H^BO8DjGiJ<~@nH}g6h)z~*Xv{=O6j0DDJ3ix3$SgQ005YE@!Rb-*}zbs zMo|>Xwrygx7v6!omeCXU7R&}J16h{6O|-6M;vfhD;G9n;U9Z=J#e*QIzDXE{%5j{= zl&Q%^3^8Caeig44y>~4x<;PoWpxDG?UuxGtfZ8k zP51j9eBbYF*vsVt007J7Qk%$TvjKp|jTuD|5kfp~LPQirq`eVMNhuq|l+w!7;czJH z#!*CPWWV1xzD-?FpD7^(LBYByG~{`nYK!z?^gZBtp2Ey2rPU*Z;$!)KtbndBk|b%A zIgVqMBuU8_t77_&;iUncn3PgWRxfjV4S5)2or<)%Dg#0Yf|=<$9=moR4Bz)Vlh`}h zM*!bHBw-kiI=l1v{Bq5*tie3H-R_xGnx={|rqVPW-AF^B(=f5L$Kw$!%lg+xDa*31 gh7f{`Jl{XX7e0*S%_@ZHTmS$707*qoM6N<$f_yvPwEzGB literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_folded.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/cheap_rollerbed_folded.png new file mode 100644 index 0000000000000000000000000000000000000000..c0a7bec080a4be5dbf560faea1792532dcca6f78 GIT binary patch literal 403 zcmV;E0c`$>P)3sO4uS4dfQ3gufoy`RYpRf>xJlOF`UJ=AiA%{{(x0Uq z!Ss`x*_kghy8}HvJv}`=J#WUb4a~C4*um9Ce|oDxk|Y2`QDiMp;y4cb z{l2?Ek|b!Yna}5(PN&);B7!m1(+b0o)oN8Q*{BCBmrDabbM-v$PvJVMWHy^k#e&P_f`~jP0L?!_L@LjeQUC)Hxjiiq1cCWIf=8$; x{xae?HbD@WIF4KQ$V*mnp67U;_t5Tm8{fTai!F4cR(=2g002ovPDHLkV1iXdxMKhS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed.png new file mode 100644 index 0000000000000000000000000000000000000000..809a1b04996617aaf0a8e17ce65b4f76d64cc71f GIT binary patch literal 449 zcmV;y0Y3hTP)zvdEF>A*yxSrZL2NX4N5eWFDhUs@V!f9dvK0UWio?^%nP=z~!5#91zCr@D**dNu(P`Ip`D9Z`y zf!P6b1QQ|4sSR$OJjI}9ZpJX}!)=5E=w&&&Bj64gNHFSv!QlYpL_rULoak8?7#J9` z1XLNOK^;MCZuq=tHHH{(Tqx0&!^#1&O2V_*r3?%V3=GCoyW#4P#Yid%VG;vc7uZ=i z5M7HsfAx%kfq{WRQcQ|0d1P?t!~sT>`WqGsFrey{z+kV2*=9hlc42J*Y+|IC$uMWa zg8!;YYX9vl9RAx`IQ&0&i{bylTMQ)E@1&XuF9%?8!oYwOPe^f24j{%%l%P;mQu~h_ rch6rvqqvzx$V{T*mr_6rGpPmuanJ0h44Nmu00000NkvXXu0mjf{HeR} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_buckled.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_buckled.png new file mode 100644 index 0000000000000000000000000000000000000000..afad4c3fe014f4e6ad9ac6089dcafd8ac56a7fc9 GIT binary patch literal 618 zcmV-w0+s!VP)PMH3OOVmLcx;= z;>927rAvX0!F-eX5qBqvM4`S*mTzX>d-?X8Z+3ut{O^c#y3mQb zT#xxbSjT*Ai|Ynj#cUuP7q*KW0CKNAx%fw!m2^GxwCP_b<99( zp1Nw5b)ASD%-4OmlM@Q*%aLc;{eB>RZ4k7ERcn|Za6l#^x;U%W48pDSIu^@oR^nl6 zNP|rDg^AxZShWUsasv6f-!#xGaovP4aGSU{a5oIdMbQh$Mc)qq^8*g@4HLGz;qTtQ z5qpq%ZY@rIprcOs_0=)}VC>x+F;9-Q)d^`pHUTuUQuncyUPm`)!D4w$a1k$wiwwkL z3FQ>aq&z_e0K-EM#q*zw-$qP^JWkJKc<)0|nfvkcc{2m)WVYo|`sLdv6pk4H;Qdlo z#0cY~PmCDN&&|4GTu1q^)XYGb2>^KUwq(S}P|#SAxM3j7#C4{E#Dc_u#x}G8rI^wy z3(FaxLcK2aIs#w8^vsk}jJBk5J*+IO;`HQ98E^Rt(#b6Ub@|gE%cMMmz!uXpQ%2+J+KoJuO3sLS=X+wE;9jME^OZ#Oq})e7SL2bTjsz|gK5CIA2c07*qoM6N<$ Eg5t6wssI20 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_folded.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/emergency_rollerbed_folded.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e3a2b82023dbdb92cc578b1e20907c446f341c GIT binary patch literal 582 zcmV-M0=fN(P)*0D!YGaL=O7msYI2w+DWOF9Q(P3gwOpjEl*AsSxX8sxNck5B z}C}WGINF?J~`vG8XVu2GNEJK$3_3b5%XnJ&p^AE3tXuq8ZT{CQXa_$4K zZ!gd_1Cfsy0N^vahww@WrFt**`Hb!X0JY8c1u?!en>J45BZgtO0$6gXu_0w_Y{2cv zBqg;_x4M+}PyJauzH=sF4k)rpSaS2~I-6EUxSI=dd^wYli+}?R`Ma_9bimm=9^WxA zW;jbifF2%XSThiD69GSLBi2zC;B1c10#O#*!PxU7$&Q{(GbV@>hPr{OUEl(ul!neVnKTHbv2Kd*{ UiU+qUX8-^I07*qoM6N<$g4;L@r~m)} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/meta.json b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/meta.json new file mode 100644 index 0000000000..669e74f8e2 --- /dev/null +++ b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/meta.json @@ -0,0 +1,38 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/59fe5dd2841f47a8abce60eecb9fafad34282bd0, Baystation 12 and AuroraStation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "rollerbed" + }, + { + "name": "rollerbed_buckled" + }, + { + "name": "rollerbed_folded" + }, + { + "name": "cheap_rollerbed" + }, + { + "name": "cheap_rollerbed_buckled" + }, + { + "name": "cheap_rollerbed_folded" + }, + { + "name": "emergency_rollerbed" + }, + { + "name": "emergency_rollerbed_buckled" + }, + { + "name": "emergency_rollerbed_folded" + } + ] +} diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed.png new file mode 100644 index 0000000000000000000000000000000000000000..846341ca498b7fd858760bfd154301746c6c1b4b GIT binary patch literal 402 zcmV;D0d4+?P)!VdD`55d{7R*3up%(KR@@+aS`P5JaO}9S4y#q)tL} zXD&?^L0pq^gWi3ofQACC+)tZ;fXCoOuKeZ^Iore0W zqK1v@n@9n+cQQhA3P5(Z>_u{45Ut0Gq85wCUVq)BVCWNvY{#8?7DkZPc3g`3z*7MV zhK}vH69t{2r44>4gk;$u|gU;&G9p=#8kgP)Hn)(8Xc5MwYHQW(FpbRrM=Ak zC^0Q@39y;jvIg%T9Br&}+xw+nigVKVBAH&BYr! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_buckled.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_buckled.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf05429e086a45b9c85bba9001c8f12a6a716fb GIT binary patch literal 565 zcmV-50?Pe~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0m?~4K~z{rV;BXa zU=$2AV1&|mL2Kuf|7I4ZP#$sM)QQs!)#W(^%_rIc7tdaT@`wZa#(Km%z|^k#KbS{n zaQaXyBV$-t+W(iz(G0fM5>R1OaQNs8oN|N!KD{70@w-bIzz$H0D+UW-1K*DBV&JlN zgYrlN`1FDtc56{D0~3@#U|`e%qYfBw2N0DF1H2^}$SI09Y<*5J8xmCz)p&3)RMl>R ziVz1tj^6b_mtaA}0_Eck0R|60Fq_x{39JW7A7;R>2OI+TUx-4v*g;#fA6X#)iUNE< zQQ|cNBdDf>@&^QfLjcMi5CE=@O)PA|j<|B^as!Bl0Y9Ix22i~Y0-*N5rY);b!r8KfZlvggXF4 zi;Idk1gkMKtiAP@VP+~PL;CFRa1G=FkmcxRzI^=>>{*Zl;3Xk404dyc@E4ekD`64~ zK%N58$Yvq~a0q|^awvcWfB@!FN&z-ALB3~TU|;|MUw;JYlCioS00000NkvXXu0mjf DAE(s8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_folded.png b/Resources/Textures/Structures/Furniture/rollerbeds.rsi/rollerbed_folded.png new file mode 100644 index 0000000000000000000000000000000000000000..5783eaef98ff83a0ade2515e6e4eedd70537ee58 GIT binary patch literal 401 zcmV;C0dD?@P)i-Gp zA?QMwkCfyz@v6J`=sLse=dTzvz%Oui3M04fSizM4XBz3hol2osBPf-^(*1*z`$^V>am6ZF$D-VFl*Xm z2IO*J*0jk4^$;Bb7tdb8D}V3NbvQeH_IHMvshkXJZ+%A*#|Civ6uAr_WC$?;SEynQ z0a!Lfwm2{_oWab(lq5?}oj8q>CWv+b0|NuRIE4W-3sZ*5@)D99KujVeITsMB6JUVY zXv67%dylR&U`qqkNDs(>s6fdw?8(+zNX5@FvyGr#b)tK1qQ-SXS7;00000NkvXXu0mjf`r)bc literal 0 HcmV?d00001 From 7c8812954085dde2850a84135579317e2faa1c3d Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 28 Dec 2021 23:58:24 -0500 Subject: [PATCH 05/12] Automatic changelog update --- Resources/Changelog/Changelog.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 9d7a3a3ec1..b1eadf0323 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - {message: Shuttle-relative movement for when we get shuttle rotation., type: Add} - id: 284 - time: '2021-07-25T15:48:22.0000000+00:00' - author: Seth changes: - {message: Added Storage Room to Coats, type: Add} @@ -2874,3 +2869,8 @@ Entries: for a role prompt!, type: Add} id: 785 time: '2021-12-29T03:58:49.0000000+00:00' +- author: Topy + changes: + - {message: Add rollerbeds to roll people around!, type: Add} + id: 786 + time: '2021-12-29T04:57:21.0000000+00:00' From 1705eae96c1f30c12cceee832ba4289c008e7d68 Mon Sep 17 00:00:00 2001 From: Alex Evgrashin Date: Wed, 29 Dec 2021 08:19:00 +0300 Subject: [PATCH 06/12] Suit sensor and crew monitoring (#5521) Co-authored-by: Paul Ritter Co-authored-by: metalgearsloth --- Content.Client/Entry/IgnoredComponents.cs | 2 + .../CrewMonitoringBoundUserInterface.cs | 44 +++ .../CrewMonitoring/CrewMonitoringWindow.xaml | 23 ++ .../CrewMonitoringWindow.xaml.cs | 87 +++++ Content.Server/Access/Systems/IdCardSystem.cs | 24 +- .../DeviceNetwork/DeviceNetworkConstants.cs | 6 + .../CrewMonitoringConsoleComponent.cs | 26 ++ .../CrewMonitoringConsoleSystem.cs | 89 +++++ .../SuitSensors/SuitSensorComponent.cs | 59 ++++ .../Medical/SuitSensors/SuitSensorSystem.cs | 312 ++++++++++++++++++ .../CrewMonitoring/CrewMonitoringShared.cs | 28 ++ .../Medical/SuitSensor/SharedSuitSensor.cs | 58 ++++ Content.Shared/Verbs/VerbCategory.cs | 2 + .../components/crew-monitoring-component.ftl | 13 + .../components/suit-sensor-component.ftl | 21 ++ Resources/Locale/en-US/verbs/verb-system.ftl | 1 + .../Catalog/Research/technologies.yml | 1 + .../Uniforms/base_clothinguniforms.yml | 13 +- .../Entities/Clothing/Uniforms/jumpskirts.yml | 4 + .../Entities/Clothing/Uniforms/jumpsuits.yml | 4 + .../Devices/Circuitboards/computer.yml | 8 + .../Machines/Computers/computers.yml | 30 ++ .../Entities/Structures/Machines/lathe.yml | 1 + 23 files changed, 845 insertions(+), 11 deletions(-) create mode 100644 Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs create mode 100644 Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml create mode 100644 Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs create mode 100644 Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleComponent.cs create mode 100644 Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs create mode 100644 Content.Server/Medical/SuitSensors/SuitSensorComponent.cs create mode 100644 Content.Server/Medical/SuitSensors/SuitSensorSystem.cs create mode 100644 Content.Shared/Medical/CrewMonitoring/CrewMonitoringShared.cs create mode 100644 Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs create mode 100644 Resources/Locale/en-US/medical/components/crew-monitoring-component.ftl create mode 100644 Resources/Locale/en-US/medical/components/suit-sensor-component.ftl diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 452f5be09f..c9c3d8df14 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -308,6 +308,8 @@ namespace Content.Client.Entry "ExtensionCableReceiver", "ExtensionCableProvider", "ApcNetworkConnection", + "SuitSensor", + "CrewMonitoringConsole", "ApcNetSwitch", "HandLabeler", "Label", diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs new file mode 100644 index 0000000000..030ce917c6 --- /dev/null +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringBoundUserInterface.cs @@ -0,0 +1,44 @@ +using Content.Shared.Medical.CrewMonitoring; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; + +namespace Content.Client.Medical.CrewMonitoring +{ + public class CrewMonitoringBoundUserInterface : BoundUserInterface + { + private CrewMonitoringWindow? _menu; + + public CrewMonitoringBoundUserInterface([NotNull] ClientUserInterfaceComponent owner, [NotNull] object uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + _menu = new CrewMonitoringWindow(); + _menu.OpenCentered(); + _menu.OnClose += Close; + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + switch (state) + { + case CrewMonitoringState st: + _menu?.ShowSensors(st.Sensors); + break; + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } + } +} diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml new file mode 100644 index 0000000000..d0d153f9d3 --- /dev/null +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs new file mode 100644 index 0000000000..1d5c13caf6 --- /dev/null +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; +using Content.Shared.Medical.SuitSensor; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Localization; + +namespace Content.Client.Medical.CrewMonitoring +{ + [GenerateTypedNameReferences] + public partial class CrewMonitoringWindow : SS14Window + { + private List _rowsContent = new(); + + public CrewMonitoringWindow() + { + RobustXamlLoader.Load(this); + } + + public void ShowSensors(List stSensors) + { + ClearAllSensors(); + + // add a row for each sensor + foreach (var sensor in stSensors) + { + // add users name and job + // format: UserName (Job) + var nameLabel = new Label() + { + Text = $"{sensor.Name} ({sensor.Job})" + }; + SensorsTable.AddChild(nameLabel); + _rowsContent.Add(nameLabel); + + // add users status and damage + // format: IsAlive (TotalDamage) + var statusText = Loc.GetString(sensor.IsAlive ? + "crew-monitoring-user-interface-alive" : + "crew-monitoring-user-interface-dead"); + if (sensor.TotalDamage != null) + { + statusText += $" ({sensor.TotalDamage})"; + } + var statusLabel = new Label() + { + Text = statusText + }; + SensorsTable.AddChild(statusLabel); + _rowsContent.Add(statusLabel); + + // add users positions + // format: (x, y) + string posText; + if (sensor.Coordinates != null) + { + // todo: add locations names (kitchen, bridge, etc) + var pos = sensor.Coordinates.Value.Position; + var x = (int) pos.X; + var y = (int) pos.Y; + posText = $"({x}, {y})"; + } + else + { + posText = Loc.GetString("crew-monitoring-user-interface-no-info"); + } + var posLabel = new Label() + { + Text = posText + }; + SensorsTable.AddChild(posLabel); + _rowsContent.Add(posLabel); + } + } + + private void ClearAllSensors() + { + foreach (var child in _rowsContent) + { + SensorsTable.RemoveChild(child); + } + _rowsContent.Clear(); + } + } +} diff --git a/Content.Server/Access/Systems/IdCardSystem.cs b/Content.Server/Access/Systems/IdCardSystem.cs index c1bcaff58e..01ebef2251 100644 --- a/Content.Server/Access/Systems/IdCardSystem.cs +++ b/Content.Server/Access/Systems/IdCardSystem.cs @@ -101,22 +101,14 @@ namespace Content.Server.Access.Systems return true; // check inventory slot? - if (EntityManager.TryGetComponent(uid, out InventoryComponent? inventoryComponent) && - inventoryComponent.HasSlot(EquipmentSlotDefines.Slots.IDCARD) && - inventoryComponent.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent? item) && - TryGetIdCard(item.Owner, out idCard)) - { - return true; - } - - return false; + return TryGetIdCardSlot(uid, out idCard); } /// /// Attempt to get an id card component from an entity, either by getting it directly from the entity, or by /// getting the contained id from a . /// - private bool TryGetIdCard(EntityUid uid, [NotNullWhen(true)] out IdCardComponent? idCard) + public bool TryGetIdCard(EntityUid uid, [NotNullWhen(true)] out IdCardComponent? idCard) { if (EntityManager.TryGetComponent(uid, out idCard)) return true; @@ -129,5 +121,17 @@ namespace Content.Server.Access.Systems return false; } + + /// + /// Try get id card from mobs ID inventory slot + /// + public bool TryGetIdCardSlot(EntityUid uid, [NotNullWhen(true)] out IdCardComponent? idCard) + { + idCard = null; + return EntityManager.TryGetComponent(uid, out InventoryComponent? inventoryComponent) && + inventoryComponent.HasSlot(EquipmentSlotDefines.Slots.IDCARD) && + inventoryComponent.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent? item) && + TryGetIdCard(item.Owner, out idCard); + } } } diff --git a/Content.Server/DeviceNetwork/DeviceNetworkConstants.cs b/Content.Server/DeviceNetwork/DeviceNetworkConstants.cs index 6136a210ae..b8d53ee423 100644 --- a/Content.Server/DeviceNetwork/DeviceNetworkConstants.cs +++ b/Content.Server/DeviceNetwork/DeviceNetworkConstants.cs @@ -24,6 +24,12 @@ namespace Content.Server.DeviceNetwork /// public const string CmdSetState = "set_state"; + /// + /// The command for a device that just updated its state + /// E.g. suit sensors broadcasting owners vitals state + /// + public const string CmdUpdatedState = "updated_state"; + #endregion #region SetState diff --git a/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleComponent.cs b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleComponent.cs new file mode 100644 index 0000000000..0b98d4e362 --- /dev/null +++ b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleComponent.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Content.Shared.Medical.SuitSensor; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Medical.CrewMonitoring +{ + [RegisterComponent] + [Friend(typeof(CrewMonitoringConsoleSystem))] + public class CrewMonitoringConsoleComponent : Component + { + public override string Name => "CrewMonitoringConsole"; + + /// + /// List of all currently connected sensors to this console. + /// + public Dictionary ConnectedSensors = new(); + + /// + /// After what time sensor consider to be lost. + /// + [DataField("sensorTimeout")] + public float SensorTimeout = 10f; + } +} diff --git a/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs new file mode 100644 index 0000000000..607b1939ec --- /dev/null +++ b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs @@ -0,0 +1,89 @@ +using System.Linq; +using Content.Server.DeviceNetwork.Systems; +using Content.Server.Medical.SuitSensors; +using Content.Server.UserInterface; +using Content.Shared.Medical.CrewMonitoring; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Timing; + +namespace Content.Server.Medical.CrewMonitoring +{ + public class CrewMonitoringConsoleSystem : EntitySystem + { + [Dependency] private readonly SuitSensorSystem _sensors = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + + private const float UpdateRate = 3f; + private float _updateDif; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnPacketReceived); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // check update rate + _updateDif += frameTime; + if (_updateDif < UpdateRate) + return; + _updateDif = 0f; + + var consoles = EntityManager.EntityQuery(); + foreach (var console in consoles) + { + UpdateTimeouts(console.Owner, console); + UpdateUserInterface(console.Owner, console); + } + } + + private void OnRemove(EntityUid uid, CrewMonitoringConsoleComponent component, ComponentRemove args) + { + component.ConnectedSensors.Clear(); + } + + private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent component, PacketSentEvent args) + { + var suitSensor = _sensors.PacketToSuitSensor(args.Data); + if (suitSensor == null) + return; + + suitSensor.Timestamp = _gameTiming.CurTime; + component.ConnectedSensors[args.SenderAddress] = suitSensor; + } + + private void UpdateUserInterface(EntityUid uid, CrewMonitoringConsoleComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + var ui = component.Owner.GetUIOrNull(CrewMonitoringUIKey.Key); + if (ui == null) + return; + + // update all sensors info + var allSensors = component.ConnectedSensors.Values.ToList(); + var uiState = new CrewMonitoringState(allSensors); + ui.SetState(uiState); + } + + private void UpdateTimeouts(EntityUid uid, CrewMonitoringConsoleComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + foreach (var (address, sensor) in component.ConnectedSensors) + { + // if too many time passed - sensor just dropped connection + var dif = _gameTiming.CurTime - sensor.Timestamp; + if (dif.Seconds > component.SensorTimeout) + component.ConnectedSensors.Remove(address); + } + } + } +} diff --git a/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs b/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs new file mode 100644 index 0000000000..f5273fa553 --- /dev/null +++ b/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs @@ -0,0 +1,59 @@ +using System; +using Content.Shared.Inventory; +using Content.Shared.Medical.SuitSensor; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Medical.SuitSensors +{ + /// + /// Tracking device, embedded in almost all uniforms and jumpsuits. + /// If enabled, will report to crew monitoring console owners position and status. + /// + [RegisterComponent] + [Friend(typeof(SuitSensorSystem))] + [ComponentProtoName("SuitSensor")] + public sealed class SuitSensorComponent : Component + { + /// + /// Choose a random sensor mode when item is spawned. + /// + [DataField("randomMode")] + public bool RandomMode = true; + + /// + /// If true user can't change suit sensor mode + /// + [DataField("controlsLocked")] + public bool ControlsLocked = false; + + /// + /// Current sensor mode. Can be switched by user verbs. + /// + [DataField("mode")] + public SuitSensorMode Mode = SuitSensorMode.SensorOff; + + /// + /// Activate sensor if user wear it in this slot. + /// + [DataField("activationSlot")] + public EquipmentSlotDefines.Slots ActivationSlot = EquipmentSlotDefines.Slots.INNERCLOTHING; + + /// + /// How often does sensor update its owners status (in seconds). + /// + [DataField("updateRate")] + public float UpdateRate = 2f; + + /// + /// Current user that wears suit sensor. Null if nobody wearing it. + /// + public EntityUid? User = null; + + /// + /// Last time when sensor updated owners status + /// + public TimeSpan LastUpdate = TimeSpan.Zero; + } +} diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs new file mode 100644 index 0000000000..e48fded7f4 --- /dev/null +++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs @@ -0,0 +1,312 @@ +using System; +using Content.Server.Access.Systems; +using Content.Server.DeviceNetwork; +using Content.Server.DeviceNetwork.Components; +using Content.Server.DeviceNetwork.Systems; +using Content.Server.Popups; +using Content.Shared.ActionBlocker; +using Content.Shared.Damage; +using Content.Shared.Examine; +using Content.Shared.Inventory; +using Content.Shared.Medical.SuitSensor; +using Content.Shared.MobState.Components; +using Content.Shared.Verbs; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Map; +using Robust.Shared.Player; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Medical.SuitSensors +{ + public class SuitSensorSystem : EntitySystem + { + [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IdCardSystem _idCardSystem = default!; + [Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + + private const float UpdateRate = 0.5f; + private float _updateDif; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnVerb); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // check update rate + _updateDif += frameTime; + if (_updateDif < UpdateRate) + return; + + _updateDif -= UpdateRate; + + var curTime = _gameTiming.CurTime; + var sensors = EntityManager.EntityQuery(); + foreach (var (sensor, device) in sensors) + { + // check if sensor is ready to update + if (curTime - sensor.LastUpdate < TimeSpan.FromSeconds(sensor.UpdateRate)) + continue; + sensor.LastUpdate = curTime; + + // get sensor status + var status = GetSensorState(sensor.Owner, sensor); + if (status == null) + continue; + + // broadcast it to device network + var payload = SuitSensorToPacket(status); + _deviceNetworkSystem.QueuePacket(sensor.Owner, DeviceNetworkConstants.NullAddress, device.Frequency, payload, true); + } + } + + private void OnMapInit(EntityUid uid, SuitSensorComponent component, MapInitEvent args) + { + // generate random mode + if (component.RandomMode) + { + //make the sensor mode favor higher levels, except coords. + var modesDist = new[] + { + SuitSensorMode.SensorOff, + SuitSensorMode.SensorBinary, SuitSensorMode.SensorBinary, + SuitSensorMode.SensorVitals, SuitSensorMode.SensorVitals, SuitSensorMode.SensorVitals, + SuitSensorMode.SensorCords, SuitSensorMode.SensorCords + }; + component.Mode = _random.Pick(modesDist); + } + } + + private void OnEquipped(EntityUid uid, SuitSensorComponent component, EquippedEvent args) + { + if (args.Slot != component.ActivationSlot) + return; + + component.User = args.User; + } + + private void OnUnequipped(EntityUid uid, SuitSensorComponent component, UnequippedEvent args) + { + if (args.Slot != component.ActivationSlot) + return; + + component.User = null; + } + + private void OnExamine(EntityUid uid, SuitSensorComponent component, ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + string msg; + switch (component.Mode) + { + case SuitSensorMode.SensorOff: + msg = "suit-sensor-examine-off"; + break; + case SuitSensorMode.SensorBinary: + msg = "suit-sensor-examine-binary"; + break; + case SuitSensorMode.SensorVitals: + msg = "suit-sensor-examine-vitals"; + break; + case SuitSensorMode.SensorCords: + msg = "suit-sensor-examine-cords"; + break; + default: + return; + } + + args.PushMarkup(Loc.GetString(msg)); + } + + private void OnVerb(EntityUid uid, SuitSensorComponent component, GetInteractionVerbsEvent args) + { + // check if user can change sensor + if (component.ControlsLocked) + return; + + // standard interaction checks + if (!args.CanAccess || !args.CanInteract || !_actionBlockerSystem.CanDrop(args.User)) + return; + + args.Verbs.UnionWith(new[] + { + CreateVerb(uid, component, args.User, SuitSensorMode.SensorOff), + CreateVerb(uid, component, args.User, SuitSensorMode.SensorBinary), + CreateVerb(uid, component, args.User, SuitSensorMode.SensorVitals), + CreateVerb(uid, component, args.User, SuitSensorMode.SensorCords) + }); + } + + private Verb CreateVerb(EntityUid uid, SuitSensorComponent component, EntityUid userUid, SuitSensorMode mode) + { + return new Verb() + { + Text = GetModeName(mode), + Disabled = component.Mode == mode, + Priority = -(int) mode, // sort them in descending order + Category = VerbCategory.SetSensor, + Act = () => SetSensor(uid, mode, userUid, component) + }; + } + + private string GetModeName(SuitSensorMode mode) + { + string name; + switch (mode) + { + case SuitSensorMode.SensorOff: + name = "suit-sensor-mode-off"; + break; + case SuitSensorMode.SensorBinary: + name = "suit-sensor-mode-binary"; + break; + case SuitSensorMode.SensorVitals: + name = "suit-sensor-mode-vitals"; + break; + case SuitSensorMode.SensorCords: + name = "suit-sensor-mode-cords"; + break; + default: + return ""; + } + + return Loc.GetString(name); + } + + public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = null, + SuitSensorComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.Mode = mode; + + if (userUid != null) + { + var msg = Loc.GetString("suit-sensor-mode-state", ("mode", GetModeName(mode))); + _popupSystem.PopupEntity(msg, uid, Filter.Entities(userUid.Value)); + } + } + + public SuitSensorStatus? GetSensorState(EntityUid uid, SuitSensorComponent? sensor = null, TransformComponent? transform = null) + { + if (!Resolve(uid, ref sensor, ref transform)) + return null; + + // check if sensor is enabled and worn by user + if (sensor.Mode == SuitSensorMode.SensorOff || sensor.User == null) + return null; + + // try to get mobs id from ID slot + var userName = Loc.GetString("suit-sensor-component-unknown-name"); + var userJob = Loc.GetString("suit-sensor-component-unknown-job"); + if (_idCardSystem.TryGetIdCardSlot(sensor.User.Value, out var card)) + { + if (card.FullName != null) + userName = card.FullName; + if (card.JobTitle != null) + userJob = card.JobTitle; + } + + // get health mob state + var isAlive = false; + if (EntityManager.TryGetComponent(sensor.User.Value, out MobStateComponent? mobState)) + { + isAlive = mobState.IsAlive(); + } + + // get mob total damage + var totalDamage = 0; + if (EntityManager.TryGetComponent(sensor.User.Value, out DamageableComponent? damageable)) + { + totalDamage = damageable.TotalDamage.Int(); + } + + // finally, form suit sensor status + var status = new SuitSensorStatus(userName, userJob); + switch (sensor.Mode) + { + case SuitSensorMode.SensorBinary: + status.IsAlive = isAlive; + break; + case SuitSensorMode.SensorVitals: + status.IsAlive = isAlive; + status.TotalDamage = totalDamage; + break; + case SuitSensorMode.SensorCords: + status.IsAlive = isAlive; + status.TotalDamage = totalDamage; + status.Coordinates = transform.MapPosition; + break; + } + + return status; + } + + /// + /// Serialize suit sensor status into device network package. + /// + public NetworkPayload SuitSensorToPacket(SuitSensorStatus status) + { + var payload = new NetworkPayload() + { + [DeviceNetworkConstants.Command] = DeviceNetworkConstants.CmdUpdatedState, + [SuitSensorConstants.NET_NAME] = status.Name, + [SuitSensorConstants.NET_JOB] = status.Job, + [SuitSensorConstants.NET_IS_ALIVE] = status.IsAlive, + }; + + if (status.TotalDamage != null) + payload.Add(SuitSensorConstants.NET_TOTAL_DAMAGE, status.TotalDamage); + if (status.Coordinates != null) + payload.Add(SuitSensorConstants.NET_CORDINATES, status.Coordinates); + + return payload; + } + + /// + /// Try to deserialize device network message into suit sensor status + /// + public SuitSensorStatus? PacketToSuitSensor(NetworkPayload payload) + { + // check command + if (!payload.TryGetValue(DeviceNetworkConstants.Command, out string? command)) + return null; + if (command != DeviceNetworkConstants.CmdUpdatedState) + return null; + + // check name, job and alive + if (!payload.TryGetValue(SuitSensorConstants.NET_NAME, out string? name)) return null; + if (!payload.TryGetValue(SuitSensorConstants.NET_JOB, out string? job)) return null; + if (!payload.TryGetValue(SuitSensorConstants.NET_IS_ALIVE, out bool? isAlive)) return null; + + // try get total damage and cords (optionals) + payload.TryGetValue(SuitSensorConstants.NET_TOTAL_DAMAGE, out int? totalDamage); + payload.TryGetValue(SuitSensorConstants.NET_CORDINATES, out MapCoordinates? cords); + + var status = new SuitSensorStatus(name, job) + { + IsAlive = isAlive.Value, + TotalDamage = totalDamage, + Coordinates = cords + }; + return status; + } + } +} diff --git a/Content.Shared/Medical/CrewMonitoring/CrewMonitoringShared.cs b/Content.Shared/Medical/CrewMonitoring/CrewMonitoringShared.cs new file mode 100644 index 0000000000..53f19f1295 --- /dev/null +++ b/Content.Shared/Medical/CrewMonitoring/CrewMonitoringShared.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using Content.Shared.FixedPoint; +using Content.Shared.Medical.SuitSensor; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical.CrewMonitoring +{ + [Serializable, NetSerializable] + public enum CrewMonitoringUIKey + { + Key + } + + [Serializable, NetSerializable] + public class CrewMonitoringState : BoundUserInterfaceState + { + public List Sensors; + + public CrewMonitoringState(List sensors) + { + Sensors = sensors; + } + } + +} diff --git a/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs new file mode 100644 index 0000000000..e717c6dad5 --- /dev/null +++ b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs @@ -0,0 +1,58 @@ +using System; +using Content.Shared.FixedPoint; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Serialization; + +namespace Content.Shared.Medical.SuitSensor +{ + [Serializable, NetSerializable] + public class SuitSensorStatus + { + public SuitSensorStatus(string name, string job) + { + Name = name; + Job = job; + } + + public TimeSpan Timestamp; + public string Name; + public string Job; + public bool IsAlive; + public int? TotalDamage; + public MapCoordinates? Coordinates; + } + + [Serializable, NetSerializable] + public enum SuitSensorMode : byte + { + /// + /// Sensor doesn't send any information about owner + /// + SensorOff = 0, + + /// + /// Sensor sends only binary status (alive/dead) + /// + SensorBinary = 1, + + /// + /// Sensor sends health vitals status + /// + SensorVitals = 2, + + /// + /// Sensor sends vitals status and GPS position + /// + SensorCords = 3 + } + + public static class SuitSensorConstants + { + public const string NET_NAME = "name"; + public const string NET_JOB = "job"; + public const string NET_IS_ALIVE = "alive"; + public const string NET_TOTAL_DAMAGE = "vitals"; + public const string NET_CORDINATES = "cords"; + } +} diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 45ec725028..dbc30eced3 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -57,5 +57,7 @@ namespace Content.Shared.Verbs public static readonly VerbCategory Split = new("verb-categories-split", null); + + public static readonly VerbCategory SetSensor = new("verb-categories-set-sensor", null); } } diff --git a/Resources/Locale/en-US/medical/components/crew-monitoring-component.ftl b/Resources/Locale/en-US/medical/components/crew-monitoring-component.ftl new file mode 100644 index 0000000000..d2f4a95369 --- /dev/null +++ b/Resources/Locale/en-US/medical/components/crew-monitoring-component.ftl @@ -0,0 +1,13 @@ +## UI + +crew-monitoring-user-interface-title = Crew Monitoring + +crew-monitoring-user-interface-name = Name +crew-monitoring-user-interface-status = Status +crew-monitoring-user-interface-location = Location + +crew-monitoring-user-interface-alive = Alive +crew-monitoring-user-interface-dead = Dead +crew-monitoring-user-interface-no-info = N/A + + diff --git a/Resources/Locale/en-US/medical/components/suit-sensor-component.ftl b/Resources/Locale/en-US/medical/components/suit-sensor-component.ftl new file mode 100644 index 0000000000..993e726055 --- /dev/null +++ b/Resources/Locale/en-US/medical/components/suit-sensor-component.ftl @@ -0,0 +1,21 @@ +## Modes + +suit-sensor-mode-off = Off +suit-sensor-mode-binary = Binary +suit-sensor-mode-vitals = Vitals +suit-sensor-mode-cords = Coordinates + +## Popups +suit-sensor-mode-state = Suit sensors: {$mode} + +## Components + +suit-sensor-component-unknown-name = Unknown +suit-sensor-component-unknown-job = No job + +## Examine + +suit-sensor-examine-off = Its sensors appear to be [color=darkred]disabled[/color]. +suit-sensor-examine-binary = Its binary life sensors appear to be enabled. +suit-sensor-examine-vitals = Its vital tracker appears to be enabled. +suit-sensor-examine-cords = Its vital tracker and tracking beacon appear to be enabled. diff --git a/Resources/Locale/en-US/verbs/verb-system.ftl b/Resources/Locale/en-US/verbs/verb-system.ftl index 9508eac7b9..ec9ff7763d 100644 --- a/Resources/Locale/en-US/verbs/verb-system.ftl +++ b/Resources/Locale/en-US/verbs/verb-system.ftl @@ -18,6 +18,7 @@ verb-categories-unbuckle = Unbuckle verb-categories-rotate = Rotate verb-categories-transfer = Set Transfer Amount verb-categories-split = Split +verb-categories-set-sensor = Sensor verb-common-toggle-light = Toggle light verb-common-close = Close diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index 85e590e36c..31968062d9 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -113,6 +113,7 @@ - MedicalScannerMachineCircuitboard - ChemMasterMachineCircuitboard - ChemDispenserMachineCircuitboard + - CrewMonitoringComputerCircuitboard # Security Technology Tree diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml index 76f196fb3f..54482b7164 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/base_clothinguniforms.yml @@ -1,6 +1,17 @@ - type: entity abstract: true parent: Clothing + id: ClothingWithSuitSensor + components: + - type: SuitSensor + - type: DeviceNetworkComponent + deviceNetId: Wireless + - type: WirelessNetworkConnection + range: 500 + +- type: entity + abstract: true + parent: ClothingWithSuitSensor id: ClothingUniformBase components: - type: Sprite @@ -17,7 +28,7 @@ - type: entity abstract: true - parent: Clothing + parent: ClothingWithSuitSensor id: ClothingUniformSkirtBase components: - type: Sprite diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml index f692843020..de5dc36778 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml @@ -232,6 +232,10 @@ sprite: Clothing/Uniforms/Jumpskirt/prisoner.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpskirt/prisoner.rsi + - type: SuitSensor + controlsLocked: true + randomMode: false + mode: SensorCords - type: entity parent: ClothingUniformSkirtBase diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index 5894f40337..dd218fba7d 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -310,6 +310,10 @@ sprite: Clothing/Uniforms/Jumpsuit/prisoner.rsi - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/prisoner.rsi + - type: SuitSensor + controlsLocked: true + randomMode: false + mode: SensorCords - type: entity parent: ClothingUniformBase diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml index 2ffa85da9e..21cc3bd53a 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/computer.yml @@ -35,6 +35,14 @@ - type: ComputerBoard prototype: ComputerResearchAndDevelopment +- type: entity + parent: BaseComputerCircuitboard + id: CrewMonitoringComputerCircuitboard + name: crew monitoring console board + components: + - type: ComputerBoard + prototype: ComputerCrewMonitoring + - type: entity parent: BaseComputerCircuitboard id: IDComputerCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 0be2035ed5..cba782735e 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -88,6 +88,36 @@ energy: 1.6 color: "#1f8c28" +- type: entity + parent: ComputerBase + id: ComputerCrewMonitoring + name: crew monitoring console + description: Used to monitor active health sensors built into most of the crew's uniforms. + components: + - type: Appearance + visuals: + - type: ComputerVisualizer + key: med_key + screen: crew + - type: PointLight + radius: 1.5 + energy: 1.6 + color: "#006400" + - type: Computer + board: CrewMonitoringComputerCircuitboard + - type: ActivatableUI + key: enum.CrewMonitoringUIKey.Key + - type: ActivatableUIRequiresPower + - type: UserInterface + interfaces: + - key: enum.CrewMonitoringUIKey.Key + type: CrewMonitoringBoundUserInterface + - type: CrewMonitoringConsole + - type: DeviceNetworkComponent + deviceNetId: Wireless + - type: WirelessNetworkConnection + range: 500 + - type: entity parent: ComputerBase id: ComputerResearchAndDevelopment diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 03a5cb59fb..bb40207eec 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -183,6 +183,7 @@ - SolarControlComputerCircuitboard - AutolatheMachineCircuitboard - ProtolatheMachineCircuitboard + - CrewMonitoringComputerCircuitboard - Bucket - MopItem - SprayBottle From 1084176c997360e81ad1773d4a8792276705eb91 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 29 Dec 2021 00:20:04 -0500 Subject: [PATCH 07/12] Automatic changelog update --- Resources/Changelog/Changelog.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b1eadf0323..92a94dbf5a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Seth - changes: - - {message: Added Storage Room to Coats, type: Add} - id: 285 - time: '2021-07-26T05:36:27.0000000+00:00' - author: Seth changes: - {message: Added a hardsuit into research directors locker, type: Add} @@ -2874,3 +2869,11 @@ Entries: - {message: Add rollerbeds to roll people around!, type: Add} id: 786 time: '2021-12-29T04:57:21.0000000+00:00' +- author: Macoron + changes: + - {message: 'Added suit sensors and crew monitoring console in code. They are not + mapped, but you can print circuit board.', type: Add} + - {message: Prisoners suit has locked suit sensor that always broadcasting their + position., type: Add} + id: 787 + time: '2021-12-29T05:19:01.0000000+00:00' From dc4b549b90ae7550b206e608571e718b1bdfc09c Mon Sep 17 00:00:00 2001 From: Rane <60792108+Elijahrane@users.noreply.github.com> Date: Wed, 29 Dec 2021 01:21:17 -0500 Subject: [PATCH 08/12] Pill Canister Tweaks (#5928) --- Resources/Prototypes/Catalog/Research/technologies.yml | 1 + Resources/Prototypes/Entities/Clothing/Belt/belts.yml | 2 ++ .../Prototypes/Entities/Objects/Specific/chemistry.yml | 3 +++ .../Prototypes/Entities/Structures/Machines/lathe.yml | 1 + Resources/Prototypes/Recipes/Lathes/chemistry.yml | 8 ++++++++ Resources/Prototypes/tags.yml | 3 +++ 6 files changed, 18 insertions(+) diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index 31968062d9..f7999fe89e 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -96,6 +96,7 @@ - CryostasisBeaker - Dropper - Syringe + - PillCanister - type: technology name: "medical machinery" diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index 97b029e727..c8ac59b0a6 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -237,6 +237,7 @@ - Ointment - CigPack - Pill + - PillCanister components: - Hypospray - SurgeryTool @@ -255,6 +256,7 @@ whitelist: tags: - Pill + - PillCanister bottle_spray: whitelist: tags: diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index b97db0c1ea..6c51a9f8db 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -257,6 +257,9 @@ state: pill_canister - type: Item sprite: Objects/Specific/Chemistry/pills_canister.rsi + - type: Tag + tags: + - PillCanister - type: Storage capacity: 12 quickInsert: true diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index bb40207eec..df0e9e169f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -160,6 +160,7 @@ - CryostasisBeaker - Dropper - Syringe + - PillCanister - Flash - Handcuffs - Stunbaton diff --git a/Resources/Prototypes/Recipes/Lathes/chemistry.yml b/Resources/Prototypes/Recipes/Lathes/chemistry.yml index 372669674d..f1a02c461c 100644 --- a/Resources/Prototypes/Recipes/Lathes/chemistry.yml +++ b/Resources/Prototypes/Recipes/Lathes/chemistry.yml @@ -48,3 +48,11 @@ completetime: 500 materials: Glass: 200 + +- type: latheRecipe + id: PillCanister + icon: Objects/Specific/Chemistry/pills_canister.rsi/pill_canister.png + result: PillCanister + completetime: 500 + materials: + Plastic: 100 diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index f7eaa44692..715c2fd401 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -180,6 +180,9 @@ - type: Tag id: Pill +- type: Tag + id: PillCanister + - type: Tag id: Pipe From 9a0055a0ef91ee273863a3161f7e780e4ab96d11 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 29 Dec 2021 01:22:20 -0500 Subject: [PATCH 09/12] Automatic changelog update --- Resources/Changelog/Changelog.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 92a94dbf5a..6577f7030a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,9 +1,4 @@ Entries: -- author: Seth - changes: - - {message: Added a hardsuit into research directors locker, type: Add} - id: 286 - time: '2021-07-26T22:14:10.0000000+00:00' - author: Seth changes: - {message: Added bio suits into bio lockers, type: Add} @@ -2877,3 +2872,10 @@ Entries: position., type: Add} id: 787 time: '2021-12-29T05:19:01.0000000+00:00' +- author: Rane + changes: + - {message: Pill canisters are now available in the protolathe after researching + chemistry technology., type: Add} + - {message: Pill canisters now fit inside medical belts., type: Tweak} + id: 788 + time: '2021-12-29T06:21:17.0000000+00:00' From ca8d673fadbfe8a255144cb564a758cd13fcd537 Mon Sep 17 00:00:00 2001 From: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Date: Tue, 28 Dec 2021 23:31:18 -0800 Subject: [PATCH 10/12] Add ShowRules commmand (#5908) --- Content.Client/Info/RulesManager.cs | 11 +++- Content.Server/Entry/EntryPoint.cs | 2 + Content.Server/Info/RulesManager.cs | 15 +++++ Content.Server/Info/ShowRulesCommand.cs | 67 +++++++++++++++++++++++ Content.Server/IoC/ServerContentIoC.cs | 2 + Content.Shared/Info/SharedRulesManager.cs | 26 +++++++++ 6 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 Content.Server/Info/RulesManager.cs create mode 100644 Content.Server/Info/ShowRulesCommand.cs create mode 100644 Content.Shared/Info/SharedRulesManager.cs diff --git a/Content.Client/Info/RulesManager.cs b/Content.Client/Info/RulesManager.cs index 2986b9c244..4cc361c5ba 100644 --- a/Content.Client/Info/RulesManager.cs +++ b/Content.Client/Info/RulesManager.cs @@ -3,29 +3,38 @@ using System.Globalization; using Content.Client.Lobby; using Content.Client.Viewport; using Content.Shared.CCVar; +using Content.Shared.Info; using Robust.Client.Console; using Robust.Client.State; using Robust.Client.UserInterface; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; using Robust.Shared.IoC; +using Robust.Shared.Network; using Robust.Shared.Utility; namespace Content.Client.Info; -public sealed class RulesManager +public sealed class RulesManager : SharedRulesManager { [Dependency] private readonly IResourceManager _resource = default!; [Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; [Dependency] private readonly IStateManager _stateManager = default!; [Dependency] private readonly IClientConsoleHost _consoleHost = default!; + [Dependency] private readonly INetManager _netManager = default!; public void Initialize() { + _netManager.RegisterNetMessage(OnShowRulesPopupMessage); _stateManager.OnStateChanged += OnStateChanged; } + private void OnShowRulesPopupMessage(ShowRulesPopupMessage message) + { + ShowRules(message.PopupTime); + } + private void OnStateChanged(StateChangedEventArgs args) { if (args.NewState is not (GameScreen or LobbyState)) diff --git a/Content.Server/Entry/EntryPoint.cs b/Content.Server/Entry/EntryPoint.cs index fa3bee9f45..c74441b013 100644 --- a/Content.Server/Entry/EntryPoint.cs +++ b/Content.Server/Entry/EntryPoint.cs @@ -8,6 +8,7 @@ using Content.Server.Connection; using Content.Server.Database; using Content.Server.EUI; using Content.Server.GameTicking; +using Content.Server.Info; using Content.Server.IoC; using Content.Server.Maps; using Content.Server.NodeContainer.NodeGroups; @@ -91,6 +92,7 @@ namespace Content.Server.Entry IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); + IoCManager.Resolve().Initialize(); _euiManager.Initialize(); IoCManager.Resolve().Initialize(); diff --git a/Content.Server/Info/RulesManager.cs b/Content.Server/Info/RulesManager.cs new file mode 100644 index 0000000000..975cb1a108 --- /dev/null +++ b/Content.Server/Info/RulesManager.cs @@ -0,0 +1,15 @@ +using Content.Shared.Info; +using Robust.Shared.IoC; +using Robust.Shared.Network; + +namespace Content.Server.Info; + +public class RulesManager : SharedRulesManager +{ + [Dependency] private readonly INetManager _netManager = default!; + + public void Initialize() + { + _netManager.RegisterNetMessage(); + } +} diff --git a/Content.Server/Info/ShowRulesCommand.cs b/Content.Server/Info/ShowRulesCommand.cs new file mode 100644 index 0000000000..101f1dd99c --- /dev/null +++ b/Content.Server/Info/ShowRulesCommand.cs @@ -0,0 +1,67 @@ +using Content.Server.Administration; +using Content.Shared.Administration; +using Content.Shared.CCVar; +using Content.Shared.Info; +using Robust.Server.Player; +using Robust.Shared.Configuration; +using Robust.Shared.Console; +using Robust.Shared.IoC; +using Robust.Shared.Network; + +namespace Content.Server.Info; + +[AdminCommand(AdminFlags.Admin)] +public class ShowRulesCommand : IConsoleCommand +{ + public string Command => "showrules"; + public string Description => "Opens the rules popup for the specified player."; + public string Help => "showrules [time]"; + public async void Execute(IConsoleShell shell, string argStr, string[] args) + { + string target; + float seconds; + + switch (args.Length) + { + case 1: + { + target = args[0]; + var configurationManager = IoCManager.Resolve(); + seconds = configurationManager.GetCVar(CCVars.RulesWaitTime); + break; + } + case 2: + { + if (float.TryParse(args[1], out seconds)) + return; + + target = args[0]; + shell.WriteLine($"{args[1]} is not a valid amount of minutes.\n{Help}"); + break; + } + default: + { + shell.WriteLine(Help); + return; + } + } + + var locator = IoCManager.Resolve(); + var located = await locator.LookupIdByNameOrIdAsync(target); + if (located == null) + { + shell.WriteError("Unable to find a player with that name."); + return; + } + + var message = new SharedRulesManager.ShowRulesPopupMessage + { + PopupTime = seconds + }; + + var player = IoCManager.Resolve() + .GetSessionByUserId(located.UserId); + IoCManager.Resolve() + .ServerSendMessage(message, player.ConnectedClient); + } +} diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index 196873a7e5..bef312b4bb 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -11,6 +11,7 @@ using Content.Server.DeviceNetwork; using Content.Server.EUI; using Content.Server.Holiday; using Content.Server.Holiday.Interfaces; +using Content.Server.Info; using Content.Server.Maps; using Content.Server.Module; using Content.Server.MoMMI; @@ -57,6 +58,7 @@ namespace Content.Server.IoC IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); } } } diff --git a/Content.Shared/Info/SharedRulesManager.cs b/Content.Shared/Info/SharedRulesManager.cs new file mode 100644 index 0000000000..abd8037934 --- /dev/null +++ b/Content.Shared/Info/SharedRulesManager.cs @@ -0,0 +1,26 @@ +using JetBrains.Annotations; +using Lidgren.Network; +using Robust.Shared.Network; + +namespace Content.Shared.Info; + +public abstract class SharedRulesManager +{ + [UsedImplicitly] + public sealed class ShowRulesPopupMessage : NetMessage + { + public override MsgGroups MsgGroup => MsgGroups.Command; + + public float PopupTime { get; set; } + + public override void ReadFromBuffer(NetIncomingMessage buffer) + { + PopupTime = buffer.ReadFloat(); + } + + public override void WriteToBuffer(NetOutgoingMessage buffer) + { + buffer.Write(PopupTime); + } + } +} From 45bfc0b96bf314f9abad25cd683093f1fcfe44e4 Mon Sep 17 00:00:00 2001 From: AJCM-git <60196617+AJCM-git@users.noreply.github.com> Date: Wed, 29 Dec 2021 05:24:51 -0400 Subject: [PATCH 11/12] Adds posters (for mapping) (#5812) --- .../Behaviors/SpawnEntitiesBehavior.cs | 7 +- .../Components/RandomSpawnerComponent.cs | 2 +- Resources/Audio/Effects/license.txt | 4 + Resources/Audio/Effects/poster_being_set.ogg | Bin 0 -> 19649 bytes Resources/Audio/Effects/poster_broken.ogg | Bin 0 -> 8038 bytes .../Markers/Spawners/Random/posters.yml | 131 +++ .../Entities/Markers/marker_base.yml | 4 +- .../Wallmounts/Signs/base_structuresigns.yml | 2 + .../Structures/Wallmounts/Signs/posters.yml | 814 ++++++++++++++++++ .../Structures/Wallmounts/Signs/signs.yml | 5 - .../Wallmounts/posters.rsi/meta.json | 322 +++++++ .../Wallmounts/posters.rsi/pinningposter.png | Bin 0 -> 1003 bytes .../posters.rsi/poster10_contraband.png | Bin 0 -> 1063 bytes .../Wallmounts/posters.rsi/poster10_legit.png | Bin 0 -> 986 bytes .../posters.rsi/poster11_contraband.png | Bin 0 -> 1429 bytes .../Wallmounts/posters.rsi/poster11_legit.png | Bin 0 -> 1177 bytes .../posters.rsi/poster12_contraband.png | Bin 0 -> 1971 bytes .../Wallmounts/posters.rsi/poster12_legit.png | Bin 0 -> 892 bytes .../posters.rsi/poster13_contraband.png | Bin 0 -> 917 bytes .../Wallmounts/posters.rsi/poster13_legit.png | Bin 0 -> 1302 bytes .../posters.rsi/poster14_contraband.png | Bin 0 -> 1444 bytes .../Wallmounts/posters.rsi/poster14_legit.png | Bin 0 -> 1226 bytes .../posters.rsi/poster15_contraband.png | Bin 0 -> 1845 bytes .../Wallmounts/posters.rsi/poster15_legit.png | Bin 0 -> 659 bytes .../posters.rsi/poster16_contraband.png | Bin 0 -> 1576 bytes .../Wallmounts/posters.rsi/poster16_legit.png | Bin 0 -> 625 bytes .../posters.rsi/poster17_contraband.png | Bin 0 -> 1341 bytes .../Wallmounts/posters.rsi/poster17_legit.png | Bin 0 -> 609 bytes .../posters.rsi/poster18_contraband.png | Bin 0 -> 1873 bytes .../Wallmounts/posters.rsi/poster18_legit.png | Bin 0 -> 670 bytes .../posters.rsi/poster19_contraband.png | Bin 0 -> 1710 bytes .../Wallmounts/posters.rsi/poster19_legit.png | Bin 0 -> 1014 bytes .../posters.rsi/poster1_contraband.png | Bin 0 -> 1776 bytes .../Wallmounts/posters.rsi/poster1_legit.png | Bin 0 -> 655 bytes .../posters.rsi/poster20_contraband.png | Bin 0 -> 1425 bytes .../Wallmounts/posters.rsi/poster20_legit.png | Bin 0 -> 977 bytes .../posters.rsi/poster21_contraband.png | Bin 0 -> 1513 bytes .../Wallmounts/posters.rsi/poster21_legit.png | Bin 0 -> 1016 bytes .../posters.rsi/poster22_contraband.png | Bin 0 -> 762 bytes .../Wallmounts/posters.rsi/poster22_legit.png | Bin 0 -> 700 bytes .../posters.rsi/poster23_contraband.png | Bin 0 -> 733 bytes .../Wallmounts/posters.rsi/poster23_legit.png | Bin 0 -> 943 bytes .../posters.rsi/poster24_contraband.png | Bin 0 -> 967 bytes .../Wallmounts/posters.rsi/poster24_legit.png | Bin 0 -> 816 bytes .../posters.rsi/poster25_contraband.png | Bin 0 -> 731 bytes .../Wallmounts/posters.rsi/poster25_legit.png | Bin 0 -> 796 bytes .../posters.rsi/poster26_contraband.png | Bin 0 -> 1159 bytes .../Wallmounts/posters.rsi/poster26_legit.png | Bin 0 -> 1204 bytes .../posters.rsi/poster27_contraband.png | Bin 0 -> 1296 bytes .../Wallmounts/posters.rsi/poster27_legit.png | Bin 0 -> 1208 bytes .../posters.rsi/poster28_contraband.png | Bin 0 -> 985 bytes .../Wallmounts/posters.rsi/poster28_legit.png | Bin 0 -> 998 bytes .../posters.rsi/poster29_contraband.png | Bin 0 -> 1131 bytes .../Wallmounts/posters.rsi/poster29_legit.png | Bin 0 -> 1201 bytes .../posters.rsi/poster2_contraband.png | Bin 0 -> 1781 bytes .../Wallmounts/posters.rsi/poster2_legit.png | Bin 0 -> 553 bytes .../posters.rsi/poster30_contraband.png | Bin 0 -> 858 bytes .../Wallmounts/posters.rsi/poster30_legit.png | Bin 0 -> 904 bytes .../posters.rsi/poster31_contraband.png | Bin 0 -> 766 bytes .../Wallmounts/posters.rsi/poster31_legit.png | Bin 0 -> 1075 bytes .../posters.rsi/poster32_contraband.png | Bin 0 -> 829 bytes .../Wallmounts/posters.rsi/poster32_legit.png | Bin 0 -> 717 bytes .../posters.rsi/poster33_contraband.png | Bin 0 -> 915 bytes .../Wallmounts/posters.rsi/poster33_legit.png | Bin 0 -> 826 bytes .../Wallmounts/posters.rsi/poster34_legit.png | Bin 0 -> 559 bytes .../posters.rsi/poster35_contraband.png | Bin 0 -> 798 bytes .../Wallmounts/posters.rsi/poster35_legit.png | Bin 0 -> 633 bytes .../posters.rsi/poster36_contraband.png | Bin 0 -> 1233 bytes .../Wallmounts/posters.rsi/poster36_legit.png | Bin 0 -> 977 bytes .../posters.rsi/poster37_contraband.png | Bin 0 -> 330 bytes .../Wallmounts/posters.rsi/poster37_legit.png | Bin 0 -> 662 bytes .../posters.rsi/poster38_contraband.png | Bin 0 -> 367 bytes .../posters.rsi/poster39_contraband.png | Bin 0 -> 421 bytes .../posters.rsi/poster3_contraband.png | Bin 0 -> 1785 bytes .../Wallmounts/posters.rsi/poster3_legit.png | Bin 0 -> 683 bytes .../posters.rsi/poster40_contraband.png | Bin 0 -> 637 bytes .../posters.rsi/poster41_contraband.png | Bin 0 -> 480 bytes .../posters.rsi/poster42_contraband.png | Bin 0 -> 544 bytes .../posters.rsi/poster43_contraband.png | Bin 0 -> 820 bytes .../posters.rsi/poster44_contraband.png | Bin 0 -> 574 bytes .../posters.rsi/poster45_contraband.png | Bin 0 -> 1702 bytes .../posters.rsi/poster46_contraband.png | Bin 0 -> 719 bytes .../posters.rsi/poster47_contraband.png | Bin 0 -> 1526 bytes .../posters.rsi/poster48_contraband.png | Bin 0 -> 677 bytes .../posters.rsi/poster49_contraband.png | Bin 0 -> 2008 bytes .../posters.rsi/poster4_contraband.png | Bin 0 -> 1954 bytes .../Wallmounts/posters.rsi/poster4_legit.png | Bin 0 -> 644 bytes .../posters.rsi/poster5_contraband.png | Bin 0 -> 1092 bytes .../Wallmounts/posters.rsi/poster5_legit.png | Bin 0 -> 588 bytes .../posters.rsi/poster6_contraband.png | Bin 0 -> 1866 bytes .../Wallmounts/posters.rsi/poster6_legit.png | Bin 0 -> 627 bytes .../posters.rsi/poster7_contraband.png | Bin 0 -> 1800 bytes .../Wallmounts/posters.rsi/poster7_legit.png | Bin 0 -> 658 bytes .../posters.rsi/poster8_contraband.png | Bin 0 -> 1166 bytes .../Wallmounts/posters.rsi/poster8_legit.png | Bin 0 -> 596 bytes .../posters.rsi/poster9_contraband.png | Bin 0 -> 1698 bytes .../Wallmounts/posters.rsi/poster9_legit.png | Bin 0 -> 979 bytes .../posters.rsi/poster_being_set.png | Bin 0 -> 1210 bytes .../Wallmounts/posters.rsi/poster_broken.png | Bin 0 -> 592 bytes .../posters.rsi/random_anything.png | Bin 0 -> 609 bytes .../posters.rsi/random_contraband.png | Bin 0 -> 619 bytes .../Wallmounts/posters.rsi/random_legit.png | Bin 0 -> 616 bytes .../posters.rsi/rolled_contraband.png | Bin 0 -> 527 bytes .../Wallmounts/posters.rsi/rolled_legit.png | Bin 0 -> 507 bytes 104 files changed, 1281 insertions(+), 10 deletions(-) create mode 100644 Resources/Audio/Effects/poster_being_set.ogg create mode 100644 Resources/Audio/Effects/poster_broken.ogg create mode 100644 Resources/Prototypes/Entities/Markers/Spawners/Random/posters.yml create mode 100644 Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/meta.json create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/pinningposter.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster12_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster12_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster13_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster13_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster14_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster14_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster16_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster16_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster17_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster17_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster1_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster1_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster20_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster20_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster21_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster21_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster22_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster22_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster23_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster23_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster25_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster25_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster26_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster26_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster27_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster27_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster28_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster28_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster29_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster29_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster2_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster2_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster31_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster31_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster34_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster35_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster35_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster36_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster36_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster37_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster37_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster38_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster39_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster40_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster41_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster42_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster43_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster44_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster45_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster46_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster47_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster48_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster49_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster4_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster4_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster5_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster5_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster6_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster6_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster7_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster7_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster8_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster8_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster9_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster9_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster_being_set.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/poster_broken.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/random_anything.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/random_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/random_legit.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/rolled_contraband.png create mode 100644 Resources/Textures/Structures/Wallmounts/posters.rsi/rolled_legit.png diff --git a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs index bdf7172f1a..1af5e80199 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs @@ -19,6 +19,9 @@ namespace Content.Server.Destructible.Thresholds.Behaviors [DataField("spawn")] public Dictionary Spawn { get; set; } = new(); + [DataField("offset")] + public float Offset { get; set; } = 0.5f; + public void Execute(EntityUid owner, DestructibleSystem system) { var position = system.EntityManager.GetComponent(owner).MapPosition; @@ -36,14 +39,14 @@ namespace Content.Server.Destructible.Thresholds.Behaviors var spawned = system.EntityManager.SpawnEntity(entityId, position); var stack = IoCManager.Resolve().GetComponent(spawned); EntitySystem.Get().SetCount(spawned, count, stack); - spawned.RandomOffset(0.5f); + spawned.RandomOffset(Offset); } else { for (var i = 0; i < count; i++) { var spawned = system.EntityManager.SpawnEntity(entityId, position); - spawned.RandomOffset(0.5f); + spawned.RandomOffset(Offset); } } } diff --git a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs index bae54820e9..46c7a775e3 100644 --- a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs @@ -64,7 +64,7 @@ namespace Content.Server.Spawners.Components public override void MapInit() { Spawn(); - _entMan.DeleteEntity(Owner); + _entMan.QueueDeleteEntity(Owner); } } } diff --git a/Resources/Audio/Effects/license.txt b/Resources/Audio/Effects/license.txt index d5727525a3..8cba3cecd0 100644 --- a/Resources/Audio/Effects/license.txt +++ b/Resources/Audio/Effects/license.txt @@ -10,3 +10,7 @@ adminhelp.ogg taken from https://github.com/tgstation/tgstation/blob/d775e1ac804 The sound had been reversed and the volume altered. voteding.ogg taken from "Bike, Bell Ding, Single, 01-01.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org at https://freesound.org/people/InspectorJ/sounds/484344/ under CC BY 3.0. The volume has been reduced. + +poster_broken.ogg taken from https://github.com/tgstation/tgstation/blob/2834383245d2129a106acef3afd17b81e1e64777/sound/items/poster_ripped.ogg + +poster_being_set.ogg taken from https://github.com/tgstation/tgstation/blob/2834383245d2129a106acef3afd17b81e1e64777/sound/items/poster_ripped.ogg diff --git a/Resources/Audio/Effects/poster_being_set.ogg b/Resources/Audio/Effects/poster_being_set.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f651a53c3e8cfda272b98c6e16675fa0f8bb59ac GIT binary patch literal 19649 zcmce-cT`hN_b_@=AoSi12og$Yf`CFOQUoFNfOHTk3euZYA#|i0s`M%#1Oe#^(tEFp zN>!=_6a-Q59-ilYf8YJ?y6ao_uRH5xGADax&+IaL?f<(5C%n~{P+Ks`e6T}p$4Ja zcOKl8mJz#lRZK!${Jc6h_;GNvbGLW!QUHN=AW%Y5>Kw}L;$-`8LkP*g-rfu&L;SgJTL zxk@w>yvAk0(gt@7&Z|cH9Ljc&#*6YCOaD2(-E+(d(#^B~*88XOKUu;#`hQAp5}PdE zHRo8sSLDCHaZA}V11SJdSR@#?CP+iaQBMI30sx(oC)3TxOj>owktq~48MPS+C&!G!pyojm}M*$Bp! z$RvF2WU@)JM)pU=PDasvPmE@;mN`>zPdcsSTq z^KcB76f7!8dR0!9an;JQh!u1cpWU=!wK5q`@Hd5{rJ!&BihvFP?l8&3h7F*|cp`0? z1a5df~dV%4Trkvg}O;V4G}~%Q{_iqoIg6VH*}b9&E0Zc z`00B4r|a^Z!}3pucXJL_84e#BU9IM=tQLI#_vatd@o)g2^bzDb_-G`RYEb+moD>K^ z2jEL&;?^}lc_i_f5%`@l?geC&2V_?~;`*lwC>W4yV8R#wBQ}&-##5*K@^fK7dlvV! z^4YWd*-xGR&kwYSrwRbb0f2MB6M54UIpBFt)ju5OhMiA6RRg4&m&gD?N(-cM=ElT< zrNLESLlf8k3IVKgo(8<-!Dk3$1z1Rx*PM~k`TzKwGZqSf%14))g4L}vQAhWq8mxs% znNnwiDza>~F<&ZGNYRMa7%Wd&;mp#NvJ@OuPMEemJC_H-L z252z)x%=tt1||6UA{ZnFQ1-Y>o4IMaSpKq7WAo9{$SiF9V{cuo0ADK3oU+n^fOY13 z3W^kp1V18?;8@^*0RY5GXrN1(a9D}*ELALeAk9t#{VCT=S9T!FhfZjd&4&hCn&y=x zTb}F9a0QX>O{2mO+B`gf06&yPlPSy)rCjhm#XC-djNXn;g&ZBFk9(GzI<2f(89~5l zR`wBa3F+QA3_04D0Vjm+GsVS;mKxbPi7rgz5=HxSEfU(J(`-d6=giHkTKi1BS>Ch+?=%pVFV0+xIG1f+C7n8L?nLZQF^@m*JYM1+ z&RnFj&(u6lqA$xkUUXs7yaw#UFkW`RJc3a7)7rf1990|#G4MYb;)OM$Up7A81a*(`L4n|NAQ>|*_8QLbpMiJeEULvPHj7a$9x1t z6%i+Kob4@+*|aqxc7X(@G_n*0UB+&5r#)*#JaN{)vH+s$+bWE|3;;Hr5P-Wg@`}FW zU>v}$3*eOpWy{ziv1qcQ$TSr}^sNNV!K?^^gg{vu&YX;|5tP~!JKU9l(ntn#A-)C% ztW#y$w7FneV}^MGx{*Z{T^WTl7cOhaFn=b|Xl&P;l{PAi23ug!#B`i_6*83|Ay^ra zf<>eIaJYC-&R4c7eCV)3mAytdCt~R|4qXN+fD5|M$RfTm`kd9h#<=?ujo_=qLaYRu z9c-})S~T2wAF={v5lPsM!cqdxxvZ2)a-$T~zG3bX9H=s742IySKvZR=^X3VSPiM_V z`5Hk~b!iOes93agK$XD?Nq~JgOKfDD$4h_!G`gRFbs_d;Te!&nr*rK6y15KH=emtq zTq3#=1hn?2874RW%mp>0(dZmtYT*tVO*v4>K+5_0vdrV_K(!R)Yx<{iHn2q#iyduI zgDHrrl)(<{jm;vdve6s_Je{>AHvU9fxG9veILFs*fEq5nuwxuuznEW$=u@a<366)wpZmE93zH?#s=cekTL3P%@0;-EXb|crD z4ol9HhQnfcB5@!paKb{*C-4O+J{ANxAhmx7WS1*B&O?z`HjYD8mdqPC3zl(cCFJ!R z2ko}ba0I!wUQ5F!R?a6mkF?G$Iq4`gBf$a5fdi7OrK6xWBL_Z$h8!G0miIV&6x+Ek zr@|$iyY@KH-Gj8913*^;0zhRXfbKq$4!d-rHJyleMrFxF=iZ3-Bh%7s

hi*HpQRn|cF7s?5u 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 Z#~%@jy5_qodIA6d002ovPDHLkV1kGo+&2IK literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..b1aeebf02023157ce822593d2531f3fb6877f25a GIT binary patch literal 1063 zcmV+?1laqDP)8Fz`M{@`xgzo4;2^7soJa|onVFIpeo-?Dpr8>k$L@f|XhZVcd8|z~ z;ljDH7-A7bG&D4X&wDEY9*-xckJ^Mo_pC5joCx{euy*jlX%uZ-#O(b1d~E`fl9GNRkc*Jx_=XYT_tB4z z4dqaS8S{YL1H1?tlZ$C>ZBTn$zy;C zvk<`Nf#He@xHIR&rcXf9z>w76*w`r9XU`1?LZY_Y?Z!>vLTg^U7==PST&k?pE`X1L zbb;uGNGg=(=4QBDE;KYWpt`zRn&{rk`>Y_qs}xd^H?3*bHQE0~FVS^?yNy1KfU zghc5%H8nNnOG!7U@$qqXjVI9-Ap_E<+-x?pK&Dut?+Rts^z?KL4-cyo(BI#$Q|kA6 h<7c(m;Gh3H{s!T0qSm^MbZ7to002ovPDHLkV1iNM@tXhu literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster10_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..9e3d23053af39f687779843408147ae01142720d GIT binary patch literal 986 zcmV<0110>4P)n@~wQZWD7Hdrd;z4>Sg8xSU zfgU`FC-D$L@FocT2RupzK@<;`(xe}0lSZ~`6^bbIqQ#o-W_QPVGn*!jJJX2>^}%Fz zKHkpn{ocoHOgLfrKLMoEY2tYvXqpCwVL&300A1JF7@KX|&}cN+8a5Qyby<&V@pzo= zCxkHFSS$w3W)n)KlBNUz582u>f)SzZSI90sSaZAPW5K)^jQ3f~=TqtopgeqX8)j$j zb&T(_G4?H)ow-lPcUaHGKit=?^K|a9Isl}ROEdsdJRI|bi)_BF-u;@W;8_s>`k#vv z+VjIv+^*g~vfjyHD@K$6V9;=hhW5uX&|-|cpvYP#qpJhJ2yXeVvv12$%m1|4>DcQq z{kcaE)B#}nptanRcHg$n?CM(*wwKSP)1l{w1Mq$Hr3Yfs1@pd8!!(oX09p*F$Y}N) z(DDT9wa?Oh?Z8$5z=NTk0j^iAt1Hd{Uvt}$e42AqOXu1Z(C&4UIEY5;h%?RV1yl>%NFP-2!W;2 z3lK5KvqTX9-<$xMjEs!K=4P4Ezgl_2;==Xta8c~+s{_FAJsN7^@4@dv8i3#t%9Kt0 z-UQEgsm>nM>f1uVJhK!5n5Nj5n#NzGQy@O^SVIui`VPo4r`g<72Oz5h<<$zM-G;*C zO}IRE9Tpbnsmt)9k=KEq7&z`Oz~H0B9ZKbwjDE?h{tf{D)(>akQg)E${1lW|Uc+)_ z6Ef+uL1xGq;BHj}Ad3M^H@tj27V##dA8*Bxp?;`a--G}Xi5{+F83P-&_p}5*qaN^K zc+6GTHUY_GlKC8C3GWrGtUR?90a%u$h0X8o?!v#86aRPo8=dWmrxTwdnE(I)07*qo IM6N<$g3A%oIsgCw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..b110ab89fbf6b4d1799480827fe5c299e260b4e7 GIT binary patch literal 1429 zcmV;G1#0?T+&JVYW9#9}cd5(z}3QU0dK zvMgk?SstT@#C2V6X)GR(^ZXzPc&)0ca2y9?V`Gt`0FaXX-8*5KSyUudq{_=ty`~PU ztE+gtzNQipS%qiJ<>t#8Y~vdIXbhGez;taG^BI_?j`XaKsBfXG`>oM#0CMWsywlRxGAKQYttSwHRvkWOG zsjIJt@B76AApgJd*;U9&O875{K>U=ieuWpfkR%n7qCu7Jh2-ZMo zLnIc3Yn$TLh37hasGx56npPzUHxETsL~FryGW`7h%ZCLwY-oBBs+NK=HzVd{ z5sk^*Poymx0QpN*R*6%Jjf@%bE#tQz4qZ2=si_IQy}kTCGBSeE(NTUMAAdIwgd`@# z*a9U1pzyKmG{4Kj8qr9OK*Phsd1cMb%>_3kVB_QC{H~Q(Aw7LrfRIabK}eXSRt?A1 z;RpW^C_HIPOUsfzlF%xxt*uyd=W~$c1iOOrK+yom0wlWer|^9Oo^Ru3gtjXw3W$Wn z0kS|46h>Z17N36YJ>5)15|P(R0}xIo<*sKzim517WF^4_w6c0W5{d>O%QBPDhsQ2( zJTpJm-`|gpj*ca3s6Vs-iDMULeNg}uMahMsa0P{8=mv^_m4wV6N<6uWTQj4V27vNF zE(~)U5Qv(Z8fJT;)00e0OmIu{%5Luxw_pm_Ltq4)KUtvswoXj` z(T94G*B6^Q6td3H&=6`HU*d1e(ghF7_}#G!=YVAa*tX3sAmv0t%7m6_p0{x7TqLQ&6(w6B%vzR}0r^6X#i7PEk(j3QAbJOpSIiqNQXYz)zQQ3$ zcR@)2ZcG|vfrurG@=KIv;yNx{yJN|9>=n3x7S>;WY zWZ!;X0su*zE~zDv67^t0k#X?Ypy=FL81=|&jeEJ?&Mca4o z<#~r*+sUmhZb3y|K9eq+2cm(;%BdI)d=E$W?LuW)0*^nt8>c^c6LC=^4u8~xO;7E? z*@45NjLLE!0UG?E2ite-#gPNMv62+U0o!)awd(-1l$KY{ixU+*cH`VFUETQjoqfpI zCRUPy0K!^7l$n`noa{S-_Rd$J>$!YDAl&TilC?DV+{xpZ(^po$ECAxb^vo<*#?x1> zVs>sGt{>q1sXpBQ@RPXs{g)y#d_1`AWy~8HJkY)a--$8e0L`VUI3g*$wx+fgbLn*H z7Et2}20?#J29CZCM^whHNNE?&3?M2?q8wLoe&~Ikzc>nhzHllZ1*_|-1(-BPLCF^A z-v9P>WfZ07auJSnQ-(s7ldkJr#uI2w)A%Y+CX-BL;u75}lvx`Z8uAy`iU2NMx)dqY jKQ%Rl|5|SOzvI6FO`w=AlRzd<00000NkvXXu0mjf(ubK> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster11_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa6b1f6568a3f94b0144deaa1b50fe3a7302a6f GIT binary patch literal 1177 zcmV;K1ZMk*P)R_sO^t0*wee{v6f9$dp-egv(M?4P zVi`W{r4GA?wJ%GJo2w7))MZu>bPp|4@E@|r4*wLLlv*m9j*3ji>e$O#H`dHWrE8L# zq}O}CoA2h{^xo_%2zns-zH`o(`}>`9zVm%Im3YPSdJ<@AYEts~JRA-OoK7daUN0&t zDws~6OeTX=D#d*CA<5-(Y$Tt@<6-L+MPa{nyWPlUvxvvz4j}>r(h>PW*FW1I!{w`| zbbas6PMjG0ysZE7)srTD{d&K628s{vGd!e2edquijs6pZJ?c!h^c&}PVo89~NTNMl zi?Aq?KI49)%{bQxbuOI%)t^VtBP>dBZp?s{-MyOoqPWEgQ2Ur`9X0KP#T{YxbKSVEH)6dPED0H;dk z%GK}SujvQ6jrV+i-*CZV?f~vLo(;x5pk-B%fXn4l!6#4~SkCm`=(oD>S@K^svI#cl z5n6SO*OxeZ&U(vC?{UuJR1qPF}x0; zPymwK1zDCY*V~>0wSj6}JRdXJN#DJD56i-0;A{bS8;iJ9`0*}8Ks&W0e0TOP)?WA! zk3RZdA2lg0$x3&8K&0*{Rj zvT@VqPYPufB*0sSGC;Cc1-?D@8>VNTGM&JK4feo4O$;M7{|Ay!#+g1kqGrmygc8u( z3(1c+&zVLpHMPx_;5_0D8~3sC?l|`-h0|4#04@GHHh@#7uOXRysM`a9b?E$b2eXfk zoL1MRv3W~G2Pfd`KeX$>Et~f1zm4CCiW8vsJ!-l6x!+kUa(O&Gq}m@Mmwk@L)vZh) zxz%4Fp{T%T5UAT|0={wmOXgc1Si(6_S*e)`+~IKQb|aZ+cdPo{imtA9HTnS+)O`Kk z9PTk_4!x{G1n3+%dh`%t$A?(TxlrmgU?9>RMgQ>_BSo3A1_rim|B8+G#t*!SDB@At*t~UP65UICi8BPGt^0Pac!;L#V2%LT$ARD?=+-&1o;uy+S7| rwYD&Usi`T;na1EG{AY00000NkvXXu0mjfc0Mxp literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster12_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster12_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..5cf6ab8936c26d4ef261a97ff08b7519011b4fa8 GIT binary patch literal 1971 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 r_4j%`c5SsUP)| zOft{!oXL$Z(@C6HgnHo2z4yF(@AsW^|IT=Dm*xLSpsudYURzs(WmzaKErrkLLrF=A zwndkhm$A6GsNY0IR##WGly4Ok724mnZ5`|NdXdRwFg7-36-7Wmgn-D<(2$mmjg1%? z8QG{CP_db|$mr;3!T#mt<;6$9h;wrBG#Ct`wzgL7O-)Uhn3&LZGMPj;9Ny^fjEosC z5hr zVcoQW8QL;DHT!7WMg5jKMSX?(BlS7zpFsKxU~iAFcmld%cC#{1fI*&p=~Yj_W|rj^ zst?yA^w8da23!DAGruAE{SHG2Co09&EUx|Ki)JhdF2wqYwf_# z(6HkQ$2DWy>#pFZvNG;E@zgKjAn@)iEWeH9nQ>k$ZzA@_G40oPc@iBR9a``1?q>ZM z20rRRcwc+Y0WUY;0+;cYO9FatS936n;8To-JRx(r3DwhcpTYllvx29F`*{kYS{Hk2 z`l_zEZsLHI8+)%y0(uX8&&m@F;Q~)V88^gzw${T{?MP1dVBv>BEG^9A+SFCtxY&;h z|2+yG4$%7@0#2RcaUHt@0!vFvfShfH(JJKzn&wmdD_waZtM>39NuURzhiepAM8Ss$ z-U3~F?4ee143`eq?|^{K3&(l}x~r`eJ*i{_egWb?C2}5Kn!!84(8ib#*@lnb=yBJ} zoqC60b^W3${0wYOKu^Igvfo4Y_j3Xd%fEmlw-R`E{dv8}JO16T#*sMmJUaU>sLgzf zpGlxA+L_zPa*O(163|;~hmD{#|LW_+fpU|Tdo%rs+0R#g%kb|rXsECvY9pBP7=Cpqt3B1>O z9O<+ig~B8X63~~6kBb$^odS`*{;zT9=?27)C)8sBlaR|&NNK=@jDSmjNJ{3#wo;IQ z$Kyfc+mAT1n_iqf-HW3&HNfdy-6^-VrQcf}>))!^pXABn37B;@nNfa{@o(*|Y(*1r zzFfn@!&~Nr`Kg*|=jV;C2{;o=5fh2+L_j6~%g-ZCM&ycs?16kS6Q$GX+w5X9>9^_U zOw(NxaC)2n2gBJm8E?Mi|ABE$Kq4S%v`M3)(I{3{R!~`4sV`+L7E`-C+w=4Dh(sbv z+VA(Pt*xz1H*z2l&}&^X>`*9#R4P>*0j{4_$UZwei~m~g`oH790snUx$xVg!(EtDd M07*qoM6N<$f)Jy0_y7O^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster14_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster14_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..eb2a81884e2f22323aec13fe7548d4ebf395143e GIT binary patch literal 1444 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..43cd915420e643ba548984be6522d606018de03b GIT binary patch literal 1845 zcmV-52g>+~P)>1mW@mFFs_GH?$0oqixi$&6w z3L20ai9Q60H+}&R`5W+nP{acQRYGb3$SNq6AvF&@!^L#6pI$FUHb@EuU^%;3x$IFKLM0VCHTIttLW?N zMJQN@Wro=k;4<3;V4ECcpzA<494DZ2MWa!j`>71LuIme(w$lY4A-G-v>l@1`>~Q@a z86-I1OD6Ze?jJscbyWZ)1L z4gL6jlixMXr{~uHoi5KM*r4_cGs23nQLR=us6zFJwQ4Lre^OO#0oX2VqsD-yVQCPV zJQ$29<(?+mLxA@tY4=Z z42z2kI!`)%l>ZC#l%>u9>{Mub6qWI%)xGfiGq`;DU5t&5>1K1`!UYTt44_Dy!^`BC~j{ta1xiVT)~+$XYkGGY0Tfcg-3b5cXU$A(4||B9)1%W z>siDT&%nU`ttEhRrL1MB&L<`0^ZJ@N4SH|cYOSVe)1;PoPN?Jbo3G<9fBQS8r=~G9 zJj?(N!lCP^RKncE`t)7jYcMULT}NyYd|v>%aTun$m`o(zFBMVRS)?}@x>!d1P($N?9@yXl+iZ{7yQf}+j@1Fv0pQ2tQE--XnD5*~!-{fs0lXM1t02Ui1PMJinaGwb;0Qd_A*FOIFf0&2t5As~L>Qw3= zau0IkA)&`@H-AA(FdPo6<3%D76|yi=snl?2;xG;!I)s&#mG%H+v)PuAWhaz&^X5%- j(&px_@7wp4|2qB`Y{)k%Ia>6t00000NkvXXu0mjf{2YZ> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster15_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..07f728814fda20e2c4ada5db70b22ae994e32a1c GIT binary patch literal 659 zcmV;E0&M+>P)jX2p8F7M)JVViCY3)9L-itD4V$ z)|JbjM%&OW==GkD@1;^n+}%Bj!QfR)CKJ(YzQ}g~_1*5%i7f!TMq@t)Ji;abHv;Hv z+wMslCNsT*kO}DT``+&H`2?{4SpB&{;{cNbv?vw%&%mmVoDZiAO;8Vi9m0N5Bcc72m~MfII*K$YM8-f<2+Xiv%M9-1RXz zk${Mx2a_jM<*TWi+SHpdn*cO`NK{E+Ai8?%S9H{)BwMu)fbUA>J)Q^XpMcn#RzdeY z9eN-2|AIvT9%!{%G9ft!i`8l+ipApbqy%ttn$2eN8V}NiLO~wo`F#E$WM8KBcDudv tKt+s3BOZZ%zi*l9$K$a`8aMwt{sOCZV>Fk}&oTf2002ovPDHLkV1mQ5Ba#3B literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster16_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster16_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..a211a38009e83e2e2f64e847e6072da5d86e8b34 GIT binary patch literal 1576 zcmV+@2G{wCP)r`B~Hnx;8@iuocMni`;by-2jTV(8l;sV)FwlD7utVU%sCigZsc%qBkF zu%Yn2Y})Jt=MuKL?V|JS(_g0RXP}me0fl9=9<1dgEH2w9=;FDFpif4~55$^*hLC7w zZGdnAMWa!qQmOg?2pZjv8!IZxxH4m7B2~iNY6&^rfN9@xljK22^&%Qju{+^IZ>NlK zxV#Cx>(aUan5Maj?m}M1xiJ$XGg+91j2&n~H{uAv51nNZ8KlhxOcirj$d!=Jgt5N| z=t|zZsJZ}nDH?b3VqU?|BPCp(G0KAg$kQW(mv$erpe}=G5(kWBaMivnQ zi=i25wlYYi*iqX8AOyqU27{e~+-wn+B^HbR_Cn)om#OeU$}hqJ3Y@Z)_ZmzVp@{;D zyq8dq)dZlbD!bbVcohik=Baj->lIg+fD)v69>4KT2QP+U{LOY*(!ZDQ1Gs=`M;pRC z(*1$d1duD_pr{sFA_}f$^0>+Y4`3hHtC8>(%JEGO|2dz3d}jz9&*FK!!7Z94Q^PC^ zq+dixzbbDZKyza=WX~encPN;eE#ZPO&cGvLUljjhhTd(a;y=JRwZBS0-4Fq4fD9FJ z7C(`jKe%0Wgk%-5MtLKs)eS%#w*-%!aS5@ggwchIIAHImw1T9+5jRMA6IXf|U37@p z1r`M=Hr^P{;XI|7a;T4oeCSC&gbUob9c{32ut&w2+$>J5pC!#taa{%S5Mo5Qg$e4s z%%bydnMDMkN&c3pi)1i}-Zn2hE++H3T95#q#Wq=zM02&f8rIQe7kD!MyNM1r@+5pkf_?S2!*#i@j%5*Hs$lDl^u%}aj zUg8m}OHLZ5c_rqCCIWsY9=7O*P1(@>K-6{t6Uxf1Q<b(T3YSjR|8_e%7NXwdcf*HK`(n5xvugRCZiNF?HXiXA_9H+YEiA(@O}XiP<0TLS6y96CE~d~rU{j}DWy48Pxx z?rsHvKmez2c+l5p;RhzQM~-%3boeh!PfyneU}9pT<_VHcr=5Cyd>q@c(b17D-#zlL aqC`#)#Nh`9U4qk+B`S_SY~Y zA!ZiD#KORW1mPoTpR0?EbtcY7MV}NozSw%t=kxhe6;Hxs66cTrL+epU)jD0U(*pW}-|?CKJ|f z+=Ah7de?VdFL{rm(_Noz`dHQ0?Yi~?;Kt?hSHNiWp4ivx57F6+Cs7HAP!~uop2gx#deiqqdjSZVvVowr7JvwTssJ1x0PZ7qbM9B|rZJsP zN4AJ7YXMOdC8t1*c8*-Po5mmySPLKzn4kupiC6~~Wi5b$P(SNL&XJkyxdfO7>*pOv zi;*<20&2Bd>O?N_a8R?MwSaoPo=oPpfskj#Rs#Ma4`dQ>I`MAP_gPQLdAyNHfGR@m z7eS^|z>yY>16BZKtw#Z*Lz6{OcnYn;c6;C z$O}{xW)grH&?iBJO3c|gqDSOL0q_8=zAR)4LU>?29^aKw=kr;#+wJ701W-904hLDr zL$vSv@+xn&S~8FkOGxYZZ3}`xY`0rG0jt%@;q1HJPLz$O{~dn=!ah8&#trzi00000 LNkvXXu0mjfDIN_J literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster17_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster17_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..a21373dc483c59f10d14a59f7daadd2755db92a0 GIT binary patch literal 1341 zcmV-D1;YA?P)5~VIm^Sg+vX5&sKQPI-G zl46A}#7(K-T5zQ(QbZRnf-MwuA%sexh1dop1yOL3;zki>LQ*7)NHWEm&i_nip69zW z=gxg^-b`Ew^}yxbxj*Oo&bjBFbElV{vi!dYOixd{mSw5_(a{m1-_z4Wkw}DW+g88P z%H=W@i$yhuChH-X3x~sMz3aMaZzvQ};}DE*Zf;tE1fV>V$*4v3dR+seuNL?AQms}~ ziUEwitTiQ@&33eSXlSUj2SlJy6ax&v_==Sv1#np_mPud8X%OCzInmpZfVjz2fd1nC zKCKQ8>UAJvf?|z~K}>Lv72;Uu_m+o%Y%~?1KhoR;WgC2^%5rXpOu%N~IJZaKA8M|v za_i%E&>Rz+lZApdGLQg*rBo_;2tW#sqrfAP4OWs=E)}ax!5Y&O;>l?AK3U(MCpt$e zcsmk+O9g!4@Q_YbDs;qSAI;6tt@LM9U~ut@dFB9~oSdX|I_&|5M57y2sk}^1#8G>? z5&(O#Vr^hR2irGWA82q1BJ(WI-`=3L3-j7~0S|?~*ZZ83qvpFFfoYNSW3d%_(*G{m zdGDHui3yti^h>(=!VJ}a_=U#D$F&Fk+S#E~Gk>tPb6Ot)0R*bmYIhHq-&kywa=9h4 zbEFl?+}73>jpwqI7#^mz=6*Sr=brzSO64WJUhQ$b1_Tm75DGvvdY8dpBgu@ClrRq^ zQ&UrP_wu3!MnhmC;EKh04-kS@zFi5(v5cEg3lb{zoOy+H0*=!-C^zPM7M(nEhM-D{lb;B{kUzo{_M~vheDHuHLC}qWR6O$K7^wwN z7UTglDakd(ElH(PDnIP72d#qDRtMS$zzUTMs;$6-6#&3jtTWx~FFcZ@#yfbDv+WJdx@Dy_)&Cl`|##?VX>vgfN8XVn$eq_VaS&W;4cIyc^M_umg5Q2gv! z4=`kGY)mH|KRNWz-MUA$dq2{;L5M6mJ_wPe%xnm7e{sQaOkP{2)M8SP%h_7FMoswc zjaOBkkfH@$D{s5B*bLyV9#Cif$oABHnM2DQ91#8doBEE7j_NrGZVx;IKx9f8M-^T0 zC8t0FQmJrfg}so1WfLENK{kV5n|zk4>pu~Fy-E*1d0$04K<$0IS+*lwgbGR*GGn>? z5?#HzPd9En)182%N)RxgUufIg+myce3O#1a+~0R;W#%-UoSki1k83*8ct`rdF}J*& zptk!>0eJwx_JQpoWZv@uzTeiJ`!s;yG>VhTA%#{I1-QS22T5Qps1G;3ij1*YGF$4s zcLLATeqy(Qn|hBWAW?1=Eq#5=C%L3p^9q{Jv)W*dPMo++`Fv962Fap98MKW67URWo z^Afw3E8QRi2EE&JcqzeBR-9#`abEWr56}yBelxz_AkzfAa^+9Detoo+=8y9LprgI@u>Fuy&l5_TrL;gVk}KlJ-;Xl{cOA4R_F6s&FAw-L;y}Uo2S~V+UoT4Mg%hmlMGLyIvX!Qo&qQB>@D@cZ_L#e!i;l z_~q7`Ho6DwF>?;Erx!{Hxc1BCfOBXghycibg6m7>&|r=gfYtJTu2 znFX#Dabs0kQ%S%+2YhmJK}ojS1P%vYwz?T`7XjOuF9Te*U;?2B(LG=Z;M7_yW~$%s zmt;3v6WkanfcF5y;hUTQDd3XPN5&qC8FTdk#?T=Sx3HY6dHS7$DXr3EQ#n-fVrxF-riozL|+!70eU&SIc4ohylBP;L2{! zL6t)h0s7lQ8y6)6s#9Si-T6 v-?k(fs?};GBd}a9BhJ2Fuhn1U;eW?pg8pLG)782V00000NkvXXu0mjfrJ50> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..b28447a5fee98e690fc92584b4f37aa82a0edcc2 GIT binary patch literal 1873 zcmV-X2d?;uP)EA{E(YTNE~s254Q>h^5%FWcd;& zP1C=9h5qd8^kJH|h~-OSTbAvrM(flmkRpZS#FA;5m%Yu-&h`u)^cNkFK!KFPg4*SB z=Ir^-cfLc3@A>ur3El|eaKnkM&}l^&7ZqYD&{P&$ zBv8<>{E96NeAIX;Bm&Q%%k_SH;?4OPaIe@?I1)=#VFyjFA#DM)J19e-qxqx+bRx`P z5I}Mxp@$e%9@_lhL;_W5aqLJ7L935{?0<=vtjrC-(O9Gfbi0do5+dcbnw0u(J4t%O z0L$eVCqD8ZJRkr1jYOuF5my9R`-D_Ot{g)>N#Qs9P?>?Xc76b^{(j^ZZ=kab*^40> zGE%Y}QkC$k6kqYaCtESrcM}}{Ga(iNAD=zMv8KVH*G9z6kGER*8UhJ5;2vsj08TVU z*HG;kP!y6qMAo71z$v((n0zX`riwFOvsnpC;gw^9A`TF9@roc5pP$zauALg-!rl=CVS%mP7H+H> zc)kZqwp2+L#ca9FyxNdPX+u{|c&>g_aV~wd%LZ#Z#}Ky!YQuV$9!+UJ%I95}BE(Prpz+zSLrg{~Dzdr|1Fp|4`}`T{Zkhla|BO)Q3W6+H zRpa`(;VWbEL-f1?heklwdb(hh`t$+~FOV#QL@39wX6F8{7ojRrG_0H7jj_4I#-ae- zQ*%W)Jw=8-Cj(TxZz3gnkwsR~57;RW&W~~SP6Cf$Pu&DQ`gshC1w`mdP_XNz_3$&& z7*Y?7Ctz%YT3E=Y#<{(txUo5b)$|7^TC`}I8bO;vB@;prbVMU7Y8G+!=C1{yl)?%R z)kzT2(M%Zg!AsnGdjuIMocXj(QB~OZqr&a;4SedWQ5pQek^u#;rWW3Qj*Gj?h{9La z&N|KyfHMT&&^Y?E&(A-!c>A3T86m%m!r78Hb!l0Zk8a< zQ{+~m4mcxxGS);0-M})lMKBXU6h!FJYF_eK_7%3ze8qMGGz}*bK21;H_UaHDdwt{; zK|BQhbou~(L649vYQx9YCkm_>hmmDT>cvV>6a|s93G)FJd;}o{r$sXzP(Djj3^mer zK(onlWltez?cck96j#??!WSB`Z>X6LX%Dc+R&Dp_n}-Wnu``W4k%*T%FcchHflnpb z83Woe7i5ul0e9sU(kH$LD;yvgj=g4o^v8HA^nPzuVgFU-c0e%{T_s&L*_Nx zl{%qVH+laT=gFkgjaPBe1pqh^CMk_)nL~-2R|S24Eyu;b{Scq54+s*%sct zL(^gobBtBYeLL%8T>2}Giw5-5n+ZO9pPf;$9cF8AHUJkir3<4J9@T|Q?D@L3xO@5= zTzJ&OHih@_e2&%olB~Ssv}E5ikO<~KEVZz`{sNbFyZHP23@;qn-NwbS$@~DOiI%+^ zvftm_rt6I>PSk*uYuq}0h_FyhIvOv2VW4QY4Q<%QV+e)_kCTsC8aLMu(C-~bT|UF) z+vGeq0H*;#5O00Vsis{SEN*QcvaMs3oJ0{t8Vk<)&_Y!-CNtz%W+w1!Xv6Md>ouID zO*vwkW=0%kive&Yn1&IylJ!%3dAY%I+@r}5oLS$OIU-cs5zUh$L&D$^>^VFxzpFWxAfB!|A~UMc_}BT{9KO959un<4KE@qP1ke za)g)s-7t;n#tGA6Y4Vyd@LdcDPcvjxQxOeaqNTH04jaLs!Ffkfa!fNdPp}UsF~#tj zQiy%_d-iSLyR=kHe<3Y63mgN#JK87u>c7`qtnPNZjDIc4a zzU$tdke!wcUCS^I{b>IHPoF-W55VKckHxI(&!0cX|N8a4|2qB;Q8Y}<(tWN+00000 LNkvXXu0mjf7KnV? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster18_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..78ceec5e8811fdffabd3e41f0c44587fe1b8e7db GIT binary patch literal 670 zcmV;P0%84$P)^d+ZzZDk6CFTIfN%cnCcSVo@mc z)CZ6vUV11M!GkX#3cYyqA_&13=nM2xNGTTDre8XX6O(o~*;L#5hjhEMN#>W?*~umV z8`l2>$Ye6J$z%eGqJZD;hiEhkKA(^E@fZ$=(C_!z7#^tcc+6THi$o&q{Ml^At__F7 zFdB_O(=vXN7fZ91LG1K|9N9C;N*!TM0H0GKo&xL{df z(nr8KsNKCifbV5y6+#gN&pFuhgIh)OT1MtsnLJY%@S`qqJ>7GwIv^hyS z2M~f}g_(EY=1>ZNB2X+AU2mYOD*Q&m2$V`C+cpX#kVqtKPmen%-0R^s9--s$ID3`H zVlkG;m`hmJ@v|+RPD88Jk^^Wqn+ng~ZnxpDwehdxPp@9=5Ln3bMgRZ+07*qoM6N<$ Ef|;`|XaE2J literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..c57a0ebfb83e81a88569d82b4c11b65688682e7d GIT binary patch literal 1710 zcmV;f22uHmP)oM1S-`8vM zTr5pfeUG9Dp69in%Xb~eL6Rgme*C!66975r&3k`=!94>9C|D+(f;11!ft zrU)ifP__lPks{5X|9+J(SsA<>P>)?WS%mxF9_pO|?U6F+i2)}_d8mTzl;D>5x|bps z3rHRw8L;gHDR{^%1+x(%i3x1LKvWGesWKR01VtdiR?h&!Fhs%4(BMI(*)yt=W%@sCV)?e7Sc%maHGqEXdl;48<4w7ct%*)Oo;$N?_(p z1QnBPC?>Ool!+LIosa7HG-J)SY{Rw@9C~gp9M?v8K8{B|__e)m$e(GGi8?o{AxdY! zN=vW{^q!#HK?Q4KT(i?VfWQ5pb1fuM2#584c+Y$+-!Q7fpaEndjKpOX@WM2P&mto! zo!}K3$TR+R?%1UWx+kId+M?eG%W$V%rZ+WBM?Y(=Wr`}v9IzC#&#b`AW+LM~4hWbm zMD{c!)rq!>_QpWg(j}xi#nN>r+NCLG8J;u%WR_G9biye!f?qYD;xeK# z%P*F`pgJAZ8G!4uY?!qNw-n&^O^46Vc|T}px|o#aSFhfL#SebdWb35`+)a@UTfb*y z0Sf(0M&+PBHX%Ir4nX47=S1j}_|fZJALW&xQc)FLh`$^zB`G$%aRf*AFJ#Yf2!f@@ zg!QW#bAa05clN$30OJA_X0*K%Rr^et7_T#p#r|{+L z*E7K^46i+^-;ubtnw5m26^@oZe7tiG>f;sI$vEzOaf$$J+otRqsO2oa(9D5)WfChM z`x!@HTS|>jrR`xEJryPdL@N*&q zG8bmj!sYh?r``9Tx*U#KMNn(1+S!S-nBL#)j8bP&AGM<#a5VE!Ec&QU_;f^p6FIx3 zgmDT}vE+at=MD988A@m@v9B9Ntls_yKG@2}6!}=T{v6(Wd;pE|pNP)ba7neW;@3Hj z`!zN-ZpM+^%ylK8I|HmhPB;8rzzr+h$f!?3)h6-oBLsE!9Oc%)$V2?>PjD1ZVZ{#V zkKxeSG&6PFBMvDcyJK#uWhe~X@x~PwjZq>hrBX?EO8G2zv1+xd!zG}L#iDNIg+f8^ zA&M$JLH3z7tAf*~Pxl7k=)c^nh07*qoM6N<$ Eg12`v7ytkO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster19_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..12b423165cfc0c17b2f3b0f99704f63761a6d8c5 GIT binary patch literal 1014 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster20_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster20_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1091c22917e81e1c0d60bb6b03bbfd4cb75cb8 GIT binary patch literal 977 zcmV;?11|iDP)c*g_hn#v3Z4(HZ{%5OP_CcvzwP@ z6E_&C126k_W_ISA+1Y&)H*7Qgp8#50Tg_}X3l4_^TrL+ViULljlg#l+r_+#1rHBk4 zB*QSsh_c$+TB2{7CRywCdLfg^Kr9w>NC7}63k$B?%(R|g0xf4wW^CbmbNp;>zD}Nw zj-B!uK#EKZ@%O$n*I{aAjL*9|&y#U#W|Yq(6T?ONT6~GTM<#BN${7Bm{u_kI1Qmo&p)2I}0+AAA7dwJgZES4F1HcLf(94)B1#YwC3e)t;1Hj|M_OV(-ZAt>z+{8$-P?{>wfZOep2kGhTzswfoGca)N7--AOkVqszhWvg%jE}!B;F+c&)D;4#sj0Dk zljJ=V+6%LDb0ABBK!5=4?ml9Hc+2@tr})wpay=f5-eWnhhiEhk@pv3su6!-hTX`5F zW8G<$f=!NqrfIOYzDnl7Ha~p&NVihg|Kc8K8PZBSKlcSd30Nhgfog^!moQ91!7ONtZj&bs)e|7++#G3`yA3N*;<%7-XdrFk2QpL8XLvOS_ptP7j%KDE?Gus)J;uI zMb(V}F={4XTwEk|fR5REw3SYaPmmA*b}#lbjS<*K`#qql-;4A_M31&40IIA&b!lB5 z0QP&Ns~tl@n45j*Ltu5j?NwIh zSY=ch&ey%kK!hsdzz0zu9QY*Lh^1~tyQuV~^hNeC7H9?|V^7){?6!7ES(`Pt$<3|b z@4M%21(T9I%`YV9-gC}(e!uhmJ0~H$VEKO%7#<$pc3oGWgTWvy%R)37MIaE+@7C59 zY}?i`ekqRQXj`dN5Q#)o$KJHDXYU@gg~Ql4G=Q1unLtwn2=ZZW1DkLWgQaaJf~cS> zZ5W^RK2<{P?d|C7=s@Y|Q(nuWZg#y;r){su8 zaryFP)fpQb!`Ihe!rYGz((eUL1z}y-7VT{`lDY(#vyLh1flgZ%V!GqeruvnIPLzu`Gj18b!(GmfI&~#m5x}vy&89X~Ofd0Nd9WOk7 ztUD&~g$oxjIXQ{r$B!d@{W`|p>cFqLK1_`Or?QX5dW@SEEl?_#w2JvbG$T7Fcu~w= ztyYof>A{C*&mwpCuFjvIpU2@thqOO^<1d}Z`7=UdEW4uTM@s|}T?zTk3yFXpLKGj| zw*bLLM@Mn-;zgW0cTV4DKVHGxUku5Ns?Mi`)e()$cU=NJZe0bgsVmN8ixPx2CBuF_ zAO3u#>e-_cn2=uP{`5QB@?6k(u|?0-v*UT{Hcfza+tKJJ2?tZjLA;+?(PbE(EJS0O z2XgF&a4G4PJ{BO$xNJI^FnvXtU6B*C{yET)z-D<}bXCh1 z@XqeQGa!GVuq;gTUJ<_&G-QIyk8;Kg=S_>nJYvhHl-DoA4GHi<$;_n-PRg!$5Ov8e zYysraN)k}ekUq0g(n^+A%z%=!^+aSE*Yq;iG674#QzpVG%mVs;Hrc1o1YkCtRzEZH zdo&YfrO%(AlDX{rnSG1P%@be@Y?{C!04>3KepMD^9HbQ3TafM{7{$-`Q<4p?3CQp+ z{%=Ttcm0sb0N?+eX6lUDp|wM`VlE!GF?E;R26!!>5MootVvE5R2t*@fU)o^-_gTvM zCasuvrXOnsrPK87yq0@pTP(#Jr43+*l7B6ygiXKS#_@b>wgH@yO32`K&6wS4DUQeE z`2IC9tQjSKR^TEce=;#}(M;BW5|OBjRzbzABhz)3HH&FP9p}&2JNM4L^WK~HraK_m z2XEdz=bn4cch3EJckHmw_&*7FJRUinPJ_i_0h`SRPNx&BRx6S5iO1s*i^WJEK8RE* zMc&v~TwF}-WmzU;9S#R1lSv4LLKYzc7-V(TmXT!T**37UX8KY(y(6PfXXGvNG&Yus zR{$|GeVeztF5H2c`AIIfHeV+1nfVDWk4z8d*oS}rBJGjsdk}awB2ECyNFCi*9F6ke zt<9Yod4jaFx(VJ#^%ChTuQ<$!n8A<$&Ob7z0Xj5&RJLj=k$rdQ?6Rn@FB2z#i-rZ+ zE9~s-h!emS43Nm<&Wzly=?GbNh!eo=!{(8}?T$bph(-?@_!K0tyNj8mx$JgtL5WN2 z5cCc$`Yj$&NR(s)*e`B*Dq_}Z9A(WL&rpTC2(O26QGMQ zre~$e(&zKR@bDwj?(6H-RzPD**HS8F10&>_0$PD+R3e$Er=YB~62`~J;oI_eB4Zl~ z{n=Qj21@X)?TBU_$g=*#%tN54s7U$UYD{(~S*^y0uAx?vB+%~yZ%YpZf4Q)3!kBC!YO0A`Qi zrPcwbrn2G)3#sX2$GZ>#dTMDa@aEkZoH>0JK8F@bsf~cs(A02}*y_hyECo~`kwEs^ z41WBiBnEChfvM-ChR!avcf!!aYl>}d_2{$;5}=oh+yO`e0|Z{ok~0AJKYJs*=g$!v zqp|ULRGa|bUd+yQ41j@*`^>)|bZZL|pvF#9XEaMANMMdFaRPYXQ%-|C&I4xfQT; zz1EGyZE2rG>}zU_ca>=c)N4SU2}SnP%1C9apteh7l9+_M-B-j3Uqdty%)W-r%}sLKsjjxcV2=-KYn|Y7x!}|LC1_|kM7}FSH@Y;w{z+hE mWyNBo4~N6B*Vy-e$A1Bz-i_b5Zhe{n0000xeFEKE)7hJm# zd=THj7jR?2jo`nIC)4xIX-H_&4s;Gkk}o&8=l0Hm}v&pi|6pKYu ztJO@QP_SeC_WQlrZnt(0Kj3sa*%ouvYSqeLuUEUaQmL5Z@o47rc@{+gN zEARDse;42VSq@LkX0u!#pd7w;yIpg+T;d798Y*^`h5#AJDlmp}*Qj?1AZZw1ZtRkv z_3Zod0c#i*ByBW-P`uR2e!u@_j^9a^V|pNo0FDnABNS>q`f5D^Lh1#s!Fq%=DFmT} z`3z78q6yFg1l_6DPbQN*4Cn*&g31#~rvORFN=GoRP(tNOf^F#3BoT-S0prbCt6LPa?p&&4L7|RT>WF1m~F#pYniP2Q>NEY8_yo*87fW5&_;| zxzKIHA1^QF+rxt$qyKb&Z~H%Q7tZsoWK)KKY$#mG1PCRe%F%v*e6(|}%!df*DNuL9 z>R+!`;ydnswuIIY%zY>cQML57qW}q5>>|e9(FEWDD0h=dZ#}e@%xYzxUf&CVdILaF z3mxeo0aQWM0tMp=63?Pg`_YP)< zYx6WI(nRU$qEtwcC@7E&7)@A@D z^z_S}on5)XU?8oQ(J9)Ci=UaUl|%OU_@l6%CzBEIK^p{U1Y{@+!$`&&R<40@n#R&c zI7$g{$C|k&V|Qa=*ZP3G$_OBd-g4%EHBn};jx!CO0+Un-^!xoRIcU_^+P-hD?iz0n zFrly`y^uTfwN}qM)TcxFY&LV_@i-^YYPGVgWeCcSmPYLE%5=3I_TgtZ^qhc>f8DrR z-bkC9OQfp@XTifdcB^T z&-Y5WCb}5;4BD%w=QYVXi75o|p+Ug;u|;(srYc#X4s^R+_fg_Qk#` z?zRwBg`n^nrp!R&TpKDYK2=4@=bTB%+9L#(%Vj|U$7JKog&Mfe`HrH3zIAAI3LhlA z623)sQD=?T;n%Scn7`h^=jR*u9zbmQ2~S7ZEq>_pb3aMG2OT9ZfRxZuM5cvZ?CkD0`!h3sKzEG) z1nvicR;v}wW;2@4=Oo`kp+Jkpg4@+6H7%<1qz6z;yt1 z=s+HZA(hKzmPb)U-EKEv0_c48HA*;zNfDHiFZw4*eYByyv!oEceq2s>0PKCI(XfaR z{h+ybTCL~mWc6WZ3<041;hX9F@~p`N_s*}Z$u5s}Eg9NCmY(!$o$LOx9lm^G69C@6 zCwlSRW_|W<`8_=$OQzdddM=>zYq+fAUKs+oL;x0l^e`@py>CL1?d9lYjl(W{`dml} zG#ZWg_dD-Et-5Nh;Lwrf>1pWxB+fcmvq0}14E!x zDzWtkitVApS}fZ{=C*MUR(8Nxj{%)s>uXKEp-kHH6hH2dZ31@%i-7x{w}p$NCJl$f zlmPrP;GX5S(2fh@f*~*%3?QO*r@7*Ow*lM(ivXe@{e^{nU;@HMpgo+_*U8-Yur4;p zD?pex1nTuVNr=sgcrGywi4EdELK)M~Z( z_b27S7X{bp8iJJW4h+ODOGd>6Bz@Azvh<9uZWQ?d#0In_M(8z}0CKi0_O1m&Ld%H! z=kFUYcT9W_6Bv!s91jXU-wq!kgQc!zdW^24UvxFBghZZ%9&}Uu$r!C8*)bF7_xp58 zJ-Q9xY$b)4gXPp7a3Y)#==FL5-4Zal{GR|2bYNf>?pHYeCkgxp)<8Z9sE{VX P00000NkvXXu0mjfw~JWY literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster23_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster23_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..4e1b818657f9a03793fc293ea4648e9586e54578 GIT binary patch literal 943 zcmV;g15o^lP)iv_DLz!0%EroOW5Jch+7w6Y!__&3oKZ= z@Mjpd{s6bSCbB@(M4_NbOR$lcm>bhlS_<|>AKq`^+&lMnN*gptqF-`5XP)OfXU?3N zUZcN^{{*fEfmkfoZZsOyY&MC@fq?;PwOXR?^Z7*G<#LJA>-CBcz?gcyPA4ZPqOVq~ zk;CB-G5{H4(C&0P$>Z^e_IA5X>2%s52%vLiW#v*WpP!#MJplGVG#aH$CL>Blp-`Yu zC?v{!K5vZS@jM2=IC(zHazD4jGX?<_STTc10O4?0Nl@hpT1cJe!(t>_T^ny%~<3t$)yg%nzqmsLo-DG%x zAqcqLZn|tJJ`vY%VJlp)SkXmkgy+Ddjr2Uz{$FN#OYSSX97_;~?>9j(#4MNz3NMf>;=n z*(%w(soPQ7+0Asws#w81Tu$TTev<%hzuDPYnivh!a42|2ra z#FD-!V|&qDbV(tHL&NlOW6Nj{jttYmex3q);=?u=1O^8OsZuV}>($lMiPCZ0OeSf1 zdfKRiM8806RqHkKx;`>~YepQ%!6)BfDs;O?pi(UlnWB7F}2o#G& z%R}^cfW74>JS&2=_#pFhe`sjPB%o=UgZ>b(IRBpjaOuFnZnzr%jQ(i?zW^2M5Y?NL RXC?pu002ovPDHLkV1n`ouBHG0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..093de12189463afd9ba290092ed763edb8ba5633 GIT binary patch literal 967 zcmV;&133JNP)K@`3D)F{>Z1x2Z$1T@eD|aEEdV-a>+h`KE}ZA@p!1Mtxei1l?rWaY`CNVIJ-ADm8#ctSM?|9OM~jF z|HwAxjkHz7YaE?zvu>eY-?m`KE`9}mSg(FZ=AA}qq4Ly zR)o+P-IQZ2EfzAP1eoxGeyaX5-BbMuTBj*NXTozz$#zQ0sfq$Q$H22J0?W}|Fg4E_s(EHQ^nmQwGv)O0cwP$Lq>`_ztBWX;X;9s2R+q6k z{paoh(~MjBTiKe$lmh&IKV1o9W7T$T?ZS^3GjNr%7z%~xyVGb8#BTv=PXlMFzhCu( zdwUmS7PALAfSo-!IH+77Quef)Vk!aKy}dLUiz!Du9AhWK#9R z;joPiK8QdT3WY*l0O~Sue0;11cXV`6G#agn+uo+}@$rWKWr62bS669Bh_Dr+qoZnF zPp8wi4at2@vEJX=*`ckiEgL~kPY)d&9GrWPSN?~nJ3(ClzJ5B8DhzH0CO3_7+Rlrk z1aLY`L?$@NowIb>bYQY~4iBkhS#<%Oot<+1QIhqtoXh3x8&1RU@URjype;qF=7WGk zK@`eXD_}sZKQcSycoU=m95jG@K2Kh+SBk;Iz=MfLvW-T0=M$9_ z0Mgt0`*ni@7ZIToVW*>IyH3uqeGPGDYlT)K7?Ma_12tl0tAR@~*B&Y0|EXQ_DqA?+>28=e8NrIG4!Z3hyZe0>hGX4n-(5b-(r zjTQwt+Fb*=33^;U9ZLaOq161wo3UOae81G_!`ku@o{2D9Ti literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster24_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..13b95788c6dae2cb9615a3df71342a0a43a2772f GIT binary patch literal 816 zcmV-01JC@4P)k7RCt{2mpyA!Q5eUcB)v&)gCVWaEDmk~9Wr#&A>iU>KY)Xa zi-SdqMSO!|eWeoA#l^)B;GiEs$e>$62hHjrfoct*q~tv@|L68O_uS*XH%VKtpnnMG zJm>BC-RHb!hW@ht0~`*3d_F(y^?KCr_es)dG)jZPfNk5h*|sc;(_}KqKL~9)oep)o zU9M}l+Z2gJI1eF@HYkt9Vw6ZExO_MqQl(OfFaRp&=AKVQKJuvqU%TUuApP6V&U)>g zofS6%p!d_q*H2Zxc=2r2snGgqq}G&ZS<5Fl|#3 z1zDsFkWQy3Cg1B9n;N?YAoJ^k?4WcKF+e;X_pN+?x~TH!zLfWE>++3&-^w*RPV30D zWf$P=`2)aD7~CA>AnV5hgmsqsFehfY?1E;q=>p(fo>Y3c!|KJcX^T7uQKQiyoC~)z zMS4(o8;+Y#vCTB7eINjCztv-lT(F)C|3crvE*3alF1?t#?~G1UI66A-limiO&KJfG za(3Y)ec1R$rRAlu5V8w!%`1RZD#gaZmE-m0}}?aD1$ zdaRuTv!mBSz>|O#6jlj2*3HUhnQegs43x{(JbkkB4v@U47(i~OX$9v_bPA(DdFS7p z3QV0Y&uxe|+g=qE9VrJ0qJeb-#bTSB%GtvJtyYV6Hv+FxzdJ#HPWj2N4|Mg(J)UzY zlb%tF(6-lH0Bi{Xn8cZ%!usf|UL>z$2B_ETRIM)3K?rjzPk3>J=NEp+%X8ndj<^8T uYBfR!Bn&S9Cm>up_`o0?j(Bgf`{A!IV2F-!N3Ocm?UHVB{k_8yC)Nfal!pT=;`X}uK!dz zU7aoZ$D9f{83L-+syCTTXgZyew24H5X0sXhv)L^7ZQJHHlgaQ0z-K%jlk2)XHX4n{ zvMhcEc!m$`$z+n!=``Ct&!a}8VX*)Vey+XV=$qep@_dm2s8`v3@Ql8_dqX!K?@{Y( zjct|dyY%JlL10|<6U0YQ*En*1`gUZ-7og+(xwHN=f@2YBkxGn93nYk2cpiL31m+qA zU=WkSi$x(pbaoxsSH1vjB0+s4b#k~LMi*Q+PqHAJlm!%vMOpZa5xM& z=r*BD#839pwMV`UebXFu9#DM(7ZUkN=qBNgr}l9NRFS^;g#AtH%I%m1^m;wIaP>B= z1AMn~g_l5hTYT^=*Zo4Fun^GcbSzpESX};302Cd(pox?5&*;Av@Cz68X~#t|>a+j= N002ovPDHLkV1f%4Mxp=! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster25_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster25_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..6062a3295c42fff5b29b4fdfed4b3a342d065819 GIT binary patch literal 796 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 Hu0mjfEv3Ac literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster28_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster28_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..3484b9f57a401ff3e3f9d4a03323aa93f996d938 GIT binary patch literal 998 zcmV!(?X??H zU*#K@%YmN*O=aV`Ke37gRSDQ^HqhNdu>*EpKJsW7UqcH>NeLB?ZNYuK1~!T8>E;gj zAB+JJV03&D4{!TKAGO#QhUx$rCy?>lx)X@3{}L^a6Ov0yl5ro}Jy-BK^73E=5{U$~ zYEi1>IFW2qgzWKHpJ;_~^1#{w2{@hV#%cEi+C70o!5Doehd_t>H3?`P88%Mf5R{IK z5Wt5ovok{O{BhGb0j^q=$}k%*1&82l&n3~WuGOL8&AKrHS{_ikS_>Qk_CQx;80iY@ zRS9Tao$amXiW#3wrC^tiDcan?0Jg@`hNLvSb$a2-$< zqOGfEFx?9bJTI(yavo@HDah2n_d)(xE3j*3tvz;AsIFgWUzn9H1k#dT~^G zsRGyE6~@fYN)4`aVyWWRk4JPLMGif~_EkKCER=LLYqCgWyzT!#ddL>_XQ_Y)9={rMI+AX)AQL zNz=sh{oS1VCz~>H!GZoD`Q`l1$?x<1{qDIpCwJgqw*Lj(9s*ihTZ{R89vd4Q(7vjw z3WY*J#&vadGOn(!7GGOiD=!+?ht*pC*joOlzNYeH_Z+d+hgFug-6_=rJqyddbI5zM=Aew1AzZO)3H!8XDY za)GLfwcjxmm&ysH-+?%i!vio*`a5~_LK5E?WqUy2KdN1N#Sia3=ZDkZ5Z-sE4^B^b zc`?kF<_0d2#RY>w8$O~2dnyZOo|ermxH4US7YN*}IJ_wumRmPl$d(D%R{6@ACp~&u zI*^(`nSfIJD+#CPbK~WaE_}Ye<_h3*nH{J!T<7cmbrOMS)D^I@vLd$zcPABA63#pw z_iaYEQE&zD*N+>6*QU~N=IOsW4s6=w3gC13+nHlX;FxqkFFssfj}v9^#ZOZRW2+B- z@98KkO#9%cr{BbWeCUHSU$=s@1MlZ^u7G+qv8(=d>A=_45j>>f*RBb?dBDS(Z#n<%^4w;8w;`sg!*-&;od7 zYier3*w`3mXJ?(oTD>>HKaCMiMkEq(1+1;DVPIgu2QOF84$Y~JqZ9mD?61Ddm|o{Q zknrTICumGa^Tybnn~B}*clGI51S~Hv!)xA!e>cX>#XY4fB#1|Ij@#PWoa4Se2#bK3 xnHdAO$e3LJpP;R-u3lH5*KUu0M*nF6e*i28h-W>k8lV6G002ovPDHLkV1kN2C#?Vg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster29_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster29_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..e57d2b74fb3d90480ac26adebbfa883e35af9840 GIT binary patch literal 1201 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 X3~39;{1d{{00000NkvXXu0mjf#x6u< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster2_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster2_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b140a222fb70f828eaf133520af8dbee9bb0b5 GIT binary patch literal 553 zcmV+^0@nSBP) zO;N@bh9Lz(Alh(2r_)K?(dIag=$|Bsc(>E((D8Vr`Fw7$0AOUheW^XF{r+zv`p9N@pQIs7e4h&99F&szC8U zDS&Fd9tMEz1Ie6CS9l-a(OLqP!`vdo0X6_;V6m8q=YGF0?&I+rtyb?@AC&VdYlF0Q z0i19;ozZ&zK`OzZ%#cc20BPsqsBeW}1GHML?D@wJ1HS#PP^Ssr160EJWm|u-EQ~Kkz*0o@!Muu rL-Ku}2e4c&4O#tWv!SN-^uOaD#QgaXpI-e=00000NkvXXu0mjf@}~G8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..a7081806bebd791d725b4797ad464aad0f242e1e GIT binary patch literal 858 zcmV-g1Eu_lP)S5L7JqLnkWVl!BB%qcJt$Ylgv7q*^NmR z>LDL&XWqtq-PTd&va)= z=*_cJJ!>&4nx6To5)i?aB`IOaPJ5#A_dX0#E=eMOh^A zw?I581Q19Z{XF1=a|aMp2Br3mQ|99~<-gZx+6;^7377IN0#qRoi9{SfE_y)r4#)93 z$7tpHYnqM25c6AW#7JCzsFFu^C74%+Y}2q(shEE|>G3BI@FM_bE=FlJIZ0!OofXcciZpIkz`g`f`<;}@9zkqm z7CQv)J^E}GpPW)TMMF@SP@wD#vIuZia`fY);t!p&L-v?R_}bhAUAg^%(p?$NO(75p zh1e)&0e3T>%WJ$J$Q~M|YFY%)X5}A?7V){A8)XlO4Gh3BojCG4^=#8H7(~l7XniTK zSj!==K>^$=DwC~;tgjbY8|J`0LLtEGvv}rq*2-&d9~WpL{iSamKp{d|=0|4R3vhD* z#3+_6c8Y;vA=Vs=K&=KBc@!7Q7Rxd$L&=4egTl5QBQ-X+40dA~2CH?m=f3%rVDpVv=h7&<~Uz|dBr6Z*5c8^8eO`t6HYoDHdF$oQc1lz>;Q-*ev?Mi kfnojd|NLJtBCuQd1>Z<>`qJ2!hX4Qo07*qoM6N<$g4oY{vj6}9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster30_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..34a781a28280c7cf0f557550083ea12312fd7517 GIT binary patch literal 904 zcmV;319$w1P)pYJ@bhqf61CxJ*LQqXmsTrL-Bnnr;@fZT4kDC5g!vy@J!MIAmM zm&=J1b$-8Jv@aA2qHj%24Xv%MQ8XHLDG`8^U;0&}fN`@n^mA67iB{zH86#=%-Lo7* zc?mRaTQRTeze~z&Gq;s(h=?))gi#*s{E1Ig4W7R~SR|6q=hX>d{Yf*N-{_m8-k$3e zkIz%*{v*XUsUP1dv}2b@87Old(7bb$1|KwRm{dgq5KUTIUpQY}{3-Hn9bHrolM`d2 zeK_1)Vuxsz3D~U{5NYqCzTQhT{PYQZc{5JKug2*9&?8}+`W&_G=ZFBd4NJEH!&{qGb5vxgLSm; z70%IiQv}S7p=c-@1HYgAK*x?ArlplU)d$^Ty)}P5>6s;(nf+>z_}fPXmISQ9|6tYft5qEO_h)(0o+_}FO`Iq^LDA7 ztttW@kB3+Vl{COJHQUTOaYO*;00{6FvQoDUCo@(eAnyWfBW%S=Bp6P`Xh{HXefc^< zB+AW_$;o8pzK#h%1N?m8Lxcy~zGq0Bj!Xz;GPPx!T<3@Y|LxeJ(yW}oHUfd{V97IT zb#;~M>gtL&C4iUH^768H#)EV)7!+4|ZEdX~kYtp_=rMTk;z`7tNAc=W z{4t*P?#Y8kJxDH|1j&-4LIkrB+<;`<5H^s3Q~ju~s;j$Z zVsyp$KM7Q;RcAh*lVKPXjYcVzN>L;d;deZf$%ICu5%=K%X0sVf^d*x?9`85~&)wPC zA=|d8(P$W21YqRzhc~oMJbd~>sn_0u!u34MO6>_DI>K`S=mgMr-26z^pT4I|7r_{tg>3lac`EEWrW0>T^F_)7nHK!rlVlYUs1wQT>3 zg6z~<0!W%5z+;usbwJW;6A0R`O%RFzjt_wF1#N>aFdyrL+Jc~j*#x);v_ZFAM=h0Fz9q z>WM{VsC0g;i=dJ~Q02M|C<(-3`X9^wD2OeQ-%EM-N5 w-?n10NZoE%k3g%{GF19ruSeU)mH!?81xN^5NdDrPC;$Ke07*qoM6N<$f>0!7aR2}S literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster31_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster31_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..b58c48000898d6d0389476a13562d6ffc2dbae10 GIT binary patch literal 1075 zcmV-31kC%1P)5dGiv%KbHTKKx=EOV_6n7O+z>wMqOPULZJ|!)2~n{U~X=XzoQ?C zX`1{=@8a<|$2*S0*T!Nolu9KG3=C*W1Zb0~#xA_-d5TRv+qsU$Bz&HL`&&eEUWEfJ z&0bdbK=pu+_?@dXLg`_%N1OFd0JZICFCVy+qOCZia$x?lK8xCV1oV?)Oyp{+rkWtD6 zC~5k62;$u8i!UoAfXY0GP|_+BpmVuvzV3f?dx*Skju7l`HXWWMlz0ugwBM z3D7Bsv8JL>CL%69$GDB$$~#a|VxM1bmmT`Xdjg+f}cGxtWAOKsUIo5j8Q0;`2pB0xE??`}JE=RL+* z9sfRA#Djal;MUztH;A#Hb9mp9$KHD`{z%`>ihd-&0Q;gTi;l;i)CurjKg@1IlMK-@ zIXzWIvl3lOFrCTz#;OK`>w%e^R?(NSGdV-Xst}+YFj)*gj=Bvcd6$~Y%vcUzMn}<* z3PX6jqW{6?Q&~&GiuHjAkO%7Hc{DY!e?>7J$vPWvFZCmAS9Hr7boA~$fi-K}CA}Y( zbb&q4w*R%%Miq;XkV>V>Hzk?Gj;RwzF874D@kBbA46&=c9*M*|H<9fIUe--Bf#&9B tq|<3N0>i_@zGr8=eBt~_`RD(Re*wi<6l6Y<|BV0u002ovPDHLkV1mkw_UQls literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..5c854e07c42472b0c313c9f13a779ae381a54a2e GIT binary patch literal 829 zcmV-D1H$}?P)3x11n1k_&YPJD|p{1j3O8!EM~+XQT=# zLYSa)_P`}#90AWUGrH=o zG@H%Jmd3wIC9!vX?a62k^i&`s#sm;XS{XU!pfQ}EY;1TkRhLKtqtVEm0QMhvc5@>Z zfs@c-`|?sQgcfB)07)Y>6M`J6Iv~b@q%|gh{h|aTs0R6%`Z}Fvvng%0H#f}*;P?QT z%=h&7r`c0fcuHilK^lJ7!yDQ{(R2KzWs12=SI<2NpU$R z_xBEq3ULf&61vzq)Q8v^l{OGwoV<;>M9u;ZpP0pM^JRYBu^#)>QZ-2V0 zN=#;>|CmLqH<->t0tP`#AdyITlj#(+dt(xCMh>{6)59?#JY2pAzW2bzaZc=1ZO=Hz zlOtzF&d1~&eUiggC<2{MM<8c@yw8c%m3haD#zYM5ZA%2gmq7W|c=gzVlLJfme9U}- z1?;_braAC2L=y5N1LwnuF;gHC-(FjC?)D2iP*+QUZY``Hj=xqd`2bIkgNcwH=`M8& zC<5G=>OdtDq+6=`M?p(~KAnE6mRo9xrWP=KZYTn}96)gic(wn8$d~nX>Ew1&$Wnii z<3Ivx1XRaiorETU2ozn1yo~C(e@dB5X8fhBRD}D_C7j(|ap(S$4Y#%==?CSq{FJY( zt%(o&`!bhst>d>XpU;a%qhUs%UaxDb58DpDR+quO{~iAWLj$NcEbUnE00000NkvXX Hu0mjf!r6NH literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster32_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..53c705cdb2376180e0ff840f3508f9393ae3472e GIT binary patch literal 717 zcmV;;0y6!HP)j9on^1=PZGCDxK>>2PcF~25-g?XD~PkIPtet{SVHZl#_I4oVX8!ba%RY zzxQ!Zrx49p{!f5hE@uvhLoy75g25og<8cZE0<4Xz+wD@j-DYFBAcMhx-7yx6#n}6% zX|lP|Xq5W>K9x!(LkR#%GMS7kH5N>zQd*Wan@wrIatI=k$oRR}>)G184^k`^sZc1` z`XKO#G638tQ#@%OKt`jHIsoGDwy2k!o}Z7c=fb@p8s!Us7`w^p?h(CxwL+hMU)cKZ zuAA1_JbOO-a`0dtl2#eOEnZ{5@QAkZbu05t%fcajzp7IF1<}^>5*?Sb(m7fH*ggg$2wXea7!2w;?RQFT%M!N#XS9dGf$!Z zOR4L*pbjVla1Z!Fkd+Ta&#XnBdn$)$?E;>Je!Bolk(7SQwE_G>FinvHgu~&fDG;ln zGJsgYbc>O$OjHLR9iY?ccvizF0Z6CQvjb4s1*@zE*q>FlqY?nGT3!h_i85sXcwlAc z9VOCpV`a{QBYHr5N7lZ-yoFQ;)=ePGuJGYO!NHpp(fY`;;dV36{vn zC6smiwq>(fs@Lmk0F_F`ko7kj4Vt#h{O|Z5SgS&2%`>5d00000NkvXXu0mjfk9kN% literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..e5939facde7933d771a6f5fe3b84fb2185dbb3c9 GIT binary patch literal 915 zcmV;E18n?>P)N_=%spy3A7lNK;BK_e3Q&}b~BsKR-t~d znVo+g|Mx%g&#a$z8UH7NL?Y2@G#cdbc*y7TQ6v%}uh+}_c&gPZmCI#5h6mW(+~h6B z!r?HV-)gn^+E6G&^?IF_mXd-;nq>h*spzOXs#nKlv`bE;Sp^Da3fJfxnOW;h+e#YLwUn6W$}2N z2Bp3V&1O?6R}w({Wx#S-nZcADpO`RZpBERo+&*9SMB6A$0!SJannz}Nn@l8VePe_6 z4-D`Y{Y);$J#*pQ*{<*aNLp0 zdcf$!8OmTiWiC?c(gOEFF87m-Tb0P6a1{b1j9odfcWs{X2WGez`kC@Te~P#3p$GJv zDZe^(S?PZ4g*u>3KzKj}kjTVmX~meP^M}9D+qG$yfH_CyvQgRuR7nWS1(M7Iz{eja z3CRzSJbv<&@||%N8CL}4$wDzQU1U9vKf_8oZOW6ZFUAF#?Y!bhAP@*x`cMKCi$zO2 zJ~l?hQmIRh`5>nQC4pcNb-kSji1`Ysy`XA^Vjb%p3AF3LRy70(fD`Gs-EK9ip{!U( zxg&u}rNVv#U2>U->Io3`@aWIKZom#u{UW$7XKpmL>V$B1m#Of6u>>-SBMF2T~h4Ka}*NeVW zUg$tcK-~2O;7Zl~K#;J{{c8du2XtT$k6So;K;(c3gRsoW8)96n6QPrHNt*yXU>F6n zAkDobs?}-~i^bR%&Q`2(bGq?7&#&=!U-_u7ua6()QC6a#ef6?a)yK;^KHEk{Mkt%j p>JeC7T~!8rgB?8o8oT~={0FhH!ktl#MCAYg002ovPDHLkV1mI8rN#gN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster33_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c1f6a81c97818fecea3a313afff45281e72271 GIT binary patch literal 826 zcmV-A1I7G_P)`6pHRCt`tm(ObxK@`VdekU7US`8Q$DU^a3ym|?E=%vt$*9snb z@(-|{q##9*;z`7VM}-PK1aDpnMerb0a`GY=MFo*ilUPIik>6SOJIib*o0;uw6zYTQ z?Ckt_pLy@Qvy(U-v;Cg{g+jp|4u=$pL?{-EQ6`h2Xf(>|_;tHoYPZ|04L{gmFkmIx z(&;qoZ`(E-n@Xjq-|thoT#je~z{#B}r{+WFw9XN2JpCbU36%mfqt_;b zK}56x5Js7;-v2cdhMw5cE`WhUyOumQBnYiMrGeSu8v;5`{_WOV5OrPI?5ngZ2(oiX45w1%p_f1 zKFjI|`PTIXcE7#zg&M8izX8DO15=6a`KvlBEi3Qc%S=o~s1!gjGUo_?&UEj0KN~bV zGvky*OLM=yb`=Qr0c`*t0lz`*T>VRPxH^s29SwReC?2H zIOGOxK#0ZjdDc$`5(>cI8I!`v;)NWm=km#kF^zp!fG^%O7|8Pao-!Io0wfZNu{sYu zCWkH3A&BT01|0;YLJJ_7oLr%pe-T7<3=892382~s_?9bzOgf&YFeU})bUMz}P!1A7 zrgi*R0OKIjISvHiZ^6ydFYnpil`N}^CGR8N`}_0zPypht6*O1|Bs!MWwE+D4fapL5 zq1#s*0ADWtEmx(%|4h{O8vq)>Kyd0X;F4EDSLQ$N&HU07*qoM6N<$ Ef&(dXbN~PV literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster34_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster34_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..cde20046afe570d29ef203a1fc303fcc5bb95fcc GIT binary patch literal 559 zcmV+~0?_@5P) z`XryNU4mrtCCf?jRN1DtQ+;R=YXCH(tMtKDU5Ci?+#UeepBliNl{vU+CH)<4QX~L6 zjja*5<-ocQky4Jq0dVWpMos{@eN3qtam!FArzPMVrj0NTSOZWNKq)IUk<%_fC*1Ae zrg8#sSpw7BmAKtu1>pOB?SLGF*v+#0l27jHvlRQESIk^9*^bybov6T)%)chrRtk9eVWhT+5zCnfm?_Kz+B%<3#r*t zCCb+PECBidk(d67SPR@stOdgG<0>E>4hI+xhgT;hW=^{@bHOwop$CJ3Jj(n1{*NQ) xGOXion-CL7lEe-mj$=W!uh(n1wI2R={0;Fz`lEh(#fJa@002ovPDHLkV1hw}7e(>l zT|rn7LG+>s9`>fc!X-iRpddMTS`0$KLr6B?iS?STSn2d+dSYOG5PGJ&rt8(~>grCC zP8t6vfl8$^9goKpi^V9BNKh`9qj)@S-tp`A`_%1r%@}^bXf!e{#aYPDL-ivXNFzIt{E?_%UgA07O5_J=OP^{3U@^V|EE7T$erpoljC$fzNcxE#xK zkd0t6nfMdH`fEr;cEs9An2jCOQUXXCjddu1r1d5cv|h^)ra&YD*gk?~k@-dsL|THN zg!vbs4tNvL3J6?@7X+7Wq+Ots5R+Xl6sTA%h7yr6v3>dC8y$8!#x@cGF~0NayP52; z-8Lk?a)s1H9&B&ZnAL(}`$tE!G2lG+!MXIIZSy={1X8Kg>=`vaoleuS zWn+VW^?G!MYya+GK=0Y1IN9TI3MzIA?B$XcWqCX{DA~|9FgydmpUOEqt&p4z#D&$VhC_OI_=SdD;PwRA)` zIkRPJRe4FJ5NdN!< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster35_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster35_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..fcf4ab97e2f64e454d3db74cb65c27d8e2a253aa GIT binary patch literal 633 zcmV-<0*3vGP)W(6s$jS&Pys%`7NClN zjK}HJ8$Vk9{mX+t+MhO!$7AYtyP@A0b%Ck~xloZC3y>G9+V0)9{R_t*Z0GkoIRZg1 zU<(k1CL0hw@b$PF0J$hY6l0tSrGQ*6cXbaD07NVn3yK4XxiIp9Te`qVz<$4v{DFu- zqtOV>0Vbzs3D|D8R4SFcYotIBgA~`nQ5X@RvSgM3xeMy`IxUw=PXvlk1rY%`60_Ot zN0_mIDA$Ve^I#-Q5E}t(D7rvLF4l_hH=9i_3W)^BC)JV5B2+;75~U!MQ9r3cjH(N6 zf${Tz2{FeLv^4+=6?U8iXv0MR1$Y+_5F!As5Yhi}vwz8Pnb>!$uDFL%zl_nq^*=bn4+eQw-m{67io>)Mx2rBd?WFbo*Q2HX$a9cloH z^#l?d3A>L-ZKaTmCE@b9L}#s7@a^%59Q!?n`O*2J9TOmanj6INSI*($7jL8SdN>zslJrHROKADH#U7hZrt$5U@1WjS1v3`4+v7*iNx%7(sTTo)M)El)s;X)*{pxfU z31TI=F7L6GsKiq+yar0DOY{gZl*-snP~<7Hqea|KtfT9t_b@vAuIL#dEdr@TN{r}W z`t&p!(Ty7iFWAmi6rZd+p+~?~;zIX{eq8wct!sNpumIhSR5`43sL!U zb3r|wa~#p!++5HJjKW=c30P|ug5Lx)?`6NKX79w2BTqZeRSBg7nW;%w;)(th~RD9+sOg3t2eO6kvf1ad3a z=H@2c?t4QMiF^Ib1)tAn%kTRy;?kw>5q$6@R##VX?AWt%AZZa`5;~0%kx0bOi^|GM zThDQa4jsnLo3kQMOt%UsF>f5#UxN32sNq1S8-qR6RXC@|=9M6`%bQ7Tx(D&+8Ll0@5)v zUu`!MA_?kLT_D2Yu#9Kh-rkN6YOByu(}>BQ=kdm36nMDsB=cWL?j*$+A2myEx5>#X zc2r0}B_q#)@aZsSXJ^sb*(tiQ$PK)>`w{#b@)9U={e6E_^*#{TEi%`ZWtni6=F87r zMrb&M-rin2Qg3D=z}Zu7d$~=I0P9cgG0Zh)m}#7mQA89m_7U-T+)mV|?#gLP^FDwS zvQ9t#&vnR0os`Zk%VqI;z1ijxx@SSAaPY>fZaX~J>5yy9BUjy$)jdIx9U2AdeJ^Gm200000NkvXXu0mjf(8OUs literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster36_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster36_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..cc21a3f6d57d6ee01d1b9a3b68f4742e9300d872 GIT binary patch literal 977 zcmV;?11|iDP)5UdxoBziJvvj+{0G?1iU^`TVUh0-uxRQgfeHry8M&Rpks@7>?K z8uq=MJKwo`=Q}fV&Y6va6~_N5VDtJ-^O@PX%j#&v`4PTNe_s`q0Q!MH3%aKq!Y)p! zq*2M0?JR~?S9gG|9OErU@C|xG3JWQ~;O?i{`q?DeF*x9WKO5?QCxJb2M)2$y9YGjJ zx&_RctN>F^Xv!)f+b*pfxhAmEbLYvTkPdP6N`Wy6;0VyT@TT%P9MCyNsck6&I0Bt< zPVv#XEUT!2<|pkGdIZ&h3xwU4p9^-0L%zaN8k+!IE#{lioUk>3V`0JUC8vP%tp#%_ zdpuMFSPNL?T!dU3f{#@I=i9a~2VQjzfGJ}wxJSKWe&!KCf+bnl@f}0t%x5tNe9P$m z3e$Q8Um=_{OhKET6o)3%!m=F#McIDIayN+J)nbK9l8XNDxq0+mU>6DI$ao$-=?=*KcJ3J-s9d+#tfwbGiheGc7O*2#f^cr)K^`{{WmleF}CL6$%cW zBd=S)&DtBVW#c+XOU;13p&`gKo1x`J7aTt-AIbhdSmj=bKW2s#RaLNNwSm%b<=S<4 z*8Ws{2knaTa{U6(IbwWr6efQBA`#>6Nhq+{C=!dc-~oU7cB%M`l>e)jFVU(o3OJ&D z_x=O@0{RAqAuneeIloYI5vpsdDJ|$6cY^`sUE&*D+zB43_|O@q!8kTT9NNgk_?SKc zN6y`%LQFHIs+`lxO^O!>`&HW!fjPf@uL1TJ+8`3bo&%L-XTZ_g7K;5%rhRFq75 z;ia@A(1uv9W4a4Kjzss=WAQfk1qjg_xSXmp|KaQxsD~s9eat7Jvhh%!>)00rpCg{%8zqTK=}MTB9FIWq?Jb$fVUq*^Z{Xbbc)d18AYrChB74xtOew_COTaX z>IXO#SQFYlL6-pK>iA9U303nUx+F{=3gONu9HNc@c1Or@BxvOe9M3bb0PT_h9%B*^ zECSpSDOVM3pQu|vun16pn5d??XVhYOx?<%AHNBw0AJ`wVV{FA}S4d+dA)zDS{iL#+ zv@b~W0bI`;nUhAeIwt00000NkvXXu0mjfHo?BR literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster37_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster37_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..9cba40be3bc9c5a2f7fdf3dcadc903907ab97fdc GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5DEPH1QcjjKi-RdfiD}I>o@*y4SaNNU^zl3qFo&(6 zmFKKX1NVekKRn79^tdk^T{(^0&)C8sKzxq!S;j9+CWQ_MHgXy4J-Dj*A74YHpN_&Q z#wAi*OhaTil`Be5J6L%oi<`&>2p~43^pRZ zf|cMsgQZQtLQG*AF^vI#IP?@mjR+^t1X)1SG)9Ca_E9@OP8CuCv}jlx zT8H;LLFO)H0bza>%cwe9CkJwLm59jXD&urr2g|agF^=!y>6u=K+JMtwj<)(*0nchsx=4Za8*f2*Li?1 zk-R)>!dz`NFb@ThkoERrG6Aw^#vNLZR{)0lEefd{NAO_R0ou_Vu>z3vq*4i(9qR{^ zmr%}|phM9WfiV2@S^MA>Y>e)}eq+0P0Yu1`RNruR@9o&&2s!8zMYm!{ub=ouwA5OI zvf=t)6hgpubVD2xpMuT8kN-(PSPbA81E!M;;B)(OsRWu6kSxbL#|wR1dpr*8oWRIG zSJ+WZ^dcf+492MRihdS-&-caoUn&5}=|RG-UI5?Kn*+xRu)|FJmcRGS9kHhwc~6O` z*~$O>y&otY5iBNP*Ect{RIGZbs1kN901@>V!BX|%(UX8s(|1Zd8I&!5O+c&#@K`1! wj}_4Wl>rsB-#;SHcwzxz|8T#BKmR-a2H&Mqy}ZU-$^er@{X}`YzwS;ldvHA%RM$@~G#nQ`lBm&Ty&(=;CKb`k%|3@W= z4`Ke?t!}|Kd(X6fW}w#qu$@XJlRy>iSIaRx2R6&JY_lQEJOj9v7=WuiL^A+MvoIV7 zXzd~6MI_9^a2$aC_rUMo1DykCyPE+k%aPT`L6Sfk0h)=IroDV8$b;1ZJ(*s(`E&tl z1<)49NoBn%Cg&zaA1#&X`ym1V1gzw0PK51PVAr)%U~qtD zMG{0O_W-g&g))5Q7}9andI>};fc}$NLBa{{rNTg;&(UE~j(S8bGL? z8Hd`{Y{xp-{Y!72d+`dSIFqO3m) z0D|Mx%VV(v$iXoX9L(4NDCgXg7y-lyHeEiZ^<)l6*gOM!+DHX$uyLQqk)eNYZ+r?_92c549nB}=_*eMADN{^R1%&u_vv3;LO1AKIm8 P00000NkvXXu0mjfb49Yr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..25da210526cbc0499045d67bc6ea8f47e33d54b8 GIT binary patch literal 1785 zcmVm! zRS`%u4IohvH6}zw1EnU!1C5f1F`92&J^zBHbP=?Y7%JXLn|N z@86{sXq(-{L|?L*ng4k2``_`se~tK$<^Ktwq@+aGA`w8AVK5kwl$1oTG9*b7^Wkt9 ze!pML@i>dBs^Y0A3M>}O$T;scnM{a~zN1HvN^t>TLu+rl13ev`2w&(&k}6^Lij}x^ zMHPmJJn(piaPYBputY6K6&YnjXkW+#1k?y3sul&S=qQ+0g!df3#P0zXHtun|kwot{ zvl)c}6`G?JUvGIC5*eLrG6R|hRgWn$8X?iCHTvlUB%*5=3s;KRTfd4~u8O>qFS<1!tX!LgiP2@dMxtHY;I34P99bTT-lv>1*bz6L{;2}Mu} z#SehRpoAdPi8;wMDy@cHZ$p1)r%=wn`gLmo{*99F_I)g#b<3+p#yBxmu8u?iFb9Mw z1dxqTHC=pPG#sEac?nc~hV_bliv|O@n&xcyr`$CPk3yeeDVzWRMouBnWK94N#$$0m zKy^My9CJ_keaOtr6ysciK>~cZZVwv$0aSuz`(%B9%jdib!%|w&>`$@ZAY~~YLI=ax? zxw*M;I2&_MAEJbe@aBo><0hMwd%LMiyGSx**wX;DY+)*fFGM zWKf|PMU@OvNRsV#*s`CNMB^Q-xUWk z)6o;#ZGk;P@FD>e)A~GxZbfu}eTe{I9xzfOX31j}@6MjDXcC?;3aml*dmOX^BEzjVc8|UE}*E#IYFNP=R zyFy>W0GQjo0XM<~5LCRYisM6-07mG^KZ+4 b{_ps2J^2V>fRxqJ00000NkvXXu0mjf%h^eR literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster3_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bdeb1b20779dc7da73264598076a4dd1f10337 GIT binary patch literal 683 zcmV;c0#yBpP) zETf_*s4Pp$^W3y?t=DT>E|=yVE?~FYnLFOKS}imFcs!bKo6RO|w_6&I$5|8s7;A&CIe2Y`sQc>CJ+9p7UyNg;q>ScEdpp=Zq_=$p^ybbfvt zPk=ojA&qDx7;+5Xk)laiz#^2n&IUDOF7SJVGKl~Wwhd?oV@M#J{r<0b0`+>GPK6yJ z#2;F6K_$>=G^&qW>XxzB`nZkw`{3LMB((h3GC&Ji2r7Zq>W#Iw-P+k;BgSwv0nM0C zbQbK=lIfxt=;{$~Qp|g!X*jGk`_-GC?JPlk4$uMAz3psy=N) z3aOv_xH5_+P^*3H4k=$6X5%M^fcF8oE>smsXhIE<2x`DZB1Zl4FiIl8wZ2^y1HM(E z{_FL6?=;~v?j!&W*awK5NLER#aNAJGu$KUPz=hBOlLDs)%JQz-kbuo*L)~uIoRkby zPK(9Dl<^?l>2%Cd-fp*zkf9}P>-cReiat%J(>MZ?$t2VIXR{goYkd0O@gJHUl4X8S Ryb}Nb002ovPDHLkV1oUSJYN6+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster40_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster40_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..62ce9a61c8c24aeec7ed075acee84ac3428e5ade GIT binary patch literal 637 zcmV-@0)qXCP)UG^p*W~0iaI*fA5a8A z6a**7(zyg&Tm`!b;-J>SQN_}t4pMQeC_>dm#Gg(sE}FaK+Hk!zxtOZ&(7Swh>HB>5 zm!uYdtp5qn=x_R}mf_pWYmF@c(c?;Dd=wnlJG?Z07r?ol7W*mC%nM5?s5u>kX3s#9x-qFolk(<{0O%-a<^^RF zP)c!ft!Ba$&bK}Yw{o-yqse`!Fdz&qPS0z<0U&LZm_$(7^&Wr?F>gLJHiGW1j$-WM z>KZ2p@(`8)%owmYCt}yK5S9RRMH^d<%{4DQ>mwo1j{$fXwh&_tH;5nTab`|Rc1_xM zyau4swxADlxYw#YgxOqHQb#e_4O8euSGW$bY`Iy({xd!z&E5luPPw+k8GN}pTEFc( zgIhUX17^{~=XRN{2?kMB0AA$eqY#F9`)RN1QE>f6#Aoh*zoTGR*-vi(4zJgQ@u~Xq znE9ZpbgvY^Xvc~$9?zX)4|%#R%||qQAjLmI7*)jgZd|T92e8bdrUw&gU~fQ&@MTI* z!ijVMd96KP%@NSGqM1#WMaeTDSm7>jMu17nl$T8Awg6@wZ!getcqSoiBXL&paZdoO z%&p8AuoDPJ04zhhn5d7Pq^5w6nTKA~$B8Tf9!x7X7+SUJR&1-(M;d_teygVb{OkA| X0doCfEFr-D00000NkvXXu0mjf&^#F; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster41_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster41_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..1211b6f7b40ef6b6f3b917540418f9c168028e98 GIT binary patch literal 480 zcmV<60U!Q}P)xJE1&(b1f|7jKQ-*|YE6>{9qQZ|2R;{(m#`b~jsuU)J9R z81Y8CuFalc~wBiLB4#_}~qF{+9X&6idxusA;#=C5vUDPPO729nHC z+?PW1^(w|yH_m)3P+ExrikCh#KHF@Lk^4BFDS!<^Ypw=ZeSd?x#f;+on7|4QP(0CBiKs-0000^1dC!&yn})s-9ivhW^iV>%di*B_SF5x(3-ab z%r=^o1Xpt|ZypMtBnN;j{{*xg2Ka#S58|VT1_-n|u7F1g$Wj=n-X8%Zxkz^aIOvZ# zW0k`eB_NBC9RZ_3V%sm15d!Ewg!vvFfTDqc;VO#d$bjq+2;DUaRiMER=q)6%U6>Zx zOPWHYpbjy#n$B==tqB7@K(o347KH`CklPM&JgE-A)sw*mR)H~cW}gY6M41>E@R)_w i0oeL*v;qTO9RmPq?9yOReg}>K0000Qf=iKRk)oSgx+s`M zx~O$52^7@P4nj+jE~Pq%4gu>TZJku4ON+P&E}>95G!;!XDg{x5$nQQ+e0k0Lb7M;V zAiVqTJNKUNp8MT%Pj<>S#;}#z}XAC%(Jg2C6@;a@^G@tJnP}q z`J}Y9#-#hiUKt)*srkmZnZ=Skd-AjHSYHCu4?fGGu2|K<`|m&eOl5wy>@)@(+v@ut zEG+OIw<7>n3l*6zI7H?o97N#F+i%r(R)2r?W8j!bB7{gf9ShtB4fTh0JNbkXP^V59 z{cQl-<|TwS=4UGsPc%Tl8$woBFA9G8zh!A1M{^G#?n(-QeU4&MWE;SP03_3lF#P@pWx)_4r70}n5mBE`&#j@ zU1!%(I|5OGgV!&M(%#W7PhZ`Z{@z2*E9m9jjLw$2$JL1bOPh|a^~sPggPC%GHTutB%sgz-8vEd z+A$%I9#6<{Zbh=WtVy|x??xosku~4xOC_eNiHi2~nJLpIJEqe~W5W+Ll!&N?6et`L zq+9LBk)~zZ?o8O$nv^K8(f}mLdSpXw-xznCx-%o_9&}PU#Jm+!Bm#Qzc!8tULb- y4Hr)&{7j_m5w=(9L1P06)cX&&RoM1_$G-t)Y=dB+2=ie80000S->P)HwS$5Ed2rPi@QIzJ9|0(_3drXJm4WI2FRfX{NG9DvXF zAb{>eboCU60HG+LR6S84fR9f|Jw*;c_XRFKI*m=9tZYaRF!&viQLz(4Y(|GW)zss4 zz^bhm!J6CK55vVOD{aBz`wqXrQ14_bfm1zM4!C>i6T>QoiwwbGats%4d|)up5P%zo z%OVg)R}V6WEC+0R_=AA~h!1<~Gpt?ph#?F}_szb+AkWW*)nOou9)A1=RtHm`+gR&kUn8xKWm_^zGsOn*6ocKUS2ncYqgXy{RZ-eQx$6w=g7)q>E6PWgL49Ds)nAk_4p5?oj!PSH4hSsG(8CKFA zAfu-Y*4zMO!wkdaFoZ=67-ArEt{;0ux&tJIr5I{DRDgLKXfV_uQ0i}4b_c^@FpFxU z5b8kyRtD@Q#{tRiTnuw}enTlpKzx|N*epU<4+0{;AR;LPCD?|cNuUaZL8Q{Upio3$*i5Se$;gCOP#_WP(2P*q>5M^|;hzxzBLGGKi~tw`Falr%z&8)z zIq15FQaY~ZqC5qfE>|1mR@eP|*?~$9OfEN!W9i6O zM4~!F!)f$TSU@XWdzhHqr>z`5>X2qIlo^osgm4{&IUTDgMaq7t5c=_Q`tzK+fl7i4po@?;s~Dk|tW{swo})v=)Vc6u&d=5+U8+4S3u zJhkH)=FO{S>ZA$mIdFjc7BAtyUtj0#o_ARPt7iVveFohyxoN@#F8B43EGuW)j7k!v z2~6E^`SSDsFlE|wy3d}*b95eS_&INOo#));Uat1_a^lD-rrtb(T`#{(&4OB7WpU=r z+kE=j=UnOgI|W4vw(ZzPbJH(5dh8f8CQs*$u1;d{5(ZNPG`Ftj$8`&NdUFfQ8vn?X zt!*-i47PGG9mnQ7lO|H0DB8LVEpnrKMp*lQC;F(yNA>#48pj{EVY{izQOeL1ne67odqaCmF=3A%PyK_5jTXzTr zlenXFNhh-343U=o+uOHFG0Bl=ocDUKU=3Qh^1EXBFHk~p_sK5$ zuMbKN*phK(U`-PV3#BAgRGw2muxuGmJP08jO$aZO;-)NioDc=cQNDM{is*_G1tLOA zc+>)Cj2$zUhzQXark|39r4b1(C!ee`4MSH{d^;9|mJ-p3@-Q{e^V3pNN(I^Md0ueU zLMDIiJjumN?@1_aq2Tk5gMcpU%!M zX3nW%=X1a3)*s%&;f~`hd#Hi^hhC(4RSU(1g{*B|&Dri=_BZb3wZnhn;L&4ro$6rL z?3q-I87(^T%gTH`6`UEGAz-|mOxEY$6?^G1JS~6d_@2r-EKjC~rOcaC$ECkrX3p%YU=q4m`0SZ;)YL2x zp?iV2eb*@YxSCL4N!9nSUSa%A(*>a+$z~D~zLXp&4=lN#uWt+rVw2x(dxmr-&CIH5 ze9%6xhxQ#Ioy&@^6|HTX>CdLv{lY#hIdqgXWf+mb>r*SgANXH4{Y>$Pt&14HA{L2b zmKGX>zC20l+6jD1>V8Q0|90ZppoGL9Rhp+rELe^CNDECjn wocjNm#UY;NcT4`=h8|pfL0e+QF-eF20bs7qqz3d~;s5{u07*qoM6N<$g12Qw>;M1& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster46_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster46_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..b4dc771bad2c4c3810e108e75b90074efa24d2c8 GIT binary patch literal 719 zcmV;=0x>aZB zZ)oTCZzz-w+B0;@Sc<`vb_@hOgou=2Lp*t~T489b@1*D6oliebDs8_(?>@b|d+*+z z-aWPGALIXY;P9~jQ|4XIQ}lQ9`PP`SJ~ubhdzBpkR?CHupZam~ycO-o({{=;TN^HL zt8y>Z1D!oL&rG!~coX_rYqsGdKP=SCya<&XfH7VT^VG;JS1j!Rms@qjUs@-K_+!R zK5)pVeHv%|!|8>wf2|1Mo1U%rlu2aSON_(d^L9`4AN%{pek{A5gFH|#0(r(??{tWM zEa}C1B_fg6KRrtWy9fa3-l>eKs54-=Wj{u8={Nkks*(nGpNPnT=P% ztA#-Zx6gLhzh%4~fnIVztrL+couaTPJ7i%}$mDIGl>_=Dt7UpSemVEZ9bV94GEiiZ z^R+XfDXBbo8VS8Fi|zvJ2w=bCD6I)U9$aQ`FU9?C%i+Y`ym381RyCkpGd8Y>WWx-8 z7f2P5iSs$ks9Y5TSfM_#&bfXZQ8ko0P*(HlTpicozkvT{&M3`tNI-H8 zh%cqH>k2(5C+Jy+_t4jJ!1N!NmrBcYwH)}H_yq+(;GV@(ra=Gz002ovPDHLkV1hxX BQJw$* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster47_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster47_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..29e411f41aa44f37de3fcaa8cf70411fab3217d3 GIT binary patch literal 1526 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 KMNUMnLSTYPOY^h< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster5_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster5_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..aca3d3fb77b27f2437b8fef9cb5e7e3093b675b2 GIT binary patch literal 588 zcmV-S0<-;zP)XbI%dx&%oD)0#KDPSa-j0ujsI6)q;79cHPA~zvRM4?@PAOv*gFN;C~ zvRoj+-B4zGW(ug)YMG?E$Om-hmwBL&fO@^24p!Y@@^jflm7522P(_p_Hwri$vdvZ{ zo>PF$F1V`znYF6S1BC=sX#sf_6cT`wD`z8A2CV?!_vydFz?cUhz;qnnT>y`PdyCKt zz`s6sfvpH#zfxxbVnF?W;1h8Yv~M<>^m`tml>m9$F##mK-rJu`OBom~5Qbkjzfq^t ziQ4UUdQt+T(TH}t-PIzI5Z!9E#8KXCHh%*-7HJ*VHqU#Z)oNuYU_PHay7u*YO;zLJ ax8onqMH*R#H^-&`0000W0nK@_9`<&;z@AJNs!Drk)p8$G#dXgxLpePD7O+!AP zhpMXbSzMmy!EqcpCN9y!FqFL*%jI%%ev%~eTf;CA1OW~oKCDa&fH1Ou*LK+L7D^o* zD4PZ{dImGf75JV7*AHnxg8}wjJc$zm$zY_>fU2mdH(H1s7iB|*9RZ~oomjPY%k&u# ztvNmdqtpQf+(n^4<0cGU2M8vPxhmhQ1S)okY!+$~!Xs?2!Dq2_?GG{hn@2IHZwHR;`!13wrqKvX?s*PJ1~y^w<`)EKcyH$> zEZOoBjt*?Z;{IJYvF`yaT=xWyyt5yb75xMqPal9de{KpL1~C5iPmzgz#9kADYvId% zJ25nHFW_5zwlVbhw{hLppCI&Xv_Cop-)ZCBC+|eh`lq>gh|YWho!^U1O&fr4nu!bN z5%~@lt-1&Q*t>-WVt96oM{_|MAr0&;^nUL}{B`?xAiS$wDwFOumTujHp=a*G4gI@u z{TdjdE{G& zok>Q~5Plrus}KJkZo7_oxBUR8KRA)@2!zA9whzUsBbzhOJbwmV z^X4G0EI@wN6^LvXn$kv0;`L$?9z*WRg;&F|0!D)`kI?g6_C?I>R4^K=QU_8o@WAtD zP@S~^t%*_S#sb7qKwzgi7DMB)B$1D-VKV+5WDJe|LMII@MAV~sS9Qa&$1#7wTt0Km zHPS_a*nvrhN&+9be2GS=evJLv%vrFS^~p01RH|PD(-cdD$mDdCDg{i8{1+qVIVY3B z(4h|y6R@sp=>UkyaiVgk2K0 zCjth(pAvvh$+cVKD3)t-4_sQ|dHiy}1au5A84<81bX?EblI5PeKUl}be_V9Uzl7!Kf?1K;GF z`Xm6+@>T4{YHVn}m=1vN`!dut75F%T)A*P@>5w8__b$5yP0BSNQ0|(E!w28Sn4?p` z1P66#TymC(OG^hp6c@Tt#%BLz>_tDu#%#XTB^rCppU@!-lY|Q^7Xc+W{sAgUjqi9|$3L`_%NAAA3OTyyu`@?MCA zzkWSV9z803qcPE7IOdrj+KePkh{KdBI3)lfqoMDjJ~oO%sYWJj=}m=l7xuj2Np-tl zJqp}-qnxjvIDvsbxUyu+=n)f{$7Ey^kj}XwY|BmuKsUb_n>nIxN z=wvn=KL@>#plFIpsfi4kK`fI7619ki#q_L3XtOrRh6E^bN2wcEyp{rh^Z}JQKlJg| zpZ_l374tc)UU>`ta^y6Y-*g>*Ie750Z&t5ZhF5<3CT{Lsj6?4phfBr;J4+Vzz(`u@ z8L${q4xQ%aGJUsv>PoDfluNfH`!Kd9m^S|T&0qbj9CV2jj1poj507*qoM6N<$ Ef`~(L+5i9m literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster6_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster6_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..9a494a13dbe0276a684ff0c0365345fb16368c5f GIT binary patch literal 627 zcmV-(0*w8MP)A3y>U5{#V?8zbTm^dEKX%Gi$mJ6*f6 zFtZ>g76ya_B77y~wR*@gPHZ=o=qsUciQ%3*pU+N657z$#7z_s4<#Hj<^C$=cisP7k z-xoGMhr@yP`@MLE4|G1C#TCz@C=%ndEEB(NG#Yd|ooF(dcvb*#ve`WUI;!37{$98H zr5$TM1->8MzNcxDv-zGnHh<5z2S6I3>2yq;PKT1X2afQv_*;b#c_Ikah;czU9)*3*bFZ`M6SXLPvY|ela0G1B~`ZDLT zBNbG(0pT3YUKsT0c6e0S6H2`Noj!?E`$Nbz>4^FE9MF^>@K+S?0ec4zi0Cg}& z!+$JCt)^X#+$1ePtyas~raF*8?;}sBOj>|?y?*<#+Hz%Qs%$}x07ZRU=d3D(79dH= z(^e$c`F8@)ReaIaMaESiM`hFdRh#z$CjjnRi^Yd_eXHG$ot5ncP5_(%T|pJuroF%k z06P~igrbO9wtImSKp2LEB-m87?OxynfIa{Kkjssz%3k0Ez%_s~AyoBT=sX2D>w`gF zK1D5Amg%%?4S*U@&kwp|x6Xmdp%nnX?G(w?i8BB)5XYanW7P3@q;|V~+bJQOoVMGo zIK~6I)oO{YyxDC26mlxsI$qm?;E9&Yr5(U*HuH4%SF08MwI2R<{0&OafVhXFsipt` N002ovPDHLkV1lfX836zQ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster7_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster7_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f4dcdf8710f9266a56004909e8ec4d411eeff9 GIT binary patch literal 1800 zcmV+j2lx1iP)_c`~S#Lza;2@4e>Lm?XhVciC)8&((H z6j9c~*ra7LaI~9L#uOD>d}OuTWTlT4>u_~0>y}jtWtF(1n`v6RCb{?K z+;h%7&;7pdCI#7z-XAmE%GnX(q&^!$3?4X~-3d$l?eQ|JAyOh4=nR(7|$S+5?EfCdx$p z{YM_7C^bC)#17o?wQu3&Jv;Hmjo-wLKS$X49{ z;5O`k{WKol{)lWJ+V(Jxo;WMV4^2$rz8~C=FMai1Y%R@TcVf!iGrn31SVoN#9SkRu0-hV8Nh{w0IRRO8k~hwE~44&Kn0d% zp|{uyT5&|{RWziEh1C@sGt~f(-gbA}!^U2H9uw1b80I+?2z+|#_t4pDmeZL8L|Dyu z+a^VJuWBl}vyYainf6?}^4L1#AuYXK_M|9vJ zMBvs?VEE0DfbLHQ-}zfAh&q(te>D{YMlY_JRi29p<=eC z!!$&1pRB)Ao=?nNa%(-FVSNwmVreSDk2;(Co7(4k(+DQ$U<;wW>wYSN24@^9RL9v)w(Nt1& zx}TvlxRANabQ&(^|D2KGb_`+P?tK^-7{KM|!kOKtVChXQ(>e zSc8@3`BmS zz)><}hN!#5AqsNzigOpmO{6uNp?(Ar!RO6Eb}qF!_1rtOQ7 zWdW#sXx#V1T_31qMN!#RDYMx4pbOUPwM*Z5K4654=J=FTsg9It5qU*~_Wu4poIN|U qG5}LkQ%bw>+1XkAujwOy9se5%7Wlwb+HQCN00009H zyE@i61z}h@+^6Z%J`V=Z_PO1DvNk#P*cQ4IKo~X0+y>`x4Dfr6G>D{W>P`Up&vNby ziUOb1Spq1U?;5k9FaudL#=VRPq1Ae{?Sek&LV)rm9q|uq;59+`{Op--x93Ly%ZJzx zhcAZ@YBS`Jb-*X!l>%NcGQ8a8>KuR$I1``obRcgza$pj9 zOHn0&oh#!2b3)=;s00dyfh=0zrvz|vn$2eR7!T65TFq|d)oRriGHMC3j^DN@ sYMRk#}JOUH1Tr&e51q~EM1&zgD zU?2v9lei|P9;kS0;DH#4U}B)LCtCR6~oE#1Zxm+&F&CMmJ)5&dopP!!;3WazKA0!rwafvaH$HViJ$t17M z$;qK;G)iY@XAVmMpu|5pNw05j6b^@ZgY4{V%FD~6xKb2}L@0^HSwEMH!iWM8RdW)` zfJ8FMW5vbAG&(wJodL+><0FODX7%;;R9affo1C7WvJ#Klyt%oVt>53@XTZMJR$doR zBgtLCS_S|bL1}GmE#2JQFc>fZMG&9QM+XN73+8Bguq5@>)m7^0>CxA(t*xc739$u0HUO287V z#)+w^siE1~SseuC!d>DrTMPgQK4ZJ0qJryzKtK;Nl$Dj0{6PRt)(CsHP62{YZa&#) zZf=gcy1Mi^uohzoOejWM1oJR|XlRJrxG!u0z+~KLF?Eh{{EV!epPy4hLj%`QHa0d= zFc{R=8pk0pBGV<55df5asHn|X=T`uTAjpggHa0e>Rl5b#jT^yR27n`o`#zxsAFKeK zpw%o@RaL+A;kXL@f0B&%0HZb`&ji9OR+VQ2fD8y05Il0L8O7{pW4~F9cZg*Gpr22I zmg_}~)|){Xl^aihfUpGsmry$EZ*On;fq_gXz8@JG;apKrP{3*T;o%|W+LcF*EdWt1 z5v4mmB_$b*I+0_CXveXGba!{_eRd=*08j|8$q^J8 z8ylnX@o}1&nc+69g*)Eg-}OGM#XPe?wg7;B37o#Zz7!Ds{ry}nEiI+2LBF|=G$SM> zTLvJ$M=&A-!iNI`1GK!nOn(vqD6+V?XrBQrKp@IOyzL}CgAK9PtPFxV!UWPZ_Q(`V z83DlJpzRJ|0Cd%`YQ&u zwzg89QQxPhsj#q+bA;dT=e~)F3AR{VgY-Q$HN}5Wa38>f4H$!;o4dO^YXB}UFVjX1 guGxPrU;cOe1Ig&C?*D@zl>h($07*qoM6N<$g7eD?IsgCw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster8_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster8_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..8a4ea70ea58b6ec6603332539e5399a6d42ce423 GIT binary patch literal 596 zcmV-a0;~OrP)Wu8SKm^YX3CD4S=XoLs z0^zzYw&8a;97Gs~_zZra^ZATdc;@>)j!%*V|68xu#p!eslgY$k0f3Rs=E-_hyWQ`; zPUkywEPD%F*H7=`cz@NVK6UJMpUVdTH>#5@7Vo0leM$S|whEX962~zg0QO%sE<>p8 zJdqdVMHK=-&|G5d$~Y;jodu!xhcqDvK(}99$)0+Ad^QJw^a061WCH<$ZG?G@wm=s! zCX!wN20Ca=7E2eQpDXImiR;!|{)GROp zsMTtCEt>__9-ulfn~klFmGZ!TZ@+R=X#u#aC&^yO$^s*RvV};_7OO3ws?~0{tsyw8 z*8<$46w{W_yTAxQ_vSKDDGyXCe|K2Utpn@z+A0pXtJeZR4D|bBOhqn)iP1s;IO{_k zav{ig(P^0t05JfWC>JAuAjvS$Kb^iJEXN=VfWCIf1Ej&=ExiY$BrAv18bAE1rj5pkKWfz4q}0Ti+B6D+Bt=uBEsY3TM8T;%hSv-;49{Vh zo^{}kkdkoQe%PJd+;h*p`|P#%UVEQ&^?1Yb{{*mf>C#Xz7=%WnfljA`*=&YZtCi2Z z#>U1lGBP6H@uEyjOvpRmMMOl%??a)G)a7$>ax$8mo6*qFpqUo{jhr}f0$#6IE)o|P zhnSccBqk7#P6N&=3NFfSl)CY-}v@^YgKB<3@E6p!iOm zf@jALEWCITw(@dhA3B8KwQI2M+$p{FUB8aFty>Y~`1Wns3kxw&S&6LOyWtk^OhUKi z^l7+u?ZQM-5^VkbFhoVE10cibc4NW$^Kgjp*@frU$w~N)Mi_-h!@`hRM2TZhT^)>E zNQ?~z1I)tnlWHA?&nF*Un!Gzte4uHvI!uaT@%&SF^ zZAf^g@%f|y`|{<0h=v?zX9F}!5r!oI!4Kt5ewc;6WAkPbOGZ`|04heDIU_?lP+bj! zm~%gTC>QR3^l0iMj-NiAJ?6csY3ly?vAny*_atP$NS|)gCUpR4h*5}+jz)n9B^My^ zI6pbHl=w#))>TT}?kl55SJpEm+jU@GW6!OZkJ-r~o*xlTNKxd6|*>{z$bjb*t3xZEyy z8%*$zn*Qd@KZ*du&x;_atSFj|0j$dEMDhDWSiCX^o7!9P$8T*|UGxq#rX+ln)`4{| zdU5l|F4X*<9(IOnQIu|}Dh2FlqoNWNv5@~cCjIRwEYw1;`x8}FuR}i)qFY*|zCu3L93c4=)>EqM zV(>{qBeY2c0$mjDd~*|PidLcD6GTh*0z_!rFe)nI>#ruUue1f0w71~ATa6p{a)owB zc%5O6e)da2!uQ}Eno1WV$t_ul=)3?(7H+``dBy@dJZwotd~G-GH^z%HGveOQldu?L zM3w09OLGeRBU8pYJyzUpFoca$lrm&%R|SCOLholP^mwCj`DS$Z`GHbz5KS z2DRw%z5b3u?sWMpI*KozO{A4KT`syiVGNF^d}Yionk=?uSPe{hSl!c4JG zZ?oi$A~u^17Ryu>C?r%}hV1_Y!K=8qSRT!~ySot|A1`@v^5jYE*|TR>XXDwBkt1kc z{O-z?D>!oG2rgW>AfFX3%nN{_r*Xg7X?@`A#{Wlc>@7_36B zE#k;kDNam0tUi1845!7JuwR@7+uPeE0M%8XG@+;BkU`=wp9c>fL`O%51VsZo#G%vS zaKLJ{$`tXQk&%I-q9Qq_FePbeX<@^vNl33rKIV)>DlIJy=T(VLNl6LLo;{1bd-tNE zq5@@QWjK2DsPvo;5VUfMMp-_W>@#P_yJ1MwZ#ywQJ>_J7r^IqwJI%QYt_M~+ni s5dUzRx#sEBzm+FXp3FJ_#{Z800t<807*qoM6N<$f~(3ltpET3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/poster9_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/poster9_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..6699b59a1d96dea1f2f41db8183970b1008829e0 GIT binary patch literal 979 zcmV;^11$WBP)1KjRvf(tqEKN5G0oi7&X1~oG^NcMq9JXA2R$cqh2LXIvwLzfSLx& zD-W#N-0VZEJ~z8W%H@>>NBa_~oBgn)ee8E`0w^PZYz+LQGst{beSwr_-941tRd&B~ z5Wx9I1*o}8Bx5SjtM2}ezME@=ivTVfI>%1-{S=TKZS#gtcC^b-uh;nr;0ks|?2M>a z#MIYz^`-4}4d{A^p8#$jWNptcbk*&MyN5C(o*12mGvUitosP*#pxwquTF~3X9)7C8 z#ON&oUa9Bc%EVpR*n0+&6yYaeD!{T!i4^oRtu|(XnzE^ld+M3M(u&mD%uodVAH;oPc&KgJ8eQd*EFxdI6fFFwtZb0P# zJdv9witMDz^vW`__A1cUH7FK#JpRR}_aHTS6ZRoPNH`-mP1F7`4>+xKkb^JUs}8{d z%hzb_Q}BESs?`!4*WUtb2hsG-Nq}Z8uL8q^Nk}E{K(YL(1NI$`PS#!E*Dl|O&Fz;^ zKHT1(|>k55+BTMNSe>e7^m758==Vu+*blo09D{?0|+q??UoyAE& zlF)5OF&+;xBkyfq1saVbege)sfRQ6O0`uEnDqx-kX5%m$KtoCW3@*v~hhQq2%wsXSl+Y(jry zCmcobaU9zU0EwEKb6)%3h}hi?jZ%*i9;g$Q?)*s|9ePC))G$HF23s2JprH%&|9J`;d z+p6ey<=xwbpLFk@XPy+X@l*Dz*o{Uf?C(2FVCbweJJ8$P+rE4E?zFVDWiw~b&JGI; zn|1T%&2OJS6_%D>jfsofwtZ^W%wrD%MUu~<^4jg2H!HvY<(QxjRJ-oqYX*)9 z8jM1!4vSbkrZ990DFia9cs00ik|vmHzu@P^pXb?bEdN{bEdBZZAKE`o)Y*K_zR&+d z^xNf`^XLA5#$caiKj-J)dGA9F0?)HqoMmnO5NMH39Sa8W<`M zO)9E#CfNl*54>SFvA4Qk=kR&)=eOw0)d{HniwyD$L9_irqw3QyGl95`$Y3DFK9um> zv}Dc-t@(_y4gXdc9WY@}sA7p&$n1UUr7;lm;*JZl?L&#wR8PymP&;NThQEQS4Viog zzHn@Cn*WetO8L>;+}y3#w{PEmzs8>FN#{ED1OthZUH0CmR!&0+kl&2jbMC8uV-B;} z@BfBa`Q5444_KHZEh)k3uDW(Qw!a(_N4J0G^3n;I` zK;#tzdB4`RP8r-|pKCkkIPO;`qW1cowb%OA-WK?>{wF{*8pZ4N3XCx@o6XQ_wV0M5 zsZ$UW~(P;cyiwi)33xxuV$75J7mjs|Xcs85Ga5xO3(MWpaQrv>UU;vxV2DB)j z&*OHxh539ACX)%QR;w5QrQGlL<6Yo%I#mOdN+p)bWN2w+if*xT2Ql(PS^!5+cYBiQjCXqVo zEdV`5TX4JGz6U`2FZTdL0eHa;1yGWq0HII_`~CiFD^4U5Sg+T0>41k~u^8_6`={Tz z05+QqJ|W>QAj>2xo=hgXW?{G6i2)oA2WbpPA`$F%yP6?rywm6Td=>*B)38|dt4|tg zG!c1ga-%$k25)+)QK!>kl!eu5B?dsLayT5^l&Mv_-DWEPa{pIsL(oY| eN3lNvjMNXCM(#7LsQ#q@0000%KA)$-VDKYmc;C;Wujm!1NBu<~GNMcXX%x)cUXR<0 z<0`k!&dbWU-RUuza10`K_gb9*=6^9dk77Y&0fSN|0MTF$kw(>#%i_vGkz3oh)d|Sv zD-KXK$^=k83k`JE(?FCaFb(IKiaLSWY(}~PA5bQM42U|8s{zC)+u2+6prj%MM6K(9 zEUVHffCf;8aYim;XyAlO>I9O>B<`<2^*~i(7>;K{+FYnuEW(K>O6cu9ECmVuG# z(uXtyw?{QLr0nMpxU$YDm&=ixnxAm6&&STmd3Sgle{*8X{dD{R%==>;VuG?;00000NkvXXu0mjfux1Wr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/random_contraband.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/random_contraband.png new file mode 100644 index 0000000000000000000000000000000000000000..036c3bc9681c0b3fb3b979b46b605f7591c04e56 GIT binary patch literal 619 zcmV-x0+juUP)}K`N?3>wL70!(RNx(1+Z@pfFq9~Bh=b=<8 zK`xgg8=u8u0k&<^7(R&AYDF!M>AFted!9#gi^U==mrEE728t8`{F5j3mEL>r7t{`0 zR=oWdv8{+b4(w*LDIbA2H1wdY*Xv-K=AIqE+J1|D4c!9f?B-)cqzPacduG6V)(w8x znBP$QQX2!*B6ete)*Ta>u#H6eZh{El`tQ86APsmF&?#vGC>mTt45P?XS^IJlL{isn zc><#KN(0OqX#$u&y$`N|!#s~_;C51yC*Zm+WDTqX(gZL9Jde|A0BuZL*PY7~KoNqw z$^CfoCWa`g!X?0phiRC`b8a)=pSB>IV+m-Q23a9o4W$Vb3WbdZva184f_AbxAVMqw z$8om1UfMb^Yz1~A4IqJ2L6`+u)q#UFKvhf2whoAJ^g6)zffdk*WcR%$ot!F_FFMBGe_r|T6==6L ze@+=5eIcWkIvt0uZFohSPN#ANMx&7u*UuP(ta0|+@ehCGYMf_T2_XOg002ovPDHLk FV1m4Y2mb&7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Wallmounts/posters.rsi/random_legit.png b/Resources/Textures/Structures/Wallmounts/posters.rsi/random_legit.png new file mode 100644 index 0000000000000000000000000000000000000000..8a47595e4b3ade6ead2fb9054b224903898edb9b GIT binary patch literal 616 zcmV-u0+;=XP)7-^&j*H_wK0& zp;+)5kbqKX&02MBW@2KLEZrol_JORkyCH8TZ)RtkaAEvU0{wn}yV-0&(==!_8erQt z=(vFG$@oGjh} ztRp+W&ZqIq4{apk^MO18{Qi4SpdNNnK&PY$plI+LVi<*<#ERR@?g z(gZMlQVmR?Km%oLNHk#2?&S$^&OtS>4oDNg2&8%3v+8L8ZA{xwfm1>e0;+$P>ngy@ z5Wvl-0ZhX>o@cfbr{cUTPrxt?P=;JJlqO)BW>NByY^rgAf#@}d9;JPjt?QZ;t z6ASr;w8YpgUEA=A76gGDf$?~(70rjC`mDJ4?f4fH{A%a4pe$Sf000015kU~>XIYjbKMKfZvm}{JLNpqMPXuA#O&j9_q|<4V zNF>0rEHDg%j^Q~*JRbKj(}Hj_V45cPVgzL}880iv-4)p0KbZ)^1>n;Ui&m>e-*NJ% zmsfaxI44Kt+p#m^15~Tkhzp=;W~m>H&D8}uxg<$Yxl^%baF{T-q9`L{xEatijozT$ zZhOU-N~QX)*~)Lg#g$B#qtR$kEU#!;3_}I(1G=vF{)pZbYrwWT(6vlotzeBHfOU{N zDb(wAkU9qTHQ^yf-iUfIq_DOQcDEB)D{OL%8zBbeHw7%Wy;W81LwtEBM95C@67DO9 zq*kl>mWBmp$8j7uu$yo;6Z6IfW9+Rszjy3q1P?q&!D_baZA(1Q=7T$vgDDS{r zF?3^WAAoo0m?aDHz!IraRgr}yLd^iGN~E~HE=CDB5r6%W>a*BR9N#b3=h_$W%hCWE zKm%w14WI#X0ov_0E0@cn@49a3M*&)`7Hc#bP^na44Z-BQbHnTa*tX5;^*Y3H3}G0G zXE;U~hOvP;7l<+gtJO+58G#(f*<{6ayS(Y01fm4Mzt2+?MWS^VO-gP7=;H(HbVf&K zWCvg}nUpwyNV81+wnopF6bQjC0YWMF3=WtC_dIWJ7-a^0-xmukm&=X$EX&Hw!HATr z+gy;@Y$0G(rj^QrDm({*AV_~C7DW%FmEJD&2m;6o;z40Lo$}{*ysUw#Aof0pQZNjH zKA{9C4)P2ugQKd|K6oDkUfwYqkH;B^gHOUQkRAXxU#<28@s*{VhhRyPz Date: Wed, 29 Dec 2021 23:14:21 +1100 Subject: [PATCH 12/12] Reduce MaxBuckleDistance (#5938) --- .../Buckle/Components/BuckleComponent.cs | 19 +------------------ .../Buckle/Components/StrapComponent.cs | 5 +---- Content.Server/Buckle/Systems/BuckleSystem.cs | 8 -------- .../Components/SharedBuckleComponent.cs | 2 -- Content.Shared/Buckle/SharedBuckleSystem.cs | 1 - 5 files changed, 2 insertions(+), 33 deletions(-) diff --git a/Content.Server/Buckle/Components/BuckleComponent.cs b/Content.Server/Buckle/Components/BuckleComponent.cs index d140e264fb..9da4b1eea4 100644 --- a/Content.Server/Buckle/Components/BuckleComponent.cs +++ b/Content.Server/Buckle/Components/BuckleComponent.cs @@ -133,7 +133,7 @@ namespace Content.Server.Buckle.Components break; } - ownTransform.LocalPosition = Vector2.Zero + strap.BuckleOffset; + ownTransform.LocalPosition = strap.BuckleOffset; } public bool CanBuckle(EntityUid user, EntityUid to, [NotNullWhen(true)] out StrapComponent? strap) @@ -410,22 +410,5 @@ namespace Content.Server.Buckle.Components return new BuckleComponentState(Buckled, drawDepth, LastEntityBuckledTo, DontCollide); } - - public void Update(PhysicsComponent physics) - { - if (!DontCollide) - return; - - physics.WakeBody(); - - if (!IsOnStrapEntityThisFrame && DontCollide) - { - DontCollide = false; - TryUnbuckle(Owner); - Dirty(); - } - - IsOnStrapEntityThisFrame = false; - } } } diff --git a/Content.Server/Buckle/Components/StrapComponent.cs b/Content.Server/Buckle/Components/StrapComponent.cs index 21d1588225..81f0e79d31 100644 --- a/Content.Server/Buckle/Components/StrapComponent.cs +++ b/Content.Server/Buckle/Components/StrapComponent.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; using System.Linq; -using Content.Shared.ActionBlocker; using Content.Shared.Acts; using Content.Shared.Alert; -using Content.Shared.Buckle; using Content.Shared.Buckle.Components; using Content.Shared.DragDrop; using Content.Shared.Interaction; @@ -12,7 +10,6 @@ using Robust.Server.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Maths; -using Robust.Shared.Players; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -67,7 +64,7 @@ namespace Content.Server.Buckle.Components /// Don't change it unless you really have to /// [DataField("maxBuckleDistance", required: false)] - public float MaxBuckleDistance = 1f; + public float MaxBuckleDistance = 0.1f; /// /// You can specify the offset the entity will have after unbuckling. diff --git a/Content.Server/Buckle/Systems/BuckleSystem.cs b/Content.Server/Buckle/Systems/BuckleSystem.cs index 8ec67713a6..7586047fb3 100644 --- a/Content.Server/Buckle/Systems/BuckleSystem.cs +++ b/Content.Server/Buckle/Systems/BuckleSystem.cs @@ -64,14 +64,6 @@ namespace Content.Server.Buckle.Systems args.Handled = component.TryUnbuckle(args.User); } - public override void Update(float frameTime) - { - foreach (var (buckle, physics) in EntityManager.EntityQuery()) - { - buckle.Update(physics); - } - } - private void MoveEvent(EntityUid uid, BuckleComponent buckle, ref MoveEvent ev) { var strap = buckle.BuckledTo; diff --git a/Content.Shared/Buckle/Components/SharedBuckleComponent.cs b/Content.Shared/Buckle/Components/SharedBuckleComponent.cs index 9491e24254..724ae4581f 100644 --- a/Content.Shared/Buckle/Components/SharedBuckleComponent.cs +++ b/Content.Shared/Buckle/Components/SharedBuckleComponent.cs @@ -29,8 +29,6 @@ namespace Content.Shared.Buckle.Components public EntityUid? LastEntityBuckledTo { get; set; } - public bool IsOnStrapEntityThisFrame { get; set; } - public bool DontCollide { get; set; } public abstract bool TryBuckle(EntityUid user, EntityUid to); diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 5bc94119b0..7e76ee96b4 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -59,7 +59,6 @@ namespace Content.Shared.Buckle { if (args.BodyB.Owner != component.LastEntityBuckledTo) return; - component.IsOnStrapEntityThisFrame = true; if (component.Buckled || component.DontCollide) { args.Cancel();