]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Separate "thank you" messages from general ads (#25867)
authorTayrtahn <tayrtahn@gmail.com>
Thu, 28 Mar 2024 06:46:26 +0000 (02:46 -0400)
committerGitHub <noreply@github.com>
Thu, 28 Mar 2024 06:46:26 +0000 (17:46 +1100)
* Separated "thank you" messages from general ads

* Moved MessagePackPrototype to shared, cleaned up AdvertiseComponent, and actually killed AdvertisementsPackPrototype.
+More suggests changes.

* Rename PackPrototypeID to Pack in both components.

72 files changed:
Content.Client/Entry/EntryPoint.cs
Content.Server/Advertise/AdvertiseComponent.cs [deleted file]
Content.Server/Advertise/AdvertiseSystem.cs [deleted file]
Content.Server/Advertise/Components/AdvertiseComponent.cs [new file with mode: 0644]
Content.Server/Advertise/Components/SpeakOnUIClosedComponent.cs [new file with mode: 0644]
Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs [new file with mode: 0644]
Content.Server/Advertise/EntitySystems/SpeakOnUIClosedSystem.cs [new file with mode: 0644]
Content.Server/Advertisements/AdvertisementsPackPrototype.cs [deleted file]
Content.Server/VendingMachines/VendingMachineSystem.cs
Content.Shared/Advertise/MessagePackPrototype.cs [new file with mode: 0644]
Content.Shared/VendingMachines/VendingMachineComponent.cs
Resources/Prototypes/Catalog/VendingMachines/Advertisements/ammo.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/atmosdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/bardrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/boozeomat.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/cargodrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/chang.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/chefdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/chefvend.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/chemdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/cigs.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/clothesmate.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/coffee.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/cola.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/condiments.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/curadrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/detdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/dinnerware.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/discount.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/donut.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/engidrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/fatextractor.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/games.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/genedrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/happyhonk.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/hydrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/janidrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/lawdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/magivend.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/medidrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/megaseed.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/nanomed.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/nutrimax.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/robodrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/scidrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/secdrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/sectech.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/smartfridge.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/snack.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/sovietsoda.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/syndiedrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/theater.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/vendomat.yml
Resources/Prototypes/Catalog/VendingMachines/Advertisements/virodrobe.yml
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/boozeomat.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chang.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chefvend.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cigs.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/coffee.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cola.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/discount.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/donut.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/games.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/generic.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/happyhonk.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/lawdrobe.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/nutrimax.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sectech.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/snack.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sovietsoda.yml [new file with mode: 0644]
Resources/Prototypes/Catalog/VendingMachines/Goodbyes/syndiedrobe.yml [new file with mode: 0644]
Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml

index 7dde4557cd8008643b4f5e324d4db0e8ea863649..47f11ee16164e0729c10c55207844866a28d796d 100644 (file)
@@ -106,7 +106,6 @@ namespace Content.Client.Entry
             _prototypeManager.RegisterIgnore("gameMap");
             _prototypeManager.RegisterIgnore("gameMapPool");
             _prototypeManager.RegisterIgnore("lobbyBackground");
-            _prototypeManager.RegisterIgnore("advertisementsPack");
             _prototypeManager.RegisterIgnore("gamePreset");
             _prototypeManager.RegisterIgnore("noiseChannel");
             _prototypeManager.RegisterIgnore("spaceBiome");
diff --git a/Content.Server/Advertise/AdvertiseComponent.cs b/Content.Server/Advertise/AdvertiseComponent.cs
deleted file mode 100644 (file)
index f36cc7a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-using Content.Server.Advertisements;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Server.Advertise
-{
-    [RegisterComponent, Access(typeof(AdvertiseSystem))]
-    public sealed partial class AdvertiseComponent : Component
-    {
-        /// <summary>
-        ///     Minimum time in seconds to wait before saying a new ad, in seconds. Has to be larger than or equal to 1.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("minWait")]
-        public int MinimumWait { get; private set; } = 8 * 60;
-
-        /// <summary>
-        ///     Maximum time in seconds to wait before saying a new ad, in seconds. Has to be larger than or equal
-        ///     to <see cref="MinimumWait"/>
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        [DataField("maxWait")]
-        public int MaximumWait { get; private set; } = 10 * 60;
-
-        /// <summary>
-        ///     The identifier for the advertisements pack prototype.
-        /// </summary>
-        [DataField("pack", customTypeSerializer:typeof(PrototypeIdSerializer<AdvertisementsPackPrototype>), required: true)]
-        public string PackPrototypeId { get; private set; } = string.Empty;
-
-        /// <summary>
-        ///     The next time an advertisement will be said.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        public TimeSpan NextAdvertisementTime { get; set; } = TimeSpan.Zero;
-
-        /// <summary>
-        ///     Whether the entity will say advertisements or not.
-        /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
-        public bool Enabled { get; set; } = true;
-    }
-}
diff --git a/Content.Server/Advertise/AdvertiseSystem.cs b/Content.Server/Advertise/AdvertiseSystem.cs
deleted file mode 100644 (file)
index ab538f3..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-using Content.Server.Advertisements;
-using Content.Server.Chat.Systems;
-using Content.Server.Power.Components;
-using Content.Shared.VendingMachines;
-using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
-using Robust.Shared.Timing;
-
-namespace Content.Server.Advertise
-{
-    public sealed class AdvertiseSystem : EntitySystem
-    {
-        [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
-        [Dependency] private readonly IRobustRandom _random = default!;
-        [Dependency] private readonly IGameTiming _gameTiming = default!;
-        [Dependency] private readonly ChatSystem _chat = default!;
-
-        /// <summary>
-        /// The maximum amount of time between checking if advertisements should be displayed
-        /// </summary>
-        private readonly TimeSpan _maximumNextCheckDuration = TimeSpan.FromSeconds(15);
-
-        /// <summary>
-        /// The next time the game will check if advertisements should be displayed
-        /// </summary>
-        private TimeSpan _nextCheckTime = TimeSpan.MaxValue;
-
-        public override void Initialize()
-        {
-            SubscribeLocalEvent<AdvertiseComponent, ComponentInit>(OnComponentInit);
-            SubscribeLocalEvent<AdvertiseComponent, PowerChangedEvent>(OnPowerChanged);
-
-            SubscribeLocalEvent<ApcPowerReceiverComponent, AdvertiseEnableChangeAttemptEvent>(OnPowerReceiverEnableChangeAttempt);
-            SubscribeLocalEvent<VendingMachineComponent, AdvertiseEnableChangeAttemptEvent>(OnVendingEnableChangeAttempt);
-
-            // The component inits will lower this.
-            _nextCheckTime = TimeSpan.MaxValue;
-        }
-
-        private void OnComponentInit(EntityUid uid, AdvertiseComponent advertise, ComponentInit args)
-        {
-            RefreshTimer(uid, advertise);
-        }
-
-        private void OnPowerChanged(EntityUid uid, AdvertiseComponent advertise, ref PowerChangedEvent args)
-        {
-            SetEnabled(uid, args.Powered, advertise);
-        }
-
-        public void RefreshTimer(EntityUid uid, AdvertiseComponent? advertise = null)
-        {
-            if (!Resolve(uid, ref advertise))
-                return;
-
-            if (!advertise.Enabled)
-                return;
-
-            var minDuration = Math.Max(1, advertise.MinimumWait);
-            var maxDuration = Math.Max(minDuration, advertise.MaximumWait);
-            var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));
-            var nextTime = _gameTiming.CurTime + waitDuration;
-
-            advertise.NextAdvertisementTime = nextTime;
-
-            _nextCheckTime = MathHelper.Min(nextTime, _nextCheckTime);
-        }
-
-        public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advertise = null)
-        {
-            if (!Resolve(uid, ref advertise))
-                return;
-
-            if (_prototypeManager.TryIndex(advertise.PackPrototypeId, out AdvertisementsPackPrototype? advertisements))
-                _chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Advertisements)), InGameICChatType.Speak, true);
-        }
-
-        public void SayThankYou(EntityUid uid, AdvertiseComponent? advertise = null)
-        {
-            if (!Resolve(uid, ref advertise))
-                return;
-
-            if (_prototypeManager.TryIndex(advertise.PackPrototypeId, out AdvertisementsPackPrototype? advertisements))
-            {
-                _chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.ThankYous), ("name", Name(uid))), InGameICChatType.Speak, true);
-            }
-        }
-
-        public void SetEnabled(EntityUid uid, bool enable, AdvertiseComponent? advertise = null)
-        {
-            if (!Resolve(uid, ref advertise))
-                return;
-
-            if (advertise.Enabled == enable)
-                return;
-
-            var attemptEvent = new AdvertiseEnableChangeAttemptEvent(enable);
-            RaiseLocalEvent(uid, attemptEvent);
-
-            if (attemptEvent.Cancelled)
-                return;
-
-            advertise.Enabled = enable;
-            RefreshTimer(uid, advertise);
-        }
-
-        private static void OnPowerReceiverEnableChangeAttempt(EntityUid uid, ApcPowerReceiverComponent component, AdvertiseEnableChangeAttemptEvent args)
-        {
-            if(args.Enabling && !component.Powered)
-                args.Cancel();
-        }
-
-        private static void OnVendingEnableChangeAttempt(EntityUid uid, VendingMachineComponent component, AdvertiseEnableChangeAttemptEvent args)
-        {
-            if(args.Enabling && component.Broken)
-                args.Cancel();
-        }
-
-        public override void Update(float frameTime)
-        {
-            var curTime = _gameTiming.CurTime;
-            if (_nextCheckTime > curTime)
-                return;
-
-            _nextCheckTime = curTime + _maximumNextCheckDuration;
-
-            var query = EntityQueryEnumerator<AdvertiseComponent>();
-            while (query.MoveNext(out var uid, out var advert))
-            {
-                if (!advert.Enabled)
-                    continue;
-
-                // If this isn't advertising yet
-                if (advert.NextAdvertisementTime > curTime)
-                {
-                    _nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
-                    continue;
-                }
-
-                SayAdvertisement(uid, advert);
-                RefreshTimer(uid, advert);
-            }
-        }
-    }
-
-    public sealed class AdvertiseEnableChangeAttemptEvent : CancellableEntityEventArgs
-    {
-        public bool Enabling { get; }
-
-        public AdvertiseEnableChangeAttemptEvent(bool enabling)
-        {
-            Enabling = enabling;
-        }
-    }
-}
diff --git a/Content.Server/Advertise/Components/AdvertiseComponent.cs b/Content.Server/Advertise/Components/AdvertiseComponent.cs
new file mode 100644 (file)
index 0000000..140bc6b
--- /dev/null
@@ -0,0 +1,45 @@
+using Content.Server.Advertise.EntitySystems;
+using Content.Shared.Advertise;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.Advertise.Components;
+
+/// <summary>
+/// Makes this entity periodically advertise by speaking a randomly selected
+/// message from a specified MessagePack into local chat.
+/// </summary>
+[RegisterComponent, Access(typeof(AdvertiseSystem))]
+public sealed partial class AdvertiseComponent : Component
+{
+    /// <summary>
+    /// Minimum time in seconds to wait before saying a new ad, in seconds. Has to be larger than or equal to 1.
+    /// </summary>
+    [DataField]
+    public int MinimumWait { get; private set; } = 8 * 60;
+
+    /// <summary>
+    /// Maximum time in seconds to wait before saying a new ad, in seconds. Has to be larger than or equal
+    /// to <see cref="MinimumWait"/>
+    /// </summary>
+    [DataField]
+    public int MaximumWait { get; private set; } = 10 * 60;
+
+    /// <summary>
+    /// The identifier for the advertisements pack prototype.
+    /// </summary>
+    [DataField(required: true)]
+    public ProtoId<MessagePackPrototype> Pack { get; private set; }
+
+    /// <summary>
+    /// The next time an advertisement will be said.
+    /// </summary>
+    [DataField]
+    public TimeSpan NextAdvertisementTime { get; set; } = TimeSpan.Zero;
+
+    /// <summary>
+    /// Whether the entity will say advertisements or not.
+    /// </summary>
+    [DataField]
+    public bool Enabled { get; set; } = true;
+}
diff --git a/Content.Server/Advertise/Components/SpeakOnUIClosedComponent.cs b/Content.Server/Advertise/Components/SpeakOnUIClosedComponent.cs
new file mode 100644 (file)
index 0000000..2a663b7
--- /dev/null
@@ -0,0 +1,36 @@
+using Content.Shared.Advertise;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Advertise.Components;
+
+/// <summary>
+/// Causes the entity to speak using the Chat system when its ActivatableUI is closed, optionally
+/// requiring that a Flag be set as well.
+/// </summary>
+[RegisterComponent, Access(typeof(SpeakOnUIClosedSystem))]
+public sealed partial class SpeakOnUIClosedComponent : Component
+{
+    /// <summary>
+    /// The identifier for the message pack prototype containing messages to be spoken by this entity.
+    /// </summary>
+    [DataField(required: true)]
+    public ProtoId<MessagePackPrototype> Pack { get; private set; }
+
+    /// <summary>
+    /// Is this component active? If false, no messages will be spoken.
+    /// </summary>
+    [DataField]
+    public bool Enabled = true;
+
+    /// <summary>
+    /// Should messages be spoken only if the <see cref="Flag"/> is set (true), or every time the UI is closed (false)?
+    /// </summary>
+    [DataField]
+    public bool RequireFlag = true;
+
+    /// <summary>
+    /// State variable only used if <see cref="RequireFlag"/> is true. Set with <see cref="SpeakOnUIClosedSystem.TrySetFlag"/>.
+    /// </summary>
+    [DataField]
+    public bool Flag;
+}
diff --git a/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs b/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs
new file mode 100644 (file)
index 0000000..bb254d1
--- /dev/null
@@ -0,0 +1,137 @@
+using Content.Server.Advertise.Components;
+using Content.Server.Chat.Systems;
+using Content.Server.Power.Components;
+using Content.Shared.VendingMachines;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Advertise.EntitySystems;
+
+public sealed class AdvertiseSystem : EntitySystem
+{
+    [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly IGameTiming _gameTiming = default!;
+    [Dependency] private readonly ChatSystem _chat = default!;
+
+    /// <summary>
+    /// The maximum amount of time between checking if advertisements should be displayed
+    /// </summary>
+    private readonly TimeSpan _maximumNextCheckDuration = TimeSpan.FromSeconds(15);
+
+    /// <summary>
+    /// The next time the game will check if advertisements should be displayed
+    /// </summary>
+    private TimeSpan _nextCheckTime = TimeSpan.MaxValue;
+
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<AdvertiseComponent, MapInitEvent>(OnMapInit);
+        SubscribeLocalEvent<AdvertiseComponent, PowerChangedEvent>(OnPowerChanged);
+
+        SubscribeLocalEvent<ApcPowerReceiverComponent, AdvertiseEnableChangeAttemptEvent>(OnPowerReceiverEnableChangeAttempt);
+        SubscribeLocalEvent<VendingMachineComponent, AdvertiseEnableChangeAttemptEvent>(OnVendingEnableChangeAttempt);
+
+        // The component inits will lower this.
+        _nextCheckTime = TimeSpan.MaxValue;
+    }
+
+    private void OnMapInit(EntityUid uid, AdvertiseComponent advertise, MapInitEvent args)
+    {
+        RefreshTimer(uid, advertise);
+    }
+
+    private void OnPowerChanged(EntityUid uid, AdvertiseComponent advertise, ref PowerChangedEvent args)
+    {
+        SetEnabled(uid, args.Powered, advertise);
+    }
+
+    public void RefreshTimer(EntityUid uid, AdvertiseComponent? advertise = null)
+    {
+        if (!Resolve(uid, ref advertise))
+            return;
+
+        if (!advertise.Enabled)
+            return;
+
+        var minDuration = Math.Max(1, advertise.MinimumWait);
+        var maxDuration = Math.Max(minDuration, advertise.MaximumWait);
+        var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));
+        var nextTime = _gameTiming.CurTime + waitDuration;
+
+        advertise.NextAdvertisementTime = nextTime;
+
+        _nextCheckTime = MathHelper.Min(nextTime, _nextCheckTime);
+    }
+
+    public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advertise = null)
+    {
+        if (!Resolve(uid, ref advertise))
+            return;
+
+        if (_prototypeManager.TryIndex(advertise.Pack, out var advertisements))
+            _chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true);
+    }
+
+    public void SetEnabled(EntityUid uid, bool enable, AdvertiseComponent? advertise = null)
+    {
+        if (!Resolve(uid, ref advertise))
+            return;
+
+        if (advertise.Enabled == enable)
+            return;
+
+        var attemptEvent = new AdvertiseEnableChangeAttemptEvent(enable);
+        RaiseLocalEvent(uid, attemptEvent);
+
+        if (attemptEvent.Cancelled)
+            return;
+
+        advertise.Enabled = enable;
+        RefreshTimer(uid, advertise);
+    }
+
+    private static void OnPowerReceiverEnableChangeAttempt(EntityUid uid, ApcPowerReceiverComponent component, AdvertiseEnableChangeAttemptEvent args)
+    {
+        if (args.Enabling && !component.Powered)
+            args.Cancel();
+    }
+
+    private static void OnVendingEnableChangeAttempt(EntityUid uid, VendingMachineComponent component, AdvertiseEnableChangeAttemptEvent args)
+    {
+        if (args.Enabling && component.Broken)
+            args.Cancel();
+    }
+
+    public override void Update(float frameTime)
+    {
+        var curTime = _gameTiming.CurTime;
+        if (_nextCheckTime > curTime)
+            return;
+
+        _nextCheckTime = curTime + _maximumNextCheckDuration;
+
+        var query = EntityQueryEnumerator<AdvertiseComponent>();
+        while (query.MoveNext(out var uid, out var advert))
+        {
+            if (!advert.Enabled)
+                continue;
+
+            // If this isn't advertising yet
+            if (advert.NextAdvertisementTime > curTime)
+            {
+                _nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
+                continue;
+            }
+
+            SayAdvertisement(uid, advert);
+            RefreshTimer(uid, advert);
+        }
+    }
+}
+
+public sealed class AdvertiseEnableChangeAttemptEvent(bool enabling) : CancellableEntityEventArgs
+{
+    public bool Enabling { get; } = enabling;
+}
diff --git a/Content.Server/Advertise/EntitySystems/SpeakOnUIClosedSystem.cs b/Content.Server/Advertise/EntitySystems/SpeakOnUIClosedSystem.cs
new file mode 100644 (file)
index 0000000..048f59b
--- /dev/null
@@ -0,0 +1,58 @@
+using Content.Server.Advertise.Components;
+using Content.Server.Chat.Systems;
+using Content.Server.UserInterface;
+using Content.Shared.Advertise;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Server.Advertise;
+
+public sealed partial class SpeakOnUIClosedSystem : EntitySystem
+{
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+    [Dependency] private readonly ChatSystem _chat = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<SpeakOnUIClosedComponent, BoundUIClosedEvent>(OnBoundUIClosed);
+    }
+    private void OnBoundUIClosed(Entity<SpeakOnUIClosedComponent> entity, ref BoundUIClosedEvent args)
+    {
+        if (!TryComp(entity, out ActivatableUIComponent? activatable) || !args.UiKey.Equals(activatable.Key))
+            return;
+
+        if (entity.Comp.RequireFlag && !entity.Comp.Flag)
+            return;
+
+        TrySpeak((entity, entity.Comp));
+    }
+
+    public bool TrySpeak(Entity<SpeakOnUIClosedComponent?> entity)
+    {
+        if (!Resolve(entity, ref entity.Comp))
+            return false;
+
+        if (!entity.Comp.Enabled)
+            return false;
+
+        if (!_prototypeManager.TryIndex(entity.Comp.Pack, out MessagePackPrototype? messagePack))
+            return false;
+
+        var message = Loc.GetString(_random.Pick(messagePack.Messages), ("name", Name(entity)));
+        _chat.TrySendInGameICMessage(entity, message, InGameICChatType.Speak, true);
+        entity.Comp.Flag = false;
+        return true;
+    }
+
+    public bool TrySetFlag(Entity<SpeakOnUIClosedComponent?> entity, bool value = true)
+    {
+        if (!Resolve(entity, ref entity.Comp))
+            return false;
+
+        entity.Comp.Flag = value;
+        return true;
+    }
+}
diff --git a/Content.Server/Advertisements/AdvertisementsPackPrototype.cs b/Content.Server/Advertisements/AdvertisementsPackPrototype.cs
deleted file mode 100644 (file)
index 641ab3c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-using Robust.Shared.Prototypes;
-
-namespace Content.Server.Advertisements
-{
-    [Serializable, Prototype("advertisementsPack")]
-    public sealed partial class AdvertisementsPackPrototype : IPrototype
-    {
-        [ViewVariables]
-        [IdDataField]
-        public string ID { get; private set; } = default!;
-
-        [DataField("advertisements")]
-        public List<string> Advertisements { get; private set; } = new();
-
-        [DataField("thankyous")]
-        public List<string> ThankYous { get; private set; } = new();
-    }
-}
index b5fa611a3966fc188b6e2d5c84ae2d6d93d08ce6..7c9aed188fe91d72b4f6957216515d1ea81b513f 100644 (file)
@@ -1,12 +1,11 @@
 using System.Linq;
 using System.Numerics;
 using Content.Server.Advertise;
