Various Entities make sounds when speaking (#7980)

* Speech Sounds from Goonstation

* Added some speech sound prototypes for humans, mice, and vending machines. More to come later?

* Custom synthesized sound for a vending machine ad

* Gave mice and vending machines Speech Components on their base prototypes to make sounds

* Humans now talk using the 'Alto' voice. In the future this can be changed in customization screen

* New Prototype 'SpeechSounds' with three soundspecifiers for saying sound, asking sound, exclaiming sound.

* SharedSpeechComponent modified from being useless to being responsible for making speech noises.

* Initial creation of SpeechNoiseSystem for making Sounds when certain entities speak.

* whitespace fix

* License fix

* Remove leftover using from debugging

* Added a cooldown editable in yaml

* SharedSpeechComponent has the proper cooldown now. oops
This commit is contained in:
hubismal
2022-05-08 08:23:08 -05:00
committed by GitHub
parent 41a74b8c2a
commit 304e9b824e
21 changed files with 219 additions and 3 deletions

View File

@@ -0,0 +1,80 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Audio;
using Content.Server.Chat;
using Content.Shared.Speech;
using Content.Shared.Sound;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System;
namespace Content.Server.Speech
{
public sealed class SpeechSoundSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SharedSpeechComponent, EntitySpokeEvent>(OnEntitySpoke);
SubscribeLocalEvent<SharedSpeechComponent, ComponentStartup>(OnStartup);
}
private void OnStartup(EntityUid uid, SharedSpeechComponent component, ComponentStartup args)
{
//Cache prototype on component startup.
if (_proto.TryIndex(component.SpeechSoundsId, out SpeechSoundsPrototype? speechsnds))
{
if (speechsnds != null)
{
component.SpeechSoundsCache = speechsnds;
}
}
}
private void OnEntitySpoke(EntityUid uid, SharedSpeechComponent component, EntitySpokeEvent args)
{
if (!component.PlaySpeechSound) return;
var cooldown = TimeSpan.FromSeconds(component.SoundCooldownTime);
//Ensure more than the cooldown time has passed since last speaking
if ((_gameTiming.CurTime - component.LastTimeSoundPlayed) < cooldown) return;
//Play speech sound
if (component.SpeechSoundsCache != null)
{
//Re-Index sounds prototype if cached proto ID is outdated, allows VV and changing the voice.
if (component.SpeechSoundsCache.ID != component.SpeechSoundsId)
{
if (_proto.TryIndex(component.SpeechSoundsId, out SpeechSoundsPrototype? speechsnds))
{
if (speechsnds != null)
{
component.SpeechSoundsCache = speechsnds;
}
}
}
var contextSound = component.SpeechSoundsCache.SaySound;
//Different sounds for ask/exclaim based on last character
switch (args.Message[args.Message.Length-1])
{
case '?':
contextSound = component.SpeechSoundsCache.AskSound;
break;
case '!':
contextSound = component.SpeechSoundsCache.ExclaimSound;
break;
}
component.LastTimeSoundPlayed = _gameTiming.CurTime;
SoundSystem.Play(Filter.Pvs(uid), contextSound.GetSound(), uid, component.AudioParams);
}
}
}
}

View File

