From: Tayrtahn Date: Thu, 28 Mar 2024 06:28:45 +0000 (-0400) Subject: Arcade machine improvements (#24200) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=b1ba6b5bb615615cc58f255dc9fe84c5ffe8822b;p=space-station-14.git Arcade machine improvements (#24200) * Give 'em something to talk about * Wire panel visuals * Wire graphics tweak * More ads and thanks * More ads for a noisy arcade * New screen for space villain machines * Implement EmitSoundIntervalComponent and a bunch of arcade noises * Require power for sounds * Allow earlier startup intervals * Orange glow * Audio attributions * Include the PR link * Replace EmitSoundInterval with expanded SpamEmitSound * Remove pacman-themed arcade sounds * Documentation good. * Updated methods to use Entity * Refactored SpamEmitSound to get rid of accumulator and chance. * Fixed prewarm logic * Moved stuff to Shared * Fix outdated YAML * Better prediction, auto pause handling * Make enable/disable reset the timer instead of trying to save it. --- diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs index 5613d91544..e2acec52a3 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeComponent.cs @@ -19,4 +19,9 @@ public sealed partial class BlockGameArcadeComponent : Component /// The players currently viewing (but not playing) the active session of NT-BG. /// public readonly List Spectators = new(); + + /// + /// Whether the game machine should thank (or otherwise talk to) the player when they leave + /// + public bool ShouldSayThankYou; } diff --git a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs index 34a5689fd1..0d9487dab8 100644 --- a/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs +++ b/Content.Server/Arcade/BlockGame/BlockGameArcadeSystem.cs @@ -1,5 +1,6 @@ using Content.Server.Power.Components; using Content.Shared.UserInterface; +using Content.Server.Advertise; using Content.Shared.Arcade; using Robust.Server.GameObjects; using Robust.Shared.Player; @@ -9,6 +10,7 @@ namespace Content.Server.Arcade.BlockGame; public sealed class BlockGameArcadeSystem : EntitySystem { [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly AdvertiseSystem _advertise = default!; public override void Initialize() { @@ -89,7 +91,15 @@ public sealed class BlockGameArcadeSystem : EntitySystem UpdatePlayerStatus(uid, component.Player, blockGame: component); } else + { + // Everybody's gone component.Player = null; + if (component.ShouldSayThankYou && TryComp(uid, out var advertise)) + { + _advertise.SayThankYou(uid, advertise); + component.ShouldSayThankYou = false; + } + } UpdatePlayerStatus(uid, temp, blockGame: component); } @@ -103,6 +113,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem _uiSystem.CloseAll(bui); component.Player = null; component.Spectators.Clear(); + component.ShouldSayThankYou = false; } private void OnPlayerAction(EntityUid uid, BlockGameArcadeComponent component, BlockGameMessages.BlockGamePlayerActionMessage msg) @@ -122,6 +133,8 @@ public sealed class BlockGameArcadeSystem : EntitySystem return; } + component.ShouldSayThankYou = true; + component.Game.ProcessInput(msg.PlayerAction); } } diff --git a/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeComponent.cs b/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeComponent.cs index e93fcc6e8f..c3a8877393 100644 --- a/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeComponent.cs +++ b/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeComponent.cs @@ -110,4 +110,9 @@ public sealed partial class SpaceVillainArcadeComponent : SharedSpaceVillainArca /// [ViewVariables(VVAccess.ReadWrite)] public int RewardAmount = 0; + + /// + /// Whether the game machine should thank (or otherwise talk to) the player when they leave + /// + public bool ShouldSayThankYou; } diff --git a/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeSystem.cs b/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeSystem.cs index d97c94fd99..24fa6e32d1 100644 --- a/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeSystem.cs +++ b/Content.Server/Arcade/SpaceVillainGame/SpaceVillainArcadeSystem.cs @@ -1,5 +1,6 @@ using Content.Server.Power.Components; using Content.Shared.UserInterface; +using Content.Server.Advertise; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -13,6 +14,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly AdvertiseSystem _advertise = default!; public override void Initialize() { @@ -22,6 +24,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem SubscribeLocalEvent(OnAfterUIOpenSV); SubscribeLocalEvent(OnSVPlayerAction); SubscribeLocalEvent(OnSVillainPower); + SubscribeLocalEvent(OnBoundUIClosed); } /// @@ -79,6 +82,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem case PlayerAction.Heal: case PlayerAction.Recharge: component.Game.ExecutePlayerAction(uid, msg.PlayerAction, component); + component.ShouldSayThankYou = true; // Any sort of gameplay action counts break; case PlayerAction.NewGame: _audioSystem.PlayPvs(component.NewGameSound, uid, AudioParams.Default.WithVolume(-4f)); @@ -106,5 +110,19 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem if (_uiSystem.TryGetUi(uid, SpaceVillainArcadeUiKey.Key, out var bui)) _uiSystem.CloseAll(bui); + + component.ShouldSayThankYou = false; + } + + private void OnBoundUIClosed(Entity ent, ref BoundUIClosedEvent args) + { + if (args.UiKey is not SpaceVillainArcadeUiKey || (SpaceVillainArcadeUiKey) args.UiKey != SpaceVillainArcadeUiKey.Key) + return; + + if (ent.Comp.ShouldSayThankYou && TryComp(ent.Owner, out var advertise)) + { + _advertise.SayThankYou(ent.Owner, advertise); + ent.Comp.ShouldSayThankYou = false; + } } } diff --git a/Content.Server/Bed/Sleep/SleepingSystem.cs b/Content.Server/Bed/Sleep/SleepingSystem.cs index b497254433..5e4f0eddb5 100644 --- a/Content.Server/Bed/Sleep/SleepingSystem.cs +++ b/Content.Server/Bed/Sleep/SleepingSystem.cs @@ -1,5 +1,6 @@ using Content.Server.Popups; -using Content.Server.Sound.Components; +using Content.Server.Sound; +using Content.Shared.Sound.Components; using Content.Shared.Actions; using Content.Shared.Audio; using Content.Shared.Bed.Sleep; @@ -30,6 +31,7 @@ namespace Content.Server.Bed.Sleep [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; + [Dependency] private readonly EmitSoundSystem _emitSound = default!; [ValidatePrototypeId] public const string SleepActionId = "ActionSleep"; @@ -71,8 +73,8 @@ namespace Content.Server.Bed.Sleep { emitSound.Sound = sleepSound.Snore; } - emitSound.PlayChance = sleepSound.Chance; - emitSound.RollInterval = sleepSound.Interval; + emitSound.MinInterval = sleepSound.Interval; + emitSound.MaxInterval = sleepSound.MaxInterval; emitSound.PopUp = sleepSound.PopUp; } @@ -128,7 +130,7 @@ namespace Content.Server.Bed.Sleep return; } if (TryComp(uid, out var spam)) - spam.Enabled = args.NewMobState == MobState.Alive; + _emitSound.SetEnabled((uid, spam), args.NewMobState == MobState.Alive); } private void AddWakeVerb(EntityUid uid, SleepingComponent component, GetVerbsEvent args) diff --git a/Content.Server/Sound/Components/SpamEmitSoundComponent.cs b/Content.Server/Sound/Components/SpamEmitSoundComponent.cs deleted file mode 100644 index d17bbb9e8f..0000000000 --- a/Content.Server/Sound/Components/SpamEmitSoundComponent.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Content.Shared.Sound.Components; - -namespace Content.Server.Sound.Components -{ - /// - /// Rolls to play a sound every few seconds. - /// - [RegisterComponent] - public sealed partial class SpamEmitSoundComponent : BaseEmitSoundComponent - { - [DataField("accumulator")] - public float Accumulator = 0f; - - [DataField("rollInterval")] - public float RollInterval = 2f; - - [DataField("playChance")] - public float PlayChance = 0.5f; - - // Always Pvs. - [DataField("popUp")] - public string? PopUp; - - [DataField("enabled")] - public bool Enabled = true; - } -} diff --git a/Content.Server/Sound/EmitSoundSystem.cs b/Content.Server/Sound/EmitSoundSystem.cs index 059800c3f9..5b9620990e 100644 --- a/Content.Server/Sound/EmitSoundSystem.cs +++ b/Content.Server/Sound/EmitSoundSystem.cs @@ -2,12 +2,17 @@ using Content.Server.Explosion.EntitySystems; using Content.Server.Sound.Components; using Content.Shared.UserInterface; using Content.Shared.Sound; -using Robust.Shared.Random; +using Content.Shared.Sound.Components; +using Robust.Shared.Timing; +using Robust.Shared.Network; namespace Content.Server.Sound; public sealed class EmitSoundSystem : SharedEmitSoundSystem { + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + public override void Update(float frameTime) { base.Update(frameTime); @@ -18,18 +23,13 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem if (!soundSpammer.Enabled) continue; - soundSpammer.Accumulator += frameTime; - if (soundSpammer.Accumulator < soundSpammer.RollInterval) - { - continue; - } - soundSpammer.Accumulator -= soundSpammer.RollInterval; - - if (Random.Prob(soundSpammer.PlayChance)) + if (_timing.CurTime >= soundSpammer.NextSound) { if (soundSpammer.PopUp != null) Popup.PopupEntity(Loc.GetString(soundSpammer.PopUp), uid); TryEmitSound(uid, soundSpammer, predict: false); + + SpamEmitSoundReset((uid, soundSpammer)); } } } @@ -40,6 +40,8 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem SubscribeLocalEvent(HandleEmitSoundOnTrigger); SubscribeLocalEvent(HandleEmitSoundOnUIOpen); + + SubscribeLocalEvent(HandleSpamEmitSoundMapInit); } private void HandleEmitSoundOnUIOpen(EntityUid uid, EmitSoundOnUIOpenComponent component, AfterActivatableUIOpenEvent args) @@ -52,4 +54,39 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem TryEmitSound(uid, component, args.User, false); args.Handled = true; } + + private void HandleSpamEmitSoundMapInit(Entity entity, ref MapInitEvent args) + { + SpamEmitSoundReset(entity); + + // Prewarm so multiple entities have more variation. + entity.Comp.NextSound -= Random.Next(entity.Comp.MaxInterval); + Dirty(entity); + } + + private void SpamEmitSoundReset(Entity entity) + { + if (_net.IsClient) + return; + + entity.Comp.NextSound = _timing.CurTime + ((entity.Comp.MinInterval < entity.Comp.MaxInterval) + ? Random.Next(entity.Comp.MinInterval, entity.Comp.MaxInterval) + : entity.Comp.MaxInterval); + + Dirty(entity); + } + + public override void SetEnabled(Entity entity, bool enabled) + { + if (!Resolve(entity, ref entity.Comp, false)) + return; + + if (entity.Comp.Enabled == enabled) + return; + + entity.Comp.Enabled = enabled; + + if (enabled) + SpamEmitSoundReset((entity, entity.Comp)); + } } diff --git a/Content.Server/Sound/SpamEmitSoundRequirePowerSystem.cs b/Content.Server/Sound/SpamEmitSoundRequirePowerSystem.cs new file mode 100644 index 0000000000..9cc85060c6 --- /dev/null +++ b/Content.Server/Sound/SpamEmitSoundRequirePowerSystem.cs @@ -0,0 +1,33 @@ +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Shared.Sound; +using Content.Shared.Sound.Components; + +namespace Content.Server.Sound; + +public sealed partial class SpamEmitSoundRequirePowerSystem : SharedSpamEmitSoundRequirePowerSystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnPowerChanged); + SubscribeLocalEvent(OnPowerSupply); + } + + private void OnPowerChanged(Entity entity, ref PowerChangedEvent args) + { + if (TryComp(entity.Owner, out var comp)) + { + EmitSound.SetEnabled((entity, comp), args.Powered); + } + } + + private void OnPowerSupply(Entity entity, ref PowerNetBatterySupplyEvent args) + { + if (TryComp(entity.Owner, out var comp)) + { + EmitSound.SetEnabled((entity, comp), args.Supply); + } + } +} diff --git a/Content.Shared/Bed/Sleep/SleepEmitSoundComponent.cs b/Content.Shared/Bed/Sleep/SleepEmitSoundComponent.cs index 6313f633f2..9250a33077 100644 --- a/Content.Shared/Bed/Sleep/SleepEmitSoundComponent.cs +++ b/Content.Shared/Bed/Sleep/SleepEmitSoundComponent.cs @@ -12,16 +12,16 @@ public sealed partial class SleepEmitSoundComponent : Component public SoundSpecifier Snore = new SoundCollectionSpecifier("Snores", AudioParams.Default.WithVariation(0.2f)); /// - /// Interval between snore attempts in seconds + /// Minimum interval between snore attempts in seconds /// [DataField, ViewVariables(VVAccess.ReadWrite)] - public float Interval = 5f; + public TimeSpan Interval = TimeSpan.FromSeconds(5); /// - /// Chance for snore attempt to succeed + /// Maximum interval between snore attempts in seconds /// [DataField, ViewVariables(VVAccess.ReadWrite)] - public float Chance = 0.33f; + public TimeSpan MaxInterval = TimeSpan.FromSeconds(15); /// /// Popup for snore (e.g. Zzz...) diff --git a/Content.Shared/Sound/Components/SpamEmitSoundComponent.cs b/Content.Shared/Sound/Components/SpamEmitSoundComponent.cs new file mode 100644 index 0000000000..149728a5ba --- /dev/null +++ b/Content.Shared/Sound/Components/SpamEmitSoundComponent.cs @@ -0,0 +1,44 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Sound.Components; + +/// +/// Repeatedly plays a sound with a randomized delay. +/// +[RegisterComponent, NetworkedComponent] +[AutoGenerateComponentState, AutoGenerateComponentPause] +public sealed partial class SpamEmitSoundComponent : BaseEmitSoundComponent +{ + /// + /// The time at which the next sound will play. + /// + [DataField, AutoPausedField, AutoNetworkedField] + public TimeSpan NextSound; + + /// + /// The minimum time in seconds between playing the sound. + /// + [DataField] + public TimeSpan MinInterval = TimeSpan.FromSeconds(2); + + /// + /// The maximum time in seconds between playing the sound. + /// + [DataField] + public TimeSpan MaxInterval = TimeSpan.FromSeconds(2); + + // Always Pvs. + /// + /// Content of a popup message to display whenever the sound plays. + /// + [DataField] + public LocId? PopUp; + + /// + /// Whether the timer is currently running and sounds are being played. + /// Do not set this directly, use + /// + [DataField, AutoNetworkedField] + [Access(typeof(SharedEmitSoundSystem))] + public bool Enabled = true; +} diff --git a/Content.Shared/Sound/Components/SpamEmitSoundRequirePowerComponent.cs b/Content.Shared/Sound/Components/SpamEmitSoundRequirePowerComponent.cs new file mode 100644 index 0000000000..b0547ea398 --- /dev/null +++ b/Content.Shared/Sound/Components/SpamEmitSoundRequirePowerComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Sound.Components; + +/// +/// Enables or disables an SpamEmitSound component depending +/// on the powered state of the entity. +/// +[RegisterComponent] +public sealed partial class SpamEmitSoundRequirePowerComponent : Component +{ +} diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index 56a51744ac..cd7828fc6b 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -24,7 +24,7 @@ namespace Content.Shared.Sound; [UsedImplicitly] public abstract class SharedEmitSoundSystem : EntitySystem { - [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] protected readonly IGameTiming Timing = default!; [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly ITileDefinitionManager _tileDefMan = default!; [Dependency] protected readonly IRobustRandom Random = default!; @@ -124,7 +124,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem !args.OtherFixture.Hard || !TryComp(uid, out var physics) || physics.LinearVelocity.Length() < component.MinimumVelocity || - _timing.CurTime < component.NextSound || + Timing.CurTime < component.NextSound || MetaData(uid).EntityPaused) { return; @@ -136,7 +136,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem var fraction = MathF.Min(1f, (physics.LinearVelocity.Length() - component.MinimumVelocity) / MaxVolumeVelocity); var volume = MinVolume + (MaxVolume - MinVolume) * fraction; - component.NextSound = _timing.CurTime + EmitSoundOnCollideComponent.CollideCooldown; + component.NextSound = Timing.CurTime + EmitSoundOnCollideComponent.CollideCooldown; var sound = component.Sound; if (_netMan.IsServer && sound != null) @@ -144,4 +144,8 @@ public abstract class SharedEmitSoundSystem : EntitySystem _audioSystem.PlayPvs(_audioSystem.GetSound(sound), uid, AudioParams.Default.WithVolume(volume)); } } + + public virtual void SetEnabled(Entity entity, bool enabled) + { + } } diff --git a/Content.Shared/Sound/SharedSpamEmitSoundRequirePowerSystem.cs b/Content.Shared/Sound/SharedSpamEmitSoundRequirePowerSystem.cs new file mode 100644 index 0000000000..ad44cba8a5 --- /dev/null +++ b/Content.Shared/Sound/SharedSpamEmitSoundRequirePowerSystem.cs @@ -0,0 +1,6 @@ +namespace Content.Shared.Sound; + +public abstract partial class SharedSpamEmitSoundRequirePowerSystem : EntitySystem +{ + [Dependency] protected readonly SharedEmitSoundSystem EmitSound = default!; +} diff --git a/Resources/Audio/Machines/Arcade/attributions.yml b/Resources/Audio/Machines/Arcade/attributions.yml new file mode 100644 index 0000000000..afb120bee0 --- /dev/null +++ b/Resources/Audio/Machines/Arcade/attributions.yml @@ -0,0 +1,4 @@ +- files: ["hahaha.ogg", "pew_pew.ogg", "sting_*.ogg"] + license: "CC0-1.0" + copyright: "Recorded by https://github.com/Tayrtahn" + source: "https://github.com/space-wizards/space-station-14/pull/24200" diff --git a/Resources/Audio/Machines/Arcade/hahaha.ogg b/Resources/Audio/Machines/Arcade/hahaha.ogg new file mode 100644 index 0000000000..8a01e5dd99 Binary files /dev/null and b/Resources/Audio/Machines/Arcade/hahaha.ogg differ diff --git a/Resources/Audio/Machines/Arcade/pew_pew.ogg b/Resources/Audio/Machines/Arcade/pew_pew.ogg new file mode 100644 index 0000000000..7919ca1e3a Binary files /dev/null and b/Resources/Audio/Machines/Arcade/pew_pew.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_01.ogg b/Resources/Audio/Machines/Arcade/sting_01.ogg new file mode 100644 index 0000000000..e1b7e7fd77 Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_01.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_02.ogg b/Resources/Audio/Machines/Arcade/sting_02.ogg new file mode 100644 index 0000000000..83651e37a4 Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_02.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_03.ogg b/Resources/Audio/Machines/Arcade/sting_03.ogg new file mode 100644 index 0000000000..99bb7259cb Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_03.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_04.ogg b/Resources/Audio/Machines/Arcade/sting_04.ogg new file mode 100644 index 0000000000..07d39ca3ea Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_04.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_05.ogg b/Resources/Audio/Machines/Arcade/sting_05.ogg new file mode 100644 index 0000000000..2ebed2da3c Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_05.ogg differ diff --git a/Resources/Audio/Machines/Arcade/sting_06.ogg b/Resources/Audio/Machines/Arcade/sting_06.ogg new file mode 100644 index 0000000000..6b369aa4c0 Binary files /dev/null and b/Resources/Audio/Machines/Arcade/sting_06.ogg differ diff --git a/Resources/Locale/en-US/advertisements/arcade/blockgame.ftl b/Resources/Locale/en-US/advertisements/arcade/blockgame.ftl new file mode 100644 index 0000000000..ec755abe8f --- /dev/null +++ b/Resources/Locale/en-US/advertisements/arcade/blockgame.ftl @@ -0,0 +1,26 @@ +advertisement-block-game-1 = Legally distinct! +advertisement-block-game-2 = What the hell is a T-spin? +advertisement-block-game-3 = These blocks aren't going to clear themselves! +advertisement-block-game-4 = Beep boop! Bwoooop! +advertisement-block-game-5 = Let's play a game! +advertisement-block-game-6 = 6 whole colors of gameplay! +advertisement-block-game-7 = Hot 8-bit action! +advertisement-block-game-8 = Blocks, blocks, blocks! +advertisement-block-game-9 = Think YOU can claim the high score? +advertisement-block-game-10 = Nanotrasen Block Game IS what TetrISN'T! +advertisement-block-game-11 = Now with blast processing! +advertisement-block-game-12 = Our lawyers are standing by! +advertisement-block-game-13 = Hallelujah, it's raining blocks! + +thankyou-block-game-1 = Play again soon! +thankyou-block-game-2 = Well played! +thankyou-block-game-3 = Just one more game? +thankyou-block-game-4 = Stopping so soon? +thankyou-block-game-5 = The blocks will miss you. +thankyou-block-game-6 = Thanks for playin'! +thankyou-block-game-7 = Come back soon! +thankyou-block-game-8 = Beep bwooop! +thankyou-block-game-9 = There's always time for another game! +thankyou-block-game-10 = Don't give up now! +thankyou-block-game-11 = There are always more blocks! +thankyou-block-game-12 = The blocks await your return! diff --git a/Resources/Locale/en-US/advertisements/arcade/spacevillain.ftl b/Resources/Locale/en-US/advertisements/arcade/spacevillain.ftl new file mode 100644 index 0000000000..145c380849 --- /dev/null +++ b/Resources/Locale/en-US/advertisements/arcade/spacevillain.ftl @@ -0,0 +1,28 @@ +advertisement-space-villain-1 = Are you a bad enough dude to beat this game? +advertisement-space-villain-2 = Beat the bad guy; win a prize! +advertisement-space-villain-3 = FIGHT ME! +advertisement-space-villain-4 = Space needs a hero! +advertisement-space-villain-5 = I'm holding out for a hero! +advertisement-space-villain-6 = Won't someone save us? +advertisement-space-villain-7 = Mua-hah-hah-hah! +advertisement-space-villain-8 = Spaaaaaaaace Villain! +advertisement-space-villain-9 = No one can defeat me! +advertisement-space-villain-10 = Tremble before me! +advertisement-space-villain-11 = CHALLENGE ME! +advertisement-space-villain-12 = FEAR ME! +advertisement-space-villain-13 = Do you dare to face me in battle!? +advertisement-space-villain-14 = Beware, I live! +advertisement-space-villain-15 = I hunger! + +thankyou-space-villain-1 = And where do you think you're going, punk? +thankyou-space-villain-2 = Is that all you've got? +thankyou-space-villain-3 = This fight isn't over! +thankyou-space-villain-4 = Challenge again soon! +thankyou-space-villain-5 = Who dares to challenge me next? +thankyou-space-villain-6 = I knew you couldn't defeat me! +thankyou-space-villain-7 = Too much for you to handle? +thankyou-space-villain-8 = Run, coward! +thankyou-space-villain-9 = You never stood a chance. +thankyou-space-villain-10 = Care for a rematch? +thankyou-space-villain-11 = Fight me again! +thankyou-space-villain-12 = Come back here and fight me! diff --git a/Resources/Prototypes/Catalog/Arcade/Advertisements/blockgame.yml b/Resources/Prototypes/Catalog/Arcade/Advertisements/blockgame.yml new file mode 100644 index 0000000000..efcb8934a8 --- /dev/null +++ b/Resources/Prototypes/Catalog/Arcade/Advertisements/blockgame.yml @@ -0,0 +1,29 @@ +- type: advertisementsPack + id: BlockGameAds + advertisements: + - advertisement-block-game-1 + - advertisement-block-game-2 + - advertisement-block-game-3 + - advertisement-block-game-4 + - advertisement-block-game-5 + - advertisement-block-game-6 + - advertisement-block-game-7 + - advertisement-block-game-8 + - advertisement-block-game-9 + - advertisement-block-game-10 + - advertisement-block-game-11 + - advertisement-block-game-12 + - advertisement-block-game-13 + thankyous: + - thankyou-block-game-1 + - thankyou-block-game-2 + - thankyou-block-game-3 + - thankyou-block-game-4 + - thankyou-block-game-5 + - thankyou-block-game-6 + - thankyou-block-game-7 + - thankyou-block-game-8 + - thankyou-block-game-9 + - thankyou-block-game-10 + - thankyou-block-game-11 + - thankyou-block-game-12 diff --git a/Resources/Prototypes/Catalog/Arcade/Advertisements/spacevillain.yml b/Resources/Prototypes/Catalog/Arcade/Advertisements/spacevillain.yml new file mode 100644 index 0000000000..98063a62dd --- /dev/null +++ b/Resources/Prototypes/Catalog/Arcade/Advertisements/spacevillain.yml @@ -0,0 +1,31 @@ +- type: advertisementsPack + id: SpaceVillainAds + advertisements: + - advertisement-space-villain-1 + - advertisement-space-villain-2 + - advertisement-space-villain-3 + - advertisement-space-villain-4 + - advertisement-space-villain-5 + - advertisement-space-villain-6 + - advertisement-space-villain-7 + - advertisement-space-villain-8 + - advertisement-space-villain-9 + - advertisement-space-villain-10 + - advertisement-space-villain-11 + - advertisement-space-villain-12 + - advertisement-space-villain-13 + - advertisement-space-villain-14 + - advertisement-space-villain-15 + thankyous: + - thankyou-space-villain-1 + - thankyou-space-villain-2 + - thankyou-space-villain-3 + - thankyou-space-villain-4 + - thankyou-space-villain-5 + - thankyou-space-villain-6 + - thankyou-space-villain-7 + - thankyou-space-villain-8 + - thankyou-space-villain-9 + - thankyou-space-villain-10 + - thankyou-space-villain-11 + - thankyou-space-villain-12 diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml index 85f6dc6894..2970e9f854 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/arcades.yml @@ -10,29 +10,65 @@ priority: Low - type: ExtensionCableReceiver - type: PointLight - radius: 1.5 + radius: 1.8 energy: 1.6 color: "#3db83b" + - type: LitOnPowered - type: Sprite sprite: Structures/Machines/arcade.rsi layers: - map: ["computerLayerBody"] state: arcade - map: ["computerLayerScreen"] - state: invaders + state: screen_invaders + - map: ["enum.WiresVisualLayers.MaintenancePanel"] + state: panel + visible: false - type: Icon sprite: Structures/Machines/arcade.rsi state: arcade + - type: WiresPanel + - type: Wires + layoutId: Arcade + boardName: wires-board-name-arcade + - type: WiresVisuals + - type: TypingIndicator + proto: robot + - type: Speech + speechVerb: Robotic + speechSounds: Vending - type: Anchorable - type: Pullable - type: StaticPrice price: 300 + - type: SpamEmitSoundRequirePower + - type: SpamEmitSound + minInterval: 30 + maxInterval: 90 + sound: + collection: ArcadeNoise + params: + volume: -8 + maxDistance: 10 + variation: 0.05 - type: entity id: SpaceVillainArcade name: space villain arcade parent: ArcadeBase components: + - type: Sprite + sprite: Structures/Machines/arcade.rsi + layers: + - map: ["computerLayerBody"] + state: arcade + - map: ["computerLayerScreen"] + state: screen_spacevillain + - map: ["enum.WiresVisualLayers.MaintenancePanel"] + state: panel + visible: false + - type: PointLight + color: "#e3a136" - type: SpaceVillainArcade rewardAmount: 0 possibleRewards: @@ -108,6 +144,10 @@ type: WiresBoundUserInterface - type: Computer board: SpaceVillainArcadeComputerCircuitboard + - type: Advertise + pack: SpaceVillainAds + minWait: 60 # Arcades are noisy + maxWait: 240 - type: entity id: SpaceVillainArcadeFilled @@ -130,15 +170,14 @@ - map: ["computerLayerBody"] state: arcade - map: ["computerLayerScreen"] - state: blockgame + state: screen_blockgame + - map: ["enum.WiresVisualLayers.MaintenancePanel"] + state: panel + visible: false - type: BlockGameArcade - type: ActivatableUI key: enum.BlockGameUiKey.Key - type: ActivatableUIRequiresPower - - type: WiresPanel - - type: Wires - layoutId: Arcade - boardName: wires-board-name-arcade - type: UserInterface interfaces: - key: enum.BlockGameUiKey.Key @@ -147,3 +186,7 @@ type: WiresBoundUserInterface - type: Computer board: BlockGameArcadeComputerCircuitboard + - type: Advertise + pack: BlockGameAds + minWait: 60 # Arcades are noisy + maxWait: 240 diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml b/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml index 23c70d79cc..75c2ce3524 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml @@ -22,7 +22,6 @@ - type: SleepEmitSound snore: /Audio/Voice/Misc/silly_snore.ogg interval: 10 - chance: 1.0 - !type:AddImplantSpecial implants: [ SadTromboneImplant ] diff --git a/Resources/Prototypes/SoundCollections/arcade.yml b/Resources/Prototypes/SoundCollections/arcade.yml new file mode 100644 index 0000000000..40c8a0bc1e --- /dev/null +++ b/Resources/Prototypes/SoundCollections/arcade.yml @@ -0,0 +1,11 @@ +- type: soundCollection + id: ArcadeNoise + files: + - /Audio/Machines/Arcade/hahaha.ogg + - /Audio/Machines/Arcade/pew_pew.ogg + - /Audio/Machines/Arcade/sting_01.ogg + - /Audio/Machines/Arcade/sting_02.ogg + - /Audio/Machines/Arcade/sting_03.ogg + - /Audio/Machines/Arcade/sting_04.ogg + - /Audio/Machines/Arcade/sting_05.ogg + - /Audio/Machines/Arcade/sting_06.ogg diff --git a/Resources/Prototypes/Wires/layouts.yml b/Resources/Prototypes/Wires/layouts.yml index b30e68545d..8d6be674e8 100644 --- a/Resources/Prototypes/Wires/layouts.yml +++ b/Resources/Prototypes/Wires/layouts.yml @@ -87,6 +87,7 @@ id: Arcade wires: - !type:PowerWireAction + - !type:SpeechWireAction - !type:ArcadeOverflowWireAction - !type:ArcadePlayerInvincibleWireAction - !type:ArcadeEnemyInvincibleWireAction diff --git a/Resources/Textures/Structures/Machines/arcade.rsi/meta.json b/Resources/Textures/Structures/Machines/arcade.rsi/meta.json index 63820ec06a..38289e4b07 100644 --- a/Resources/Textures/Structures/Machines/arcade.rsi/meta.json +++ b/Resources/Textures/Structures/Machines/arcade.rsi/meta.json @@ -19,7 +19,11 @@ "directions": 4 }, { - "name": "invaders", + "name": "panel", + "directions": 4 + }, + { + "name": "screen_invaders", "directions": 4, "delays": [ [ @@ -42,7 +46,7 @@ ] }, { - "name": "blockgame", + "name": "screen_blockgame", "directions": 4, "delays": [ [ @@ -82,6 +86,48 @@ 4.8 ] ] + }, + { + "name": "screen_spacevillain", + "directions": 4, + "delays": [ + [ + 1.0, + 0.8, + 0.2, + 0.8, + 0.5, + 1.0, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.5, + 1.0, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.2, + 0.5, + 0.1, + 0.8, + 1.0 + ], + [ + 9.6 + ], + [ + 9.6 + ], + [ + 9.6 + ] + ] } ] } diff --git a/Resources/Textures/Structures/Machines/arcade.rsi/panel.png b/Resources/Textures/Structures/Machines/arcade.rsi/panel.png new file mode 100644 index 0000000000..fa65156579 Binary files /dev/null and b/Resources/Textures/Structures/Machines/arcade.rsi/panel.png differ diff --git a/Resources/Textures/Structures/Machines/arcade.rsi/blockgame.png b/Resources/Textures/Structures/Machines/arcade.rsi/screen_blockgame.png similarity index 100% rename from Resources/Textures/Structures/Machines/arcade.rsi/blockgame.png rename to Resources/Textures/Structures/Machines/arcade.rsi/screen_blockgame.png diff --git a/Resources/Textures/Structures/Machines/arcade.rsi/invaders.png b/Resources/Textures/Structures/Machines/arcade.rsi/screen_invaders.png similarity index 100% rename from Resources/Textures/Structures/Machines/arcade.rsi/invaders.png rename to Resources/Textures/Structures/Machines/arcade.rsi/screen_invaders.png diff --git a/Resources/Textures/Structures/Machines/arcade.rsi/screen_spacevillain.png b/Resources/Textures/Structures/Machines/arcade.rsi/screen_spacevillain.png new file mode 100644 index 0000000000..4935ac81b5 Binary files /dev/null and b/Resources/Textures/Structures/Machines/arcade.rsi/screen_spacevillain.png differ