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<T> * 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.
This commit is contained in:
@@ -19,4 +19,9 @@ public sealed partial class BlockGameArcadeComponent : Component
|
|||||||
/// The players currently viewing (but not playing) the active session of NT-BG.
|
/// The players currently viewing (but not playing) the active session of NT-BG.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly List<ICommonSession> Spectators = new();
|
public readonly List<ICommonSession> Spectators = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the game machine should thank (or otherwise talk to) the player when they leave
|
||||||
|
/// </summary>
|
||||||
|
public bool ShouldSayThankYou;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
|
using Content.Server.Advertise;
|
||||||
using Content.Shared.Arcade;
|
using Content.Shared.Arcade;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
@@ -9,6 +10,7 @@ namespace Content.Server.Arcade.BlockGame;
|
|||||||
public sealed class BlockGameArcadeSystem : EntitySystem
|
public sealed class BlockGameArcadeSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
|
[Dependency] private readonly AdvertiseSystem _advertise = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -89,7 +91,15 @@ public sealed class BlockGameArcadeSystem : EntitySystem
|
|||||||
UpdatePlayerStatus(uid, component.Player, blockGame: component);
|
UpdatePlayerStatus(uid, component.Player, blockGame: component);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// Everybody's gone
|
||||||
component.Player = null;
|
component.Player = null;
|
||||||
|
if (component.ShouldSayThankYou && TryComp<AdvertiseComponent>(uid, out var advertise))
|
||||||
|
{
|
||||||
|
_advertise.SayThankYou(uid, advertise);
|
||||||
|
component.ShouldSayThankYou = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UpdatePlayerStatus(uid, temp, blockGame: component);
|
UpdatePlayerStatus(uid, temp, blockGame: component);
|
||||||
}
|
}
|
||||||
@@ -103,6 +113,7 @@ public sealed class BlockGameArcadeSystem : EntitySystem
|
|||||||
_uiSystem.CloseAll(bui);
|
_uiSystem.CloseAll(bui);
|
||||||
component.Player = null;
|
component.Player = null;
|
||||||
component.Spectators.Clear();
|
component.Spectators.Clear();
|
||||||
|
component.ShouldSayThankYou = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPlayerAction(EntityUid uid, BlockGameArcadeComponent component, BlockGameMessages.BlockGamePlayerActionMessage msg)
|
private void OnPlayerAction(EntityUid uid, BlockGameArcadeComponent component, BlockGameMessages.BlockGamePlayerActionMessage msg)
|
||||||
@@ -122,6 +133,8 @@ public sealed class BlockGameArcadeSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component.ShouldSayThankYou = true;
|
||||||
|
|
||||||
component.Game.ProcessInput(msg.PlayerAction);
|
component.Game.ProcessInput(msg.PlayerAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,4 +110,9 @@ public sealed partial class SpaceVillainArcadeComponent : SharedSpaceVillainArca
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public int RewardAmount = 0;
|
public int RewardAmount = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the game machine should thank (or otherwise talk to) the player when they leave
|
||||||
|
/// </summary>
|
||||||
|
public bool ShouldSayThankYou;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
|
using Content.Server.Advertise;
|
||||||
using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent;
|
using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -13,6 +14,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
|
|||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
|
[Dependency] private readonly AdvertiseSystem _advertise = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -22,6 +24,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<SpaceVillainArcadeComponent, AfterActivatableUIOpenEvent>(OnAfterUIOpenSV);
|
SubscribeLocalEvent<SpaceVillainArcadeComponent, AfterActivatableUIOpenEvent>(OnAfterUIOpenSV);
|
||||||
SubscribeLocalEvent<SpaceVillainArcadeComponent, SpaceVillainArcadePlayerActionMessage>(OnSVPlayerAction);
|
SubscribeLocalEvent<SpaceVillainArcadeComponent, SpaceVillainArcadePlayerActionMessage>(OnSVPlayerAction);
|
||||||
SubscribeLocalEvent<SpaceVillainArcadeComponent, PowerChangedEvent>(OnSVillainPower);
|
SubscribeLocalEvent<SpaceVillainArcadeComponent, PowerChangedEvent>(OnSVillainPower);
|
||||||
|
SubscribeLocalEvent<SpaceVillainArcadeComponent, BoundUIClosedEvent>(OnBoundUIClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -79,6 +82,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
|
|||||||
case PlayerAction.Heal:
|
case PlayerAction.Heal:
|
||||||
case PlayerAction.Recharge:
|
case PlayerAction.Recharge:
|
||||||
component.Game.ExecutePlayerAction(uid, msg.PlayerAction, component);
|
component.Game.ExecutePlayerAction(uid, msg.PlayerAction, component);
|
||||||
|
component.ShouldSayThankYou = true; // Any sort of gameplay action counts
|
||||||
break;
|
break;
|
||||||
case PlayerAction.NewGame:
|
case PlayerAction.NewGame:
|
||||||
_audioSystem.PlayPvs(component.NewGameSound, uid, AudioParams.Default.WithVolume(-4f));
|
_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))
|
if (_uiSystem.TryGetUi(uid, SpaceVillainArcadeUiKey.Key, out var bui))
|
||||||
_uiSystem.CloseAll(bui);
|
_uiSystem.CloseAll(bui);
|
||||||
|
|
||||||
|
component.ShouldSayThankYou = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBoundUIClosed(Entity<SpaceVillainArcadeComponent> ent, ref BoundUIClosedEvent args)
|
||||||
|
{
|
||||||
|
if (args.UiKey is not SpaceVillainArcadeUiKey || (SpaceVillainArcadeUiKey) args.UiKey != SpaceVillainArcadeUiKey.Key)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.ShouldSayThankYou && TryComp<AdvertiseComponent>(ent.Owner, out var advertise))
|
||||||
|
{
|
||||||
|
_advertise.SayThankYou(ent.Owner, advertise);
|
||||||
|
ent.Comp.ShouldSayThankYou = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Server.Popups;
|
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.Actions;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Bed.Sleep;
|
using Content.Shared.Bed.Sleep;
|
||||||
@@ -30,6 +31,7 @@ namespace Content.Server.Bed.Sleep
|
|||||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||||
|
[Dependency] private readonly EmitSoundSystem _emitSound = default!;
|
||||||
|
|
||||||
[ValidatePrototypeId<EntityPrototype>] public const string SleepActionId = "ActionSleep";
|
[ValidatePrototypeId<EntityPrototype>] public const string SleepActionId = "ActionSleep";
|
||||||
|
|
||||||
@@ -71,8 +73,8 @@ namespace Content.Server.Bed.Sleep
|
|||||||
{
|
{
|
||||||
emitSound.Sound = sleepSound.Snore;
|
emitSound.Sound = sleepSound.Snore;
|
||||||
}
|
}
|
||||||
emitSound.PlayChance = sleepSound.Chance;
|
emitSound.MinInterval = sleepSound.Interval;
|
||||||
emitSound.RollInterval = sleepSound.Interval;
|
emitSound.MaxInterval = sleepSound.MaxInterval;
|
||||||
emitSound.PopUp = sleepSound.PopUp;
|
emitSound.PopUp = sleepSound.PopUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +130,7 @@ namespace Content.Server.Bed.Sleep
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TryComp<SpamEmitSoundComponent>(uid, out var spam))
|
if (TryComp<SpamEmitSoundComponent>(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<AlternativeVerb> args)
|
private void AddWakeVerb(EntityUid uid, SleepingComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
using Content.Shared.Sound.Components;
|
|
||||||
|
|
||||||
namespace Content.Server.Sound.Components
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Rolls to play a sound every few seconds.
|
|
||||||
/// </summary>
|
|
||||||
[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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,17 @@ using Content.Server.Explosion.EntitySystems;
|
|||||||
using Content.Server.Sound.Components;
|
using Content.Server.Sound.Components;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.Sound;
|
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;
|
namespace Content.Server.Sound;
|
||||||
|
|
||||||
public sealed class EmitSoundSystem : SharedEmitSoundSystem
|
public sealed class EmitSoundSystem : SharedEmitSoundSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
@@ -18,18 +23,13 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem
|
|||||||
if (!soundSpammer.Enabled)
|
if (!soundSpammer.Enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
soundSpammer.Accumulator += frameTime;
|
if (_timing.CurTime >= soundSpammer.NextSound)
|
||||||
if (soundSpammer.Accumulator < soundSpammer.RollInterval)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
soundSpammer.Accumulator -= soundSpammer.RollInterval;
|
|
||||||
|
|
||||||
if (Random.Prob(soundSpammer.PlayChance))
|
|
||||||
{
|
{
|
||||||
if (soundSpammer.PopUp != null)
|
if (soundSpammer.PopUp != null)
|
||||||
Popup.PopupEntity(Loc.GetString(soundSpammer.PopUp), uid);
|
Popup.PopupEntity(Loc.GetString(soundSpammer.PopUp), uid);
|
||||||
TryEmitSound(uid, soundSpammer, predict: false);
|
TryEmitSound(uid, soundSpammer, predict: false);
|
||||||
|
|
||||||
|
SpamEmitSoundReset((uid, soundSpammer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,8 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<EmitSoundOnTriggerComponent, TriggerEvent>(HandleEmitSoundOnTrigger);
|
SubscribeLocalEvent<EmitSoundOnTriggerComponent, TriggerEvent>(HandleEmitSoundOnTrigger);
|
||||||
SubscribeLocalEvent<EmitSoundOnUIOpenComponent, AfterActivatableUIOpenEvent>(HandleEmitSoundOnUIOpen);
|
SubscribeLocalEvent<EmitSoundOnUIOpenComponent, AfterActivatableUIOpenEvent>(HandleEmitSoundOnUIOpen);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SpamEmitSoundComponent, MapInitEvent>(HandleSpamEmitSoundMapInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleEmitSoundOnUIOpen(EntityUid uid, EmitSoundOnUIOpenComponent component, AfterActivatableUIOpenEvent args)
|
private void HandleEmitSoundOnUIOpen(EntityUid uid, EmitSoundOnUIOpenComponent component, AfterActivatableUIOpenEvent args)
|
||||||
@@ -52,4 +54,39 @@ public sealed class EmitSoundSystem : SharedEmitSoundSystem
|
|||||||
TryEmitSound(uid, component, args.User, false);
|
TryEmitSound(uid, component, args.User, false);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleSpamEmitSoundMapInit(Entity<SpamEmitSoundComponent> 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<SpamEmitSoundComponent> 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<SpamEmitSoundComponent?> 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
Content.Server/Sound/SpamEmitSoundRequirePowerSystem.cs
Normal file
33
Content.Server/Sound/SpamEmitSoundRequirePowerSystem.cs
Normal file
@@ -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<SpamEmitSoundRequirePowerComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
|
SubscribeLocalEvent<SpamEmitSoundRequirePowerComponent, PowerNetBatterySupplyEvent>(OnPowerSupply);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPowerChanged(Entity<SpamEmitSoundRequirePowerComponent> entity, ref PowerChangedEvent args)
|
||||||
|
{
|
||||||
|
if (TryComp<SpamEmitSoundComponent>(entity.Owner, out var comp))
|
||||||
|
{
|
||||||
|
EmitSound.SetEnabled((entity, comp), args.Powered);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPowerSupply(Entity<SpamEmitSoundRequirePowerComponent> entity, ref PowerNetBatterySupplyEvent args)
|
||||||
|
{
|
||||||
|
if (TryComp<SpamEmitSoundComponent>(entity.Owner, out var comp))
|
||||||
|
{
|
||||||
|
EmitSound.SetEnabled((entity, comp), args.Supply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,16 +12,16 @@ public sealed partial class SleepEmitSoundComponent : Component
|
|||||||
public SoundSpecifier Snore = new SoundCollectionSpecifier("Snores", AudioParams.Default.WithVariation(0.2f));
|
public SoundSpecifier Snore = new SoundCollectionSpecifier("Snores", AudioParams.Default.WithVariation(0.2f));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interval between snore attempts in seconds
|
/// Minimum interval between snore attempts in seconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float Interval = 5f;
|
public TimeSpan Interval = TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Chance for snore attempt to succeed
|
/// Maximum interval between snore attempts in seconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float Chance = 0.33f;
|
public TimeSpan MaxInterval = TimeSpan.FromSeconds(15);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Popup for snore (e.g. Zzz...)
|
/// Popup for snore (e.g. Zzz...)
|
||||||
|
|||||||
44
Content.Shared/Sound/Components/SpamEmitSoundComponent.cs
Normal file
44
Content.Shared/Sound/Components/SpamEmitSoundComponent.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Sound.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repeatedly plays a sound with a randomized delay.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent]
|
||||||
|
[AutoGenerateComponentState, AutoGenerateComponentPause]
|
||||||
|
public sealed partial class SpamEmitSoundComponent : BaseEmitSoundComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The time at which the next sound will play.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoPausedField, AutoNetworkedField]
|
||||||
|
public TimeSpan NextSound;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum time in seconds between playing the sound.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public TimeSpan MinInterval = TimeSpan.FromSeconds(2);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum time in seconds between playing the sound.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public TimeSpan MaxInterval = TimeSpan.FromSeconds(2);
|
||||||
|
|
||||||
|
// Always Pvs.
|
||||||
|
/// <summary>
|
||||||
|
/// Content of a popup message to display whenever the sound plays.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? PopUp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the timer is currently running and sounds are being played.
|
||||||
|
/// Do not set this directly, use <see cref="EmitSoundSystem.SetEnabled"/>
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
[Access(typeof(SharedEmitSoundSystem))]
|
||||||
|
public bool Enabled = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Content.Shared.Sound.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables an SpamEmitSound component depending
|
||||||
|
/// on the powered state of the entity.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class SpamEmitSoundRequirePowerComponent : Component
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ namespace Content.Shared.Sound;
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public abstract class SharedEmitSoundSystem : EntitySystem
|
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 INetManager _netMan = default!;
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
|
[Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
|
||||||
[Dependency] protected readonly IRobustRandom Random = default!;
|
[Dependency] protected readonly IRobustRandom Random = default!;
|
||||||
@@ -124,7 +124,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
|||||||
!args.OtherFixture.Hard ||
|
!args.OtherFixture.Hard ||
|
||||||
!TryComp<PhysicsComponent>(uid, out var physics) ||
|
!TryComp<PhysicsComponent>(uid, out var physics) ||
|
||||||
physics.LinearVelocity.Length() < component.MinimumVelocity ||
|
physics.LinearVelocity.Length() < component.MinimumVelocity ||
|
||||||
_timing.CurTime < component.NextSound ||
|
Timing.CurTime < component.NextSound ||
|
||||||
MetaData(uid).EntityPaused)
|
MetaData(uid).EntityPaused)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -136,7 +136,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
|||||||
|
|
||||||
var fraction = MathF.Min(1f, (physics.LinearVelocity.Length() - component.MinimumVelocity) / MaxVolumeVelocity);
|
var fraction = MathF.Min(1f, (physics.LinearVelocity.Length() - component.MinimumVelocity) / MaxVolumeVelocity);
|
||||||
var volume = MinVolume + (MaxVolume - MinVolume) * fraction;
|
var volume = MinVolume + (MaxVolume - MinVolume) * fraction;
|
||||||
component.NextSound = _timing.CurTime + EmitSoundOnCollideComponent.CollideCooldown;
|
component.NextSound = Timing.CurTime + EmitSoundOnCollideComponent.CollideCooldown;
|
||||||
var sound = component.Sound;
|
var sound = component.Sound;
|
||||||
|
|
||||||
if (_netMan.IsServer && sound != null)
|
if (_netMan.IsServer && sound != null)
|
||||||
@@ -144,4 +144,8 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
|||||||
_audioSystem.PlayPvs(_audioSystem.GetSound(sound), uid, AudioParams.Default.WithVolume(volume));
|
_audioSystem.PlayPvs(_audioSystem.GetSound(sound), uid, AudioParams.Default.WithVolume(volume));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void SetEnabled(Entity<SpamEmitSoundComponent?> entity, bool enabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Content.Shared.Sound;
|
||||||
|
|
||||||
|
public abstract partial class SharedSpamEmitSoundRequirePowerSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] protected readonly SharedEmitSoundSystem EmitSound = default!;
|
||||||
|
}
|
||||||
4
Resources/Audio/Machines/Arcade/attributions.yml
Normal file
4
Resources/Audio/Machines/Arcade/attributions.yml
Normal file
@@ -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"
|
||||||
BIN
Resources/Audio/Machines/Arcade/hahaha.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/hahaha.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/pew_pew.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/pew_pew.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_01.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_01.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_02.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_02.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_03.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_03.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_04.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_04.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_05.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_05.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Machines/Arcade/sting_06.ogg
Normal file
BIN
Resources/Audio/Machines/Arcade/sting_06.ogg
Normal file
Binary file not shown.
26
Resources/Locale/en-US/advertisements/arcade/blockgame.ftl
Normal file
26
Resources/Locale/en-US/advertisements/arcade/blockgame.ftl
Normal file
@@ -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!
|
||||||
@@ -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!
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -10,29 +10,65 @@
|
|||||||
priority: Low
|
priority: Low
|
||||||
- type: ExtensionCableReceiver
|
- type: ExtensionCableReceiver
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 1.5
|
radius: 1.8
|
||||||
energy: 1.6
|
energy: 1.6
|
||||||
color: "#3db83b"
|
color: "#3db83b"
|
||||||
|
- type: LitOnPowered
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Machines/arcade.rsi
|
sprite: Structures/Machines/arcade.rsi
|
||||||
layers:
|
layers:
|
||||||
- map: ["computerLayerBody"]
|
- map: ["computerLayerBody"]
|
||||||
state: arcade
|
state: arcade
|
||||||
- map: ["computerLayerScreen"]
|
- map: ["computerLayerScreen"]
|
||||||
state: invaders
|
state: screen_invaders
|
||||||
|
- map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
state: panel
|
||||||
|
visible: false
|
||||||
- type: Icon
|
- type: Icon
|
||||||
sprite: Structures/Machines/arcade.rsi
|
sprite: Structures/Machines/arcade.rsi
|
||||||
state: arcade
|
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: Anchorable
|
||||||
- type: Pullable
|
- type: Pullable
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 300
|
price: 300
|
||||||
|
- type: SpamEmitSoundRequirePower
|
||||||
|
- type: SpamEmitSound
|
||||||
|
minInterval: 30
|
||||||
|
maxInterval: 90
|
||||||
|
sound:
|
||||||
|
collection: ArcadeNoise
|
||||||
|
params:
|
||||||
|
volume: -8
|
||||||
|
maxDistance: 10
|
||||||
|
variation: 0.05
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: SpaceVillainArcade
|
id: SpaceVillainArcade
|
||||||
name: space villain arcade
|
name: space villain arcade
|
||||||
parent: ArcadeBase
|
parent: ArcadeBase
|
||||||
components:
|
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
|
- type: SpaceVillainArcade
|
||||||
rewardAmount: 0
|
rewardAmount: 0
|
||||||
possibleRewards:
|
possibleRewards:
|
||||||
@@ -108,6 +144,10 @@
|
|||||||
type: WiresBoundUserInterface
|
type: WiresBoundUserInterface
|
||||||
- type: Computer
|
- type: Computer
|
||||||
board: SpaceVillainArcadeComputerCircuitboard
|
board: SpaceVillainArcadeComputerCircuitboard
|
||||||
|
- type: Advertise
|
||||||
|
pack: SpaceVillainAds
|
||||||
|
minWait: 60 # Arcades are noisy
|
||||||
|
maxWait: 240
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: SpaceVillainArcadeFilled
|
id: SpaceVillainArcadeFilled
|
||||||
@@ -130,15 +170,14 @@
|
|||||||
- map: ["computerLayerBody"]
|
- map: ["computerLayerBody"]
|
||||||
state: arcade
|
state: arcade
|
||||||
- map: ["computerLayerScreen"]
|
- map: ["computerLayerScreen"]
|
||||||
state: blockgame
|
state: screen_blockgame
|
||||||
|
- map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||||
|
state: panel
|
||||||
|
visible: false
|
||||||
- type: BlockGameArcade
|
- type: BlockGameArcade
|
||||||
- type: ActivatableUI
|
- type: ActivatableUI
|
||||||
key: enum.BlockGameUiKey.Key
|
key: enum.BlockGameUiKey.Key
|
||||||
- type: ActivatableUIRequiresPower
|
- type: ActivatableUIRequiresPower
|
||||||
- type: WiresPanel
|
|
||||||
- type: Wires
|
|
||||||
layoutId: Arcade
|
|
||||||
boardName: wires-board-name-arcade
|
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.BlockGameUiKey.Key
|
- key: enum.BlockGameUiKey.Key
|
||||||
@@ -147,3 +186,7 @@
|
|||||||
type: WiresBoundUserInterface
|
type: WiresBoundUserInterface
|
||||||
- type: Computer
|
- type: Computer
|
||||||
board: BlockGameArcadeComputerCircuitboard
|
board: BlockGameArcadeComputerCircuitboard
|
||||||
|
- type: Advertise
|
||||||
|
pack: BlockGameAds
|
||||||
|
minWait: 60 # Arcades are noisy
|
||||||
|
maxWait: 240
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
- type: SleepEmitSound
|
- type: SleepEmitSound
|
||||||
snore: /Audio/Voice/Misc/silly_snore.ogg
|
snore: /Audio/Voice/Misc/silly_snore.ogg
|
||||||
interval: 10
|
interval: 10
|
||||||
chance: 1.0
|
|
||||||
- !type:AddImplantSpecial
|
- !type:AddImplantSpecial
|
||||||
implants: [ SadTromboneImplant ]
|
implants: [ SadTromboneImplant ]
|
||||||
|
|
||||||
|
|||||||
11
Resources/Prototypes/SoundCollections/arcade.yml
Normal file
11
Resources/Prototypes/SoundCollections/arcade.yml
Normal file
@@ -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
|
||||||
@@ -87,6 +87,7 @@
|
|||||||
id: Arcade
|
id: Arcade
|
||||||
wires:
|
wires:
|
||||||
- !type:PowerWireAction
|
- !type:PowerWireAction
|
||||||
|
- !type:SpeechWireAction
|
||||||
- !type:ArcadeOverflowWireAction
|
- !type:ArcadeOverflowWireAction
|
||||||
- !type:ArcadePlayerInvincibleWireAction
|
- !type:ArcadePlayerInvincibleWireAction
|
||||||
- !type:ArcadeEnemyInvincibleWireAction
|
- !type:ArcadeEnemyInvincibleWireAction
|
||||||
|
|||||||
@@ -19,7 +19,11 @@
|
|||||||
"directions": 4
|
"directions": 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "invaders",
|
"name": "panel",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "screen_invaders",
|
||||||
"directions": 4,
|
"directions": 4,
|
||||||
"delays": [
|
"delays": [
|
||||||
[
|
[
|
||||||
@@ -42,7 +46,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "blockgame",
|
"name": "screen_blockgame",
|
||||||
"directions": 4,
|
"directions": 4,
|
||||||
"delays": [
|
"delays": [
|
||||||
[
|
[
|
||||||
@@ -82,6 +86,48 @@
|
|||||||
4.8
|
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
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Resources/Textures/Structures/Machines/arcade.rsi/panel.png
Normal file
BIN
Resources/Textures/Structures/Machines/arcade.rsi/panel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 930 B |
Reference in New Issue
Block a user