@@ -1,10 +1,18 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Audio;
using Content.Shared.Sound;
using Content.Shared.Speech;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System;
namespace Content.Shared.Speech
{
/// <summary>
/// Component required for entities to be able to speak.
/// Component required for entities to be able to speak. (TODO: Entities can speak fine without this, this only forbids them speak if they have it and enabled is false.)
/// Contains the option to let entities make noise when speaking, datafields for the sounds in question, and relevant AudioParams.
/// </summary>
[RegisterComponent]
public sealed class SharedSpeechComponent : Component
@@ -12,6 +20,29 @@ namespace Content.Shared.Speech
[DataField("enabled")]
private bool _enabled = true;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("playSpeechSound")]
public bool PlaySpeechSound = false;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("speechSoundsId", customTypeSerializer:typeof(PrototypeIdSerializer<SpeechSoundsPrototype>))]
public string SpeechSoundsId { get; set; } = "Alto";
[DataField("audioParams")]
public AudioParams AudioParams = AudioParams.Default.WithVolume(5f);
[ViewVariables(VVAccess.ReadWrite)]
[DataField("soundCooldownTime")]
public float SoundCooldownTime { get; set; } = 0.5f;
public TimeSpan LastTimeSoundPlayed = TimeSpan.Zero;
//Don't use this.
//Cache for SpeechSoundsPrototype to avoid Indexing every single time someone talks.
public SpeechSoundsPrototype? SpeechSoundsCache = null;
public bool Enabled
{
get => _enabled;

View File

@@ -0,0 +1,27 @@
using System.Collections.Generic;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using Robust.Shared.Audio;
using Content.Shared.Sound;
namespace Content.Shared.Speech
{
[Prototype("speechSounds")]
public sealed class SpeechSoundsPrototype : IPrototype
{
[ViewVariables]
[IdDataFieldAttribute]
public string ID { get; } = default!;
[DataField("saySound")]
public SoundSpecifier SaySound { get; set; } = new SoundPathSpecifier("/Audio/Voice/Talk/speak_2.ogg");
[DataField("askSound")]
public SoundSpecifier AskSound { get; set; } = new SoundPathSpecifier("/Audio/Voice/Talk/speak_2_ask.ogg");
[DataField("exclaimSound")]
public SoundSpecifier ExclaimSound { get; set; } = new SoundPathSpecifier("/Audio/Voice/Talk/speak_2_exclaim.ogg");
}
}

Binary file not shown.

View File

@@ -0,0 +1,15 @@
speak_1_ask.ogg
speak_1_exclaim.ogg
speak_1.ogg
speak_2_ask.ogg
speak_2_exclaim.ogg
speak_2.ogg
speak_3_ask.ogg
speak_3_exclaim.ogg
speak_3.ogg
speak_4_ask.ogg
speak_4_exclaim.ogg
speak_4.ogg
all taken from
https://github.com/goonstation/goonstation/tree/master/sound/misc/talk
licensed under CC BY-NC-SA 3.0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -17,6 +17,8 @@
state: bat
sprite: Mobs/Animals/bat.rsi
- type: Physics
- type: Speech
speechSoundsId: Squeak
- type: Fixtures
fixtures:
- shape:
@@ -663,6 +665,9 @@
makeSentient: true
name: mouse
description: A hungry and mischievous mouse.
- type: Speech
playSpeechSound: true
speechSoundsId: Squeak
- type: Sprite
drawdepth: FloorObjects
layers:

View File

@@ -309,6 +309,7 @@
# - type: Recyclable Turns out turning off recycler safeties without considering the instagib is a bad idea
# safe: false
- type: Speech
playSpeechSound: true
- type: Vocal
- type: Emoting
- type: Grammar

View File

@@ -52,6 +52,9 @@
BoardName: "Vending Machine"
LayoutId: Vending
- type: Anchorable
- type: Speech
playSpeechSound: true
speechSoundsId: Vending
- type: DoAfter
- type: Electrified
enabled: false

View File

@@ -0,0 +1,54 @@
- type: speechSounds
id: Bass
saySound:
path: /Audio/Voice/Talk/speak_4.ogg
askSound:
path: /Audio/Voice/Talk/speak_4_ask.ogg
exclaimSound:
path: /Audio/Voice/Talk/speak_4_exclaim.ogg
- type: speechSounds
id: Baritone
saySound:
path: /Audio/Voice/Talk/speak_1.ogg
askSound:
path: /Audio/Voice/Talk/speak_1_ask.ogg
exclaimSound:
path: /Audio/Voice/Talk/speak_1_exclaim.ogg
- type: speechSounds
id: Tenor
saySound:
path: /Audio/Voice/Talk/speak_3.ogg
askSound:
path: /Audio/Voice/Talk/speak_3_ask.ogg
exclaimSound:
path: /Audio/Voice/Talk/speak_3_exclaim.ogg
- type: speechSounds
id: Alto
saySound:
path: /Audio/Voice/Talk/speak_2.ogg
askSound:
path: /Audio/Voice/Talk/speak_2_ask.ogg
exclaimSound:
path: /Audio/Voice/Talk/speak_2_exclaim.ogg
- type: speechSounds
id: Squeak
saySound:
path: /Audio/Animals/mouse_squeak.ogg
askSound:
path: /Audio/Animals/mouse_squeak.ogg
exclaimSound:
path: /Audio/Animals/mouse_squeak.ogg
- type: speechSounds
id: Vending
saySound:
path: /Audio/Machines/vending_jingle.ogg
askSound:
path: /Audio/Machines/vending_jingle.ogg
exclaimSound:
path: /Audio/Machines/vending_jingle.ogg