+using Content.Server.Advertise.Components;
 using Content.Server.Cargo.Systems;
-using Content.Server.Chat.Systems;
 using Content.Server.Emp;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
-using Content.Server.UserInterface;
 using Content.Shared.Access.Components;
 using Content.Shared.Access.Systems;
 using Content.Shared.Actions;
@@ -25,7 +24,6 @@ using Robust.Shared.Audio;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 using Robust.Shared.Timing;
-using Robust.Shared.Utility;
 
 namespace Content.Server.VendingMachines
 {
@@ -39,7 +37,7 @@ namespace Content.Server.VendingMachines
         [Dependency] private readonly ThrowingSystem _throwingSystem = default!;
         [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
         [Dependency] private readonly IGameTiming _timing = default!;
-        [Dependency] private readonly AdvertiseSystem _advertise = default!;
+        [Dependency] private readonly SpeakOnUIClosedSystem _speakOnUIClosed = default!;
 
         public override void Initialize()
         {
@@ -58,7 +56,6 @@ namespace Content.Server.VendingMachines
             Subs.BuiEvents<VendingMachineComponent>(VendingMachineUiKey.Key, subs =>
             {
                 subs.Event<BoundUIOpenedEvent>(OnBoundUIOpened);
-                subs.Event<BoundUIClosedEvent>(OnBoundUIClosed);
                 subs.Event<VendingMachineEjectMessage>(OnInventoryEjectMessage);
             });
 
@@ -114,16 +111,6 @@ namespace Content.Server.VendingMachines
             UpdateVendingMachineInterfaceState(uid, component);
         }
 
-        private void OnBoundUIClosed(EntityUid uid, VendingMachineComponent component, BoundUIClosedEvent args)
-        {
-            // Only vendors that advertise will send message after dispensing
-            if (component.ShouldSayThankYou && TryComp<AdvertiseComponent>(uid, out var advertise))
-            {
-                _advertise.SayThankYou(uid, advertise);
-                component.ShouldSayThankYou = false;
-            }
-        }
-
         private void UpdateVendingMachineInterfaceState(EntityUid uid, VendingMachineComponent component)
         {
             var state = new VendingMachineInterfaceState(GetAllInventory(uid, component));
@@ -294,7 +281,10 @@ namespace Content.Server.VendingMachines
             vendComponent.Ejecting = true;
             vendComponent.NextItemToEject = entry.ID;
             vendComponent.ThrowNextItem = throwItem;
-            vendComponent.ShouldSayThankYou = true;
+
+            if (TryComp(uid, out SpeakOnUIClosedComponent? speakComponent))
+                _speakOnUIClosed.TrySetFlag((uid, speakComponent));
+
             entry.Amount--;
             UpdateVendingMachineInterfaceState(uid, vendComponent);
             TryUpdateVisualState(uid, vendComponent);
diff --git a/Content.Shared/Advertise/MessagePackPrototype.cs b/Content.Shared/Advertise/MessagePackPrototype.cs
new file mode 100644 (file)
index 0000000..f7495d7
--- /dev/null
@@ -0,0 +1,14 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Advertise;
+
+[Serializable, Prototype("messagePack")]
+public sealed partial class MessagePackPrototype : IPrototype
+{
+    [ViewVariables]
+    [IdDataField]
+    public string ID { get; private set; } = default!;
+
+    [DataField]
+    public List<LocId> Messages { get; private set; } = [];
+}
index 725dc60e3bcbc75e260280d06560f22331a6b589..23130bb8f39345d6b4f1d01bad29f415707fbced 100644 (file)
@@ -51,8 +51,6 @@ namespace Content.Shared.VendingMachines
 
         public bool Broken;
 
-        public bool ShouldSayThankYou;
-
         /// <summary>
         /// When true, will forcefully throw any object it dispenses
         /// </summary>
index 6038134ea163d480a003fe1ecda62cbef170dc20..7e089a282595f4d55931a6d30efa48593a4beb76 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: AmmoVendAds
-  advertisements:
+  messages:
   - advertisement-ammo-1
   - advertisement-ammo-2
   - advertisement-ammo-3
@@ -11,5 +11,3 @@
   - advertisement-ammo-8
   - advertisement-ammo-9
   - advertisement-ammo-10
-  thankyous:
-  - vending-machine-thanks
index c5737d58bffeaaa0a4596a877050303598090c03..7946c0631027e68489d198a3ff7660a197649c8f 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: AtmosDrobeAds
-  advertisements:
+  messages:
     - advertisement-atmosdrobe-1
     - advertisement-atmosdrobe-2
     - advertisement-atmosdrobe-3
-  thankyous:
-    - vending-machine-thanks
index 84501583d76668fb06b331061479f8dc9304b2a0..0a21acf2cb5b453649d330f2c65d3c2914f8bd6e 100644 (file)
@@ -1,7 +1,5 @@
-- type: advertisementsPack
+- type: messagePack
   id: BarDrobeAds
-  advertisements:
+  messages:
     - advertisement-bardrobe-1
     - advertisement-bardrobe-2
-  thankyous:
-    - vending-machine-thanks
index 943e571887009b82eb0668820aee37b7a9a395e6..e6bcbbcb9c389aeb67796eeb83e67a959db4a8a5 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: BoozeOMatAds
-  advertisements:
+  messages:
   - advertisement-boozeomat-1
   - advertisement-boozeomat-2
   - advertisement-boozeomat-3
@@ -20,8 +20,3 @@
   - advertisement-boozeomat-17
   - advertisement-boozeomat-18
   - advertisement-boozeomat-19
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-boozeomat-1
-  - thankyou-boozeomat-2
-  - thankyou-boozeomat-3
index fdf90a1d0d61df0bd0bc4f452a9c4cc1a44a4bf1..f2cd38f737e2005ca93f8e3468fde7f6f2629bfe 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: CargoDrobeAds
-  advertisements:
+  messages:
     - advertisement-cargodrobe-1
     - advertisement-cargodrobe-2
     - advertisement-cargodrobe-3
-  thankyous:
-    - vending-machine-thanks
index ebfe81286b56fae42050c5768eeb5dffcf337dc5..911d467e7d06d0494cd2682dcb9b39288fb470dc 100644 (file)
@@ -1,12 +1,8 @@
-- type: advertisementsPack
+- type: messagePack
   id: ChangAds
-  advertisements:
+  messages:
     - advertisement-chang-1
     - advertisement-chang-2
     - advertisement-chang-3
     - advertisement-chang-4
     - advertisement-chang-5
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-chang-1
-    - thankyou-chang-2
index 2d45bd4e29ddb42b11466e3b59bd50a89d5eff60..c71d8225e03169a6fc49b8f8d828456d63fab09e 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: ChefDrobeAds
-  advertisements:
+  messages:
     - advertisement-chefdrobe-1
     - advertisement-chefdrobe-2
     - advertisement-chefdrobe-3
-  thankyous:
-    - vending-machine-thanks
index 9b1edb4b5becce3d0dd0335e2f9818be3e7640d4..d52fcf9894cf765e93ca953228bd8fe7d753f948 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: ChefvendAds
-  advertisements:
+  messages:
     - advertisement-chefvend-1
     - advertisement-chefvend-2
     - advertisement-chefvend-3
@@ -10,9 +10,3 @@
     - advertisement-chefvend-7
     - advertisement-chefvend-8
     - advertisement-chefvend-9
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-chefvend-1
-    - thankyou-chefvend-2
-    - thankyou-chefvend-3
-    - thankyou-chefvend-4
index 7d4508473843f9ce06ee57fe08123fde31285f6a..69a37de184be8b75458bf3231c580cabc5467a0b 100644 (file)
@@ -1,9 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: ChemDrobeAds
-  advertisements:
+  messages:
     - advertisement-chemdrobe-1
     - advertisement-chemdrobe-2
     - advertisement-chemdrobe-3
-  thankyous:
-    - vending-machine-thanks
-
index fe6cb1bf26a25147e1f238321c388e5aa9f850bd..db3d492c459625e5391bfdd653049611ea5fa02b 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: CigaretteMachineAds
-  advertisements:
+  messages:
   - advertisement-cigs-1
   - advertisement-cigs-2
   - advertisement-cigs-3
@@ -13,8 +13,3 @@
   - advertisement-cigs-10
   - advertisement-cigs-11
   - advertisement-cigs-12
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-cigs-1
-  - thankyou-cigs-2
-  - thankyou-cigs-3
index 5c728513b89f9f59c29adecfda377a6de04568cb..dc109f8eb996bb5112c4599c8667b65ec0537a88 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: ClothesMateAds
-  advertisements:
+  messages:
   - advertisement-clothes-1
   - advertisement-clothes-2
   - advertisement-clothes-3
@@ -8,5 +8,3 @@
   - advertisement-clothes-5
   - advertisement-clothes-6
   - advertisement-clothes-7
-  thankyous:
-  - vending-machine-thanks
index 5153040165c02357703b69feee68f874b904df38..4781768cf0c57fef5ed92e56b8b8d36d15444d2f 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: HotDrinksMachineAds
-  advertisements:
+  messages:
     - advertisement-coffee-1
     - advertisement-coffee-2
     - advertisement-coffee-3
@@ -15,9 +15,3 @@
     - advertisement-coffee-12
     - advertisement-coffee-13
     - advertisement-coffee-14
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-coffee-1
-    - thankyou-coffee-2
-    - thankyou-coffee-3
-    - thankyou-coffee-4
index 862846274da6f9d62ae43521530c2a16dacff675..d12d7eb92f4744a67d5c74f736cde116fb7ea8d1 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: RobustSoftdrinksAds
-  advertisements:
+  messages:
   - advertisement-cola-1
   - advertisement-cola-2
   - advertisement-cola-3
@@ -9,9 +9,3 @@
   - advertisement-cola-6
   - advertisement-cola-7
   - advertisement-cola-8
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-cola-1
-  - thankyou-cola-2
-  - thankyou-cola-3
-  - thankyou-cola-4
index 05dbc75887591c20bc45ec96489495272df3d7d5..d1d07df0c4e599ca2cde2970fc4b670166761dfe 100644 (file)
@@ -1,11 +1,9 @@
-- type: advertisementsPack
+- type: messagePack
   id: CondimentVendAds
-  advertisements:
+  messages:
   - advertisement-condiment-1
   - advertisement-condiment-2
   - advertisement-condiment-3
   - advertisement-condiment-4
   - advertisement-condiment-5
   - advertisement-condiment-6
-  thankyous:
-  - vending-machine-thanks
index b6e2d485cec0d703ebdcbb735776febd2c42dd78..47523c6e936ec89e768b7c59a5d0af290aa80cd4 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: CuraDrobeAds
-  advertisements:
+  messages:
     - advertisement-curadrobe-1
     - advertisement-curadrobe-2
     - advertisement-curadrobe-3
-  thankyous:
-    - vending-machine-thanks
index e64b519869222794e511390af159d769644de84c..50024ce3d99151ec18f3f8e34e98bc7ada40c1e3 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: DetDrobeAds
-  advertisements:
+  messages:
     - advertisement-detdrobe-1
     - advertisement-detdrobe-2
     - advertisement-detdrobe-3
-  thankyous:
-    - vending-machine-thanks
index ebaba26b6f410d84b127ccc71c9c1906282dab79..ac31dc075b95ccde9fb173917fc62894d06a968b 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: DinnerwareAds
-  advertisements:
+  messages:
     - advertisement-dinnerware-1
     - advertisement-dinnerware-2
     - advertisement-dinnerware-3
@@ -11,5 +11,3 @@
     - advertisement-dinnerware-8
     - advertisement-dinnerware-9
     - advertisement-dinnerware-10
-  thankyous:
-    - vending-machine-thanks
index 5260e2bbcc6d7eb25cf342992d80c5224c7a269b..dce8646a60ca0621efac78172ddad1bc5a577fb1 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: DiscountDansAds
-  advertisements:
+  messages:
   - advertisement-discount-1
   - advertisement-discount-2
   - advertisement-discount-3
   - advertisement-discount-7
   - advertisement-discount-8
   - advertisement-discount-9
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-discount-1
-  - thankyou-discount-2
-  - thankyou-discount-3
-  - thankyou-discount-4
-  - thankyou-discount-5
-  - thankyou-discount-6
-  - thankyou-discount-7
-  - thankyou-discount-8
index 29ea90e7655b1c09dfd532e021e5219a0594de36..73766aa749f9bf4eb0d6bdda5ebcd2f547516ad5 100644 (file)
@@ -1,14 +1,8 @@
-- type: advertisementsPack
+- type: messagePack
   id: DonutAds
-  advertisements:
+  messages:
     - advertisement-donut-1
     - advertisement-donut-2
     - advertisement-donut-3
     - advertisement-donut-4
     - advertisement-donut-5
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-donut-1
-    - thankyou-donut-2
-    - thankyou-donut-3
-    - thankyou-donut-4
index 5d1290147eeba639621d382cd4950ef500a6a45f..ec92fbe4dea8e813447fd84eb22a2db175d60664 100644 (file)
@@ -1,10 +1,8 @@
-- type: advertisementsPack
+- type: messagePack
   id: EngiDrobeAds
-  advertisements:
+  messages:
     - advertisement-engidrobe-1
     - advertisement-engidrobe-2
     - advertisement-engidrobe-3
     - advertisement-engidrobe-4
     - advertisement-engidrobe-5
-  thankyous:
-    - vending-machine-thanks
index ad100c462639fe64adfe68a19d15b53c3f81d7f5..7619ea1856c328fccd482491b97483899086f720 100644 (file)
@@ -1,11 +1,9 @@
-- type: advertisementsPack
+- type: messagePack
   id: FatExtractorFacts
-  advertisements:
+  messages:
   - fat-extractor-fact-1
   - fat-extractor-fact-2
   - fat-extractor-fact-3
   - fat-extractor-fact-4
   - fat-extractor-fact-5
   - fat-extractor-fact-6
-  thankyous:
-  - vending-machine-thanks
index e640b378def7fbaaba03fd1c1e95dca85e560c63..1348635e1f50b0f6781c455285a2a25f7229620d 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: GoodCleanFunAds
-  advertisements:
+  messages:
   - advertisement-goodcleanfun-1
   - advertisement-goodcleanfun-2
   - advertisement-goodcleanfun-3
@@ -11,9 +11,3 @@
   - advertisement-goodcleanfun-8
   - advertisement-goodcleanfun-9
   - advertisement-goodcleanfun-10
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-goodcleanfun-1
-  - thankyou-goodcleanfun-2
-  - thankyou-goodcleanfun-3
-  - thankyou-goodcleanfun-4
index 71d56bdcccc50c02db74bb323dd8c9092612d773..722388055b9f62ba12ed17fad0c370cac16716ce 100644 (file)
@@ -1,7 +1,5 @@
-- type: advertisementsPack
+- type: messagePack
   id: GeneDrobeAds
-  advertisements:
+  messages:
     - advertisement-genedrobe-1
     - advertisement-genedrobe-2
-  thankyous:
-    - vending-machine-thanks
index 737ad02e291b3d6fd75371a62fe62277f2e06dfc..e145ebcdacbd9fb5342cc9bf37d16fd3c448cb81 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: HappyHonkAds
-  advertisements:
+  messages:
   - advertisement-happyhonk-1
   - advertisement-happyhonk-2
   - advertisement-happyhonk-3
@@ -11,9 +11,3 @@
   - advertisement-happyhonk-8
   - advertisement-happyhonk-9
   - advertisement-happyhonk-10
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-happyhonk-1
-  - thankyou-happyhonk-2
-  - thankyou-happyhonk-3
-  - thankyou-happyhonk-4
index 213097db0d95343476c0cd3bafd80c9c90170861..5999c496f51fb924568fddadbfd065fb1da5136b 100644 (file)
@@ -1,9 +1,7 @@
-- type: advertisementsPack
+- type: messagePack
   id: HyDrobeAds
-  advertisements:
+  messages:
     - advertisement-hydrobe-1
     - advertisement-hydrobe-2
     - advertisement-hydrobe-3
     - advertisement-hydrobe-4
-  thankyous:
-    - vending-machine-thanks
index 2d1ee1e7dfbe8e5dc8f6984db016983b4fbbcfc1..8310136bf8fbd162565d7e2ce25bfc659a292965 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: JaniDrobeAds
-  advertisements:
+  messages:
     - advertisement-janidrobe-1
     - advertisement-janidrobe-2
     - advertisement-janidrobe-3
-  thankyous:
-    - vending-machine-thanks
index 5f3892d0f95ccca85cbb8991b60c1bc9c39421e9..a948413abde33362808be6f1f4810869a5ce254f 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: LawDrobeAds
-  advertisements:
+  messages:
     - advertisement-lawdrobe-1
     - advertisement-lawdrobe-2
     - advertisement-lawdrobe-3
@@ -9,10 +9,3 @@
     - advertisement-lawdrobe-6
     - advertisement-lawdrobe-7
     - advertisement-lawdrobe-8
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-lawdrobe-1
-    - thankyou-lawdrobe-2
-    - thankyou-lawdrobe-3
-    - thankyou-lawdrobe-4
-    - thankyou-lawdrobe-5
index 5785f04bac6047f3568545f7b43fa1d223cf45bf..896a3853e7c4486deff2ff996ad27ca0a1f73188 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: MagiVendAds
-  advertisements:
+  messages:
   - advertisement-magivend-1
   - advertisement-magivend-2
   - advertisement-magivend-3
@@ -12,5 +12,3 @@
   - advertisement-magivend-9
   - advertisement-magivend-10
   - advertisement-magivend-11
-  thankyous:
-  - vending-machine-thanks
index f5744722e476224e0f5884c026d0e73717f96cc1..b7b055231b82b3a3c3c5634fed3f6be412a99002 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: MediDrobeAds
-  advertisements:
+  messages:
     - advertisement-medidrobe-1
     - advertisement-medidrobe-2
     - advertisement-medidrobe-3
-  thankyous:
-    - vending-machine-thanks
index 77babcf55a312613354dccb0e79a217f84e2d296..b6e6ae098e9df6ba03adc47d33fe08cf67aa0be6 100644 (file)
@@ -1,11 +1,9 @@
-- type: advertisementsPack
+- type: messagePack
   id: MegaSeedAds
-  advertisements:
+  messages:
     - advertisement-megaseed-1
     - advertisement-megaseed-2
     - advertisement-megaseed-3
     - advertisement-megaseed-4
     - advertisement-megaseed-5
     - advertisement-megaseed-6
-  thankyous:
-    - vending-machine-thanks
index 3e710bf7bee6edf7ec30c9cb32a43f29c95f9d82..a79a4c8a6c498b202ba0d22d294bff3b0aa718bf 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: NanoMedAds
-  advertisements:
+  messages:
     - advertisement-nanomed-1
     - advertisement-nanomed-2
     - advertisement-nanomed-3
@@ -10,5 +10,3 @@
     - advertisement-nanomed-7
     - advertisement-nanomed-8
     - advertisement-nanomed-9
-  thankyous:
-    - vending-machine-thanks
index 40a39336eea68a76880e1b726bde58e7a155b4d3..a3ade349602b4da67e4d23b9159a4fd82bc925ac 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: NutriMaxAds
-  advertisements:
+  messages:
     - advertisement-nutrimax-1
     - advertisement-nutrimax-2
     - advertisement-nutrimax-3
@@ -8,7 +8,3 @@
     - advertisement-nutrimax-5
     - advertisement-nutrimax-6
     - advertisement-nutrimax-7
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-nutrimax-1
-    - thankyou-nutrimax-2
index f4a8f14fee6c4924891b6bb0f67354e98a46c8c4..82ece7d76329527e1e57738f9a6c76c825de88d1 100644 (file)
@@ -1,9 +1,7 @@
-- type: advertisementsPack
+- type: messagePack
   id: RoboDrobeAds
-  advertisements:
+  messages:
     - advertisement-robodrobe-1
     - advertisement-robodrobe-2
     - advertisement-robodrobe-3
     - advertisement-robodrobe-4
-  thankyous:
-    - vending-machine-thanks
index 9a3a2243606b63d51b2874b4b1bc3bcd411d89b7..f8b125073b8506827a539329fff862ca2a3b6ea7 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: SciDrobeAds
-  advertisements:
+  messages:
     - advertisement-scidrobe-1
     - advertisement-scidrobe-2
     - advertisement-scidrobe-3
-  thankyous:
-    - vending-machine-thanks
index 886856c153edbe81d325e3e055a4e60dd63301d3..99c2c402deebcd87e444fe8fbe44baa661d4e265 100644 (file)
@@ -1,10 +1,8 @@
-- type: advertisementsPack
+- type: messagePack
   id: SecDrobeAds
-  advertisements:
+  messages:
     - advertisement-secdrobe-1
     - advertisement-secdrobe-2
     - advertisement-secdrobe-3
     - advertisement-secdrobe-4
     - advertisement-secdrobe-5
-  thankyous:
-    - vending-machine-thanks
index 8b9f986572706234eb6465d2a61f91bae2a3c807..0b32ed166d52e8164f8a2b5692edc144aa6c33aa 100644 (file)
@@ -1,13 +1,8 @@
-- type: advertisementsPack
+- type: messagePack
   id: SecTechAds
-  advertisements:
+  messages:
     - advertisement-sectech-1
     - advertisement-sectech-2
     - advertisement-sectech-3
     - advertisement-sectech-4
     - advertisement-sectech-5
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-sectech-1
-    - thankyou-sectech-2
-    - thankyou-sectech-3
index e7c20761a6aea4717cadb0bb8f76f9d96b3a9850..d92a95f70ffead4476e257464400064cae51b5c7 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: SmartFridgeAds
-  advertisements:
+  messages:
   - advertisement-smartfridge-1
   - advertisement-smartfridge-2
   - advertisement-smartfridge-3
@@ -9,5 +9,3 @@
   - advertisement-smartfridge-6
   - advertisement-smartfridge-7
   - advertisement-smartfridge-8
-  thankyous:
-  - vending-machine-thanks
index c8f960d97229df134e89196fb16d56c1ed4269e8..3d9b93f9c27b2a00ac588fde92a63c0552adfed5 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: GetmoreChocolateCorpAds
-  advertisements:
+  messages:
   - advertisement-snack-1
   - advertisement-snack-2
   - advertisement-snack-3
   - advertisement-snack-13
   - advertisement-snack-14
   - advertisement-snack-15
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-snack-1
-  - thankyou-snack-2
-  - thankyou-snack-3
-  - thankyou-snack-4
-  - thankyou-snack-5
-  - thankyou-snack-6
index ff4957015317c2f39f46826223f526e893c5d9d0..630de1e615f0923d67454bd2902a2bf84242333a 100644 (file)
@@ -1,14 +1,9 @@
-- type: advertisementsPack
+- type: messagePack
   id: BodaAds
-  advertisements:
+  messages:
   - advertisement-sovietsoda-1
   - advertisement-sovietsoda-2
   - advertisement-sovietsoda-3
   - advertisement-sovietsoda-4
   - advertisement-sovietsoda-5
   - advertisement-sovietsoda-6
-  thankyous:
-  - vending-machine-thanks
-  - thankyou-sovietsoda-1
-  - thankyou-sovietsoda-2
-  - thankyou-sovietsoda-3
index c9e3bbfe5c46aed451bf69a6c2e1f17a8c63e34e..dc89d04aa0b2041be966c472a88e6b46e52dd03b 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: SyndieDrobeAds
-  advertisements:
+  messages:
     - advertisement-syndiedrobe-1
     - advertisement-syndiedrobe-2
     - advertisement-syndiedrobe-3
     - advertisement-syndiedrobe-29
     - advertisement-syndiedrobe-30
     - advertisement-syndiedrobe-31
-  thankyous:
-    - vending-machine-thanks
-    - thankyou-syndiedrobe-1
-    - thankyou-syndiedrobe-2
-    - thankyou-syndiedrobe-3
-    - thankyou-syndiedrobe-4
-    - thankyou-syndiedrobe-5
index 090ec81cffbe4bb8f96770b8b564332b1e6d44bf..8b06cdb5172601f3e05e9f29a702179d9076a381 100644 (file)
@@ -1,11 +1,9 @@
-- type: advertisementsPack
+- type: messagePack
   id: AutoDrobeAds
-  advertisements:
+  messages:
   - advertisement-theater-1
   - advertisement-theater-2
   - advertisement-theater-3
   - advertisement-theater-4
   - advertisement-theater-5
   - advertisement-theater-6
-  thankyous:
-  - vending-machine-thanks
index aaa0c411336b91d4a4980310a7bdfe2a847a103d..31c0e0c241129f9bf458097f92ae3b6833f5e61d 100644 (file)
@@ -1,6 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: VendomatAds
-  advertisements:
+  messages:
   - advertisement-vendomat-1
   - advertisement-vendomat-2
   - advertisement-vendomat-3
@@ -8,5 +8,3 @@
   - advertisement-vendomat-5
   - advertisement-vendomat-6
   - advertisement-vendomat-7
-  thankyous:
-  - vending-machine-thanks
index a64bcd824c62753a6d14d62890d9990d719474a3..c48f9e7d2e452e1dcf31c359479dd72facad9e8f 100644 (file)
@@ -1,8 +1,6 @@
-- type: advertisementsPack
+- type: messagePack
   id: ViroDrobeAds
-  advertisements:
+  messages:
     - advertisement-virodrobe-1
     - advertisement-virodrobe-2
     - advertisement-virodrobe-3
-  thankyous:
-  - vending-machine-thanks
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/boozeomat.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/boozeomat.yml
new file mode 100644 (file)
index 0000000..e5c9688
--- /dev/null
@@ -0,0 +1,7 @@
+- type: messagePack
+  id: BoozeOMatGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-boozeomat-1
+  - thankyou-boozeomat-2
+  - thankyou-boozeomat-3
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chang.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chang.yml
new file mode 100644 (file)
index 0000000..a348d8f
--- /dev/null
@@ -0,0 +1,6 @@
+- type: messagePack
+  id: ChangGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-chang-1
+  - thankyou-chang-2
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chefvend.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/chefvend.yml
new file mode 100644 (file)
index 0000000..9324958
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: ChefvendGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-chefvend-1
+  - thankyou-chefvend-2
+  - thankyou-chefvend-3
+  - thankyou-chefvend-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cigs.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cigs.yml
new file mode 100644 (file)
index 0000000..108a34a
--- /dev/null
@@ -0,0 +1,7 @@
+- type: messagePack
+  id: CigaretteMachineGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-cigs-1
+  - thankyou-cigs-2
+  - thankyou-cigs-3
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/coffee.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/coffee.yml
new file mode 100644 (file)
index 0000000..6f2aef0
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: HotDrinksMachineGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-coffee-1
+  - thankyou-coffee-2
+  - thankyou-coffee-3
+  - thankyou-coffee-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cola.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/cola.yml
new file mode 100644 (file)
index 0000000..76f00fd
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: RobustSoftdrinksGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-cola-1
+  - thankyou-cola-2
+  - thankyou-cola-3
+  - thankyou-cola-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/discount.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/discount.yml
new file mode 100644 (file)
index 0000000..d3f7d89
--- /dev/null
@@ -0,0 +1,12 @@
+- type: messagePack
+  id: DiscountDansGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-discount-1
+  - thankyou-discount-2
+  - thankyou-discount-3
+  - thankyou-discount-4
+  - thankyou-discount-5
+  - thankyou-discount-6
+  - thankyou-discount-7
+  - thankyou-discount-8
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/donut.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/donut.yml
new file mode 100644 (file)
index 0000000..3c28741
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: DonutGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-donut-1
+  - thankyou-donut-2
+  - thankyou-donut-3
+  - thankyou-donut-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/games.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/games.yml
new file mode 100644 (file)
index 0000000..5d84261
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: GoodCleanFunGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-goodcleanfun-1
+  - thankyou-goodcleanfun-2
+  - thankyou-goodcleanfun-3
+  - thankyou-goodcleanfun-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/generic.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/generic.yml
new file mode 100644 (file)
index 0000000..98a2d7d
--- /dev/null
@@ -0,0 +1,4 @@
+- type: messagePack
+  id: GenericVendGoodbyes
+  messages:
+  - vending-machine-thanks
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/happyhonk.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/happyhonk.yml
new file mode 100644 (file)
index 0000000..7859d55
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: HappyHonkGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-happyhonk-1
+  - thankyou-happyhonk-2
+  - thankyou-happyhonk-3
+  - thankyou-happyhonk-4
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/lawdrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/lawdrobe.yml
new file mode 100644 (file)
index 0000000..56678c1
--- /dev/null
@@ -0,0 +1,8 @@
+- type: messagePack
+  id: LawDrobeGoodbyes
+  messages:
+  - thankyou-lawdrobe-1
+  - thankyou-lawdrobe-2
+  - thankyou-lawdrobe-3
+  - thankyou-lawdrobe-4
+  - thankyou-lawdrobe-5
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/nutrimax.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/nutrimax.yml
new file mode 100644 (file)
index 0000000..3568ae3
--- /dev/null
@@ -0,0 +1,6 @@
+- type: messagePack
+  id: NutriMaxGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-nutrimax-1
+  - thankyou-nutrimax-2
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sectech.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sectech.yml
new file mode 100644 (file)
index 0000000..8909693
--- /dev/null
@@ -0,0 +1,7 @@
+- type: messagePack
+  id: SecTechGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-sectech-1
+  - thankyou-sectech-2
+  - thankyou-sectech-3
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/snack.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/snack.yml
new file mode 100644 (file)
index 0000000..bd86e07
--- /dev/null
@@ -0,0 +1,10 @@
+- type: messagePack
+  id: GetmoreChocolateCorpGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-snack-1
+  - thankyou-snack-2
+  - thankyou-snack-3
+  - thankyou-snack-4
+  - thankyou-snack-5
+  - thankyou-snack-6
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sovietsoda.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/sovietsoda.yml
new file mode 100644 (file)
index 0000000..01ab25a
--- /dev/null
@@ -0,0 +1,7 @@
+- type: messagePack
+  id: BodaGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-sovietsoda-1
+  - thankyou-sovietsoda-2
+  - thankyou-sovietsoda-3
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/syndiedrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Goodbyes/syndiedrobe.yml
new file mode 100644 (file)
index 0000000..1246eb3
--- /dev/null
@@ -0,0 +1,9 @@
+- type: messagePack
+  id: SyndieDrobeGoodbyes
+  messages:
+  - vending-machine-thanks
+  - thankyou-syndiedrobe-1
+  - thankyou-syndiedrobe-2
+  - thankyou-syndiedrobe-3
+  - thankyou-syndiedrobe-4
+  - thankyou-syndiedrobe-5
index 472f40fdcce53cd5187450a5648c92b16c4b787f..c97dc4b9dc925e665f02ae4ffd254013b53135a2 100644 (file)
         density: 190
   - type: Advertise
     pack: CondimentVendAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Transform
     noRot: false
     normalState: normal-unshaded
   - type: Advertise
     pack: AmmoVendAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/ammo.rsi
     loopDeny: false
   - type: Advertise
     pack: BoozeOMatAds
+  - type: SpeakOnUIClosed
+    pack: BoozeOMatGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/boozeomat.rsi
     ejectState: eject-unshaded
   - type: Advertise
     pack: ChefvendAds
+  - type: SpeakOnUIClosed
+    pack: ChefvendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/chefvend.rsi
     layers:
     denyState: deny-unshaded
   - type: Advertise
     pack: CigaretteMachineAds
+  - type: SpeakOnUIClosed
+    pack: CigaretteMachineGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/cigs.rsi
     denyState: deny-unshaded
   - type: Advertise
     pack: ClothesMateAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/clothing.rsi
     denyState: deny-unshaded
   - type: Advertise
     pack: ClothesMateAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/winterdrobe.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: HotDrinksMachineAds
+  - type: SpeakOnUIClosed
+    pack: HotDrinksMachineGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/coffee.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: RobustSoftdrinksAds
+  - type: SpeakOnUIClosed
+    pack: RobustSoftdrinksGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/cola.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: RobustSoftdrinksAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/pwrgame.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: RobustSoftdrinksAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/gib.rsi
     ejectState: eject-unshaded
   - type: Advertise
     pack: DinnerwareAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/dinnerware.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: MagiVendAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/magivend.rsi
     layers:
     initialStockQuality: 0.33
   - type: Advertise
     pack: DiscountDansAds
+  - type: SpeakOnUIClosed
+    pack: DiscountDansGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/discount.rsi
     ejectDelay: 0.6
   - type: Advertise
     pack: NanoMedAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/medical.rsi
     layers:
     denyState: deny-unshaded
   - type: Advertise
     pack: NutriMaxAds
+  - type: SpeakOnUIClosed
+    pack: NutriMaxGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/nutri.rsi
     layers:
     denyState: deny-unshaded
   - type: Advertise
     pack: SecTechAds
+  - type: SpeakOnUIClosed
+    pack: SecTechGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/sec.rsi
     layers:
     denyState: deny-unshaded
   - type: Advertise
     pack: MegaSeedAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/seeds.rsi
     layers:
     initialStockQuality: 0.33
   - type: Advertise
     pack: GetmoreChocolateCorpAds
+  - type: SpeakOnUIClosed
+    pack: GetmoreChocolateCorpGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/snack.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: BodaAds
+  - type: SpeakOnUIClosed
+    pack: BodaGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/sovietsoda.rsi
     screenState: screen
   - type: Advertise
     pack: AutoDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/theater.rsi
     denyState: deny-unshaded
   - type: Advertise
     pack: VendomatAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/vendomat.rsi
     denyState: deny-unshaded
   - type: Advertise
     pack: VendomatAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/robotics.rsi
     ejectDelay: 1.8
   - type: Advertise
     pack: GoodCleanFunAds
+  - type: SpeakOnUIClosed
+    pack: GoodCleanFunGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/games.rsi
     layers:
     initialStockQuality: 0.33
   - type: Advertise
     pack: ChangAds
+  - type: SpeakOnUIClosed
+    pack: ChangGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/changs.rsi
     initialStockQuality: 0.33
   - type: Advertise
     pack: DonutAds
+  - type: SpeakOnUIClosed
+    pack: DonutGoodbyes
   - type: Speech
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/donut.rsi
     normalState: normal-unshaded
   - type: Advertise
     pack: HyDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/hydrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: LawDrobeAds
+  - type: SpeakOnUIClosed
+    pack: LawDrobeGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/lawdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: SecDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/secdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: BarDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/bardrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: CargoDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/cargodrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: MediDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/medidrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: ChemDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/chemdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: CuraDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/curadrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: AtmosDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/atmosdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: EngiDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/engidrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: ChefDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/chefdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: DetDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/detdrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: JaniDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/janidrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: SciDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/scidrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: SyndieDrobeAds
+  - type: SpeakOnUIClosed
+    pack: SyndieDrobeGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/syndiedrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: RoboDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/robodrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: GeneDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/genedrobe.rsi
     layers:
     normalState: normal-unshaded
   - type: Advertise
     pack: ViroDrobeAds
+  - type: SpeakOnUIClosed
+    pack: GenericVendGoodbyes
   - type: Sprite
     sprite: Structures/Machines/VendingMachines/virodrobe.rsi
     layers:
     color: "#3c5eb5"
   - type: Advertise
     pack: HappyHonkAds
+  - type: SpeakOnUIClosed
+    pack: HappyHonkGoodbyes
   - type: AccessReader
     access: [["Kitchen"], ["Theatre"]]