diff --git a/Content.Server/Speech/Components/RandomBarkComponent.cs b/Content.Server/Speech/Components/RandomBarkComponent.cs
new file mode 100644
index 00000000000..7229428f538
--- /dev/null
+++ b/Content.Server/Speech/Components/RandomBarkComponent.cs
@@ -0,0 +1,63 @@
+namespace Content.Server.Speech.Components;
+
+///
+/// Sends a random message from a list with a provided min/max time.
+///
+[RegisterComponent]
+public sealed partial class RandomBarkComponent : Component
+{
+ ///
+ /// Should the message be sent to the chat log?
+ ///
+ [DataField]
+ public bool ChatLog = false;
+
+ ///
+ /// Minimum time an animal will go without speaking
+ ///
+ [DataField]
+ public int MinTime = 45;
+
+ ///
+ /// Maximum time an animal will go without speaking
+ ///
+ [DataField]
+ public int MaxTime = 350;
+
+ ///
+ /// Accumulator for counting time since the last bark
+ ///
+ [DataField]
+ public float BarkAccumulator = 8f;
+
+ ///
+ /// Multiplier applied to the random time. Good for changing the frequency without having to specify exact values
+ ///
+ [DataField]
+ public float BarkMultiplier = 1f;
+
+ ///
+ /// List of things to be said. Filled with garbage to be modified by an accent, but can be specified in the .yml
+ ///
+ [DataField]
+ public IReadOnlyList Barks = new[]
+ {
+ "Bark",
+ "Boof",
+ "Woofums",
+ "Rawrl",
+ "Eeeeeee",
+ "Barkums",
+ "Awooooooooooooooooooo awoo awoooo",
+ "Grrrrrrrrrrrrrrrrrr",
+ "Rarrwrarrwr",
+ "Goddamn I love gold fish crackers",
+ "Bork bork boof boof bork bork boof boof boof bork",
+ "Bark",
+ "Boof",
+ "Woofums",
+ "Rawrl",
+ "Eeeeeee",
+ "Barkums",
+ };
+}
diff --git a/Content.Server/Speech/Systems/RandomBarkSystem.cs b/Content.Server/Speech/Systems/RandomBarkSystem.cs
new file mode 100644
index 00000000000..4fc9dd420d2
--- /dev/null
+++ b/Content.Server/Speech/Systems/RandomBarkSystem.cs
@@ -0,0 +1,47 @@
+using Content.Server.Chat.Systems;
+using Content.Shared.Mind.Components;
+using Robust.Shared.Random;
+using Content.Server.Speech.Components;
+
+namespace Content.Server.Speech.Systems;
+
+public sealed class RandomBarkSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly ChatSystem _chat = default!;
+ [Dependency] private readonly EntityManager _entity = default!;
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnInit);
+ }
+
+
+ private void OnInit(EntityUid uid, RandomBarkComponent barker, ComponentInit args)
+ {
+ barker.BarkAccumulator = _random.NextFloat(barker.MinTime, barker.MaxTime) * barker.BarkMultiplier;
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var barker))
+ {
+ barker.BarkAccumulator -= frameTime;
+ if (barker.BarkAccumulator > 0)
+ continue;
+
+ barker.BarkAccumulator = _random.NextFloat(barker.MinTime, barker.MaxTime) * barker.BarkMultiplier;
+ if (_entity.TryGetComponent(uid, out var actComp) &&
+ actComp.HasMind)
+ continue;
+
+ _chat.TrySendInGameICMessage(uid, _random.Pick(barker.Barks), InGameICChatType.Speak, barker.ChatLog ? ChatTransmitRange.Normal : ChatTransmitRange.HideChat);
+ }
+ }
+}
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
index 378b3f8a9d8..93e19a829da 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
@@ -61,6 +61,7 @@
- type: Tag
tags:
- VimPilot
+ - type: RandomBark
- type: entity
name: bee
@@ -129,6 +130,13 @@
- ReagentId: GroundBee
Quantity: 5
- type: ZombieImmune
+ - type: RandomBark
+ barks:
+ - Bzzzzz
+ - Bzzz bzzz
+ - Bzzzzzzzzzzzz
+ - Bzz
+ barkMultiplier: 1.5
- type: entity
name: bee
@@ -236,6 +244,7 @@
- type: NpcFactionMember
factions:
- Passive
+ - type: RandomBark
- type: entity
parent: MobChicken
@@ -608,6 +617,8 @@
- type: NpcFactionMember
factions:
- Passive
+ - type: RandomBark
+ barkMultiplier: 0.7
- type: entity
name: white duck #Quack
@@ -787,6 +798,16 @@
- type: GuideHelp
guides:
- Chef
+ - type: RandomBark
+ barks:
+ - Mooooooo
+ - Moo
+ - Huff
+ - Mooooooooooo
+ - Moooooo
+ - Moooo
+ barkMultiplier: 3
+
- type: entity
name: crab
@@ -852,6 +873,12 @@
task: RuminantCompound
- type: Body
prototype: AnimalHemocyanin
+ - type: RandomBark
+ barks:
+ - click clack
+ - clack
+ - clickity clack
+ - clack clack
- type: entity
name: goat
@@ -1446,6 +1473,8 @@
makeSentient: true
name: ghost-role-information-kobold-name
description: ghost-role-information-kobold-description
+ - type: RandomBark
+ barkMultiplier: 0.65
- type: entity
name: guidebook monkey
@@ -1605,6 +1634,8 @@
- type: BadFood
- type: NonSpreaderZombie
- type: PreventSpiller
+ - type: RandomBark
+ barkMultiplier: 0.3
- type: entity
parent: MobMouse
@@ -1840,6 +1871,18 @@
- type: Tag
tags:
- VimPilot
+ - type: RandomBark
+ barkMultiplier: 1.3
+ barks:
+ - Croooaaaakkk
+ - Ribbit
+ - Ribbit
+ - Ribbit
+ - Crooaak
+ - Ribbit
+ - Ribbit
+ - Ribbit
+ - Bibbit
# Would be cool to have some functionality for the parrot to be able to sit on stuff
- type: entity
@@ -1953,6 +1996,10 @@
heatDamage:
types:
Heat : 0.2 #per second, scales with temperature & other constants
+ - type: RandomBark
+ barks:
+ - Wank
+ barkMultiplier: 0.6
- type: entity
name: grenade penguin
@@ -2068,6 +2115,14 @@
- type: Damageable
damageContainer: Biological
damageModifierSet: Scale
+ - type: RandomBark
+ barkMultiplier: 1.5
+ barks:
+ - Hsssssss
+ - Hss
+ - Hsssss
+ - Hisss
+ - Hshsss
# Code unique spider prototypes or combine them all into one spider and get a
# random sprite state when you spawn it.
@@ -2192,6 +2247,7 @@
groups:
Brute: -0.07
Burn: -0.07
+ - type: RandomBark
- type: entity
name: tarantula
@@ -2536,6 +2592,7 @@
- type: Tag
tags:
- VimPilot
+ - type: RandomBark
- type: entity
name: corrupted corgi
@@ -2692,6 +2749,7 @@
- type: Tag
tags:
- VimPilot
+ - type: RandomBark
- type: entity
name: calico cat
@@ -2880,6 +2938,10 @@
- type: Tag
tags:
- VimPilot
+ - type: RandomBark
+ barkMultiplier: 10
+ barks:
+ - Sloth
- type: entity
name: ferret
@@ -3076,6 +3138,8 @@
- type: MobPrice
price: 60
- type: NonSpreaderZombie
+ - type: RandomBark
+ barkMultiplier: 0.45
- type: entity
name: pig
@@ -3236,3 +3300,4 @@
components:
- type: ReplacementAccent
accent: nymph
+ - type: RandomBark
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
index 9981bb8bd92..274765a1931 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
@@ -307,6 +307,8 @@
- VimPilot
- type: StealTarget
stealGroup: AnimalMcGriff
+ - type: RandomBark
+ barkMultiplier: 1.3
- type: entity
name: Paperwork
@@ -406,6 +408,8 @@
- VimPilot
- type: StealTarget
stealGroup: AnimalWalter
+ - type: RandomBark
+ barkMultiplier: 1.1
- type: entity
name: Morty
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
index 12ea40b1e3c..8e84f46a693 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
@@ -104,3 +104,4 @@
- type: MobPrice
price: 150
- type: FloatingVisuals
+ - type: Speech