Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Commit

Permalink
Caveman accent (new-frontiers-14#1951)
Browse files Browse the repository at this point in the history
* space-wizards/space-station-14#29760

* Caveman accent, first pass

* LINQ cleanup

* fixed the license thingi forgor to do it before

* Update caveman_club.yml

* Caveman ooga club

* SmiteBaseline

* Update weapons.yml

* Caveman accent improvements

* Caveman smite, foam club

---------

Co-authored-by: Whatstone <[email protected]>
Co-authored-by: Thinbug <[email protected]>
  • Loading branch information
3 people authored Oct 13, 2024
1 parent 975002d commit 1ac9b2b
Show file tree
Hide file tree
Showing 18 changed files with 972 additions and 0 deletions.
65 changes: 65 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
using Robust.Shared.Random;
using Robust.Shared.Utility;
using Timer = Robust.Shared.Timing.Timer;
using Robust.Shared.Audio.Systems; // Frontier
using Robust.Shared.Audio; // Frontier
using Content.Server._NF.Speech.Components; // Frontier
using Content.Shared.Damage.Prototypes; // Frontier
using Content.Shared.Bed.Sleep; // Frontier

namespace Content.Server.Administration.Systems;

Expand Down Expand Up @@ -79,6 +84,9 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SuperBonkSystem _superBonkSystem = default!;
[Dependency] private readonly SlipperySystem _slipperySystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; // Frontier
[Dependency] private readonly DamageableSystem _damageable = default!; // Frontier
[Dependency] private readonly SleepingSystem _sleep = default!; // Frontier

// All smite verbs have names so invokeverb works.
private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
Expand Down Expand Up @@ -849,5 +857,62 @@ private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
Message = Loc.GetString("admin-smite-super-slip-description")
};
args.Verbs.Add(superslip);

// Frontier
Verb caveman = new()
{
Text = "admin-smite-caveman-name",
Category = VerbCategory.Smite,
Icon = new SpriteSpecifier.Rsi(new("_NF/Objects/Weapons/Melee/caveman_club.rsi"), "icon"),
Act = () =>
{
// Remove whatever they're holding, summon & pickup the funny club, destroy on failure
var hand = _handsSystem.GetActiveHand(args.Target);
if (hand != null)
{
_handsSystem.TryDrop(args.Target, hand);
var club = EntityManager.SpawnNextToOrDrop("CavemanClubCursed", args.Target);
if (club.Valid &&
!_handsSystem.TryPickupAnyHand(args.Target, club, false))
{
QueueDel(club);
}
}

if (_prototypeManager.TryIndex<DamageTypePrototype>("Blunt", out var bluntProto))
{
var bluntDamage = new DamageSpecifier(bluntProto, 10);
_damageable.TryChangeDamage(args.Target, bluntDamage, true);
}

// Make them slip and fall.
var hadSlipComponent = EnsureComp(args.Target, out SlipperyComponent slipComponent);
if (!hadSlipComponent)
{
slipComponent.SuperSlippery = true;
slipComponent.ParalyzeTime = 10;
slipComponent.LaunchForwardsMultiplier = 1;
}

_slipperySystem.TrySlip(args.Target, slipComponent, args.Target, requiresContact: false);
if (!hadSlipComponent)
{
RemComp(args.Target, slipComponent);
}

// Fall asleep
_sleep.TrySleeping(args.Target);

// Play a noise, they bonked their head
_popup.PopupEntity(Loc.GetString("admin-smite-caveman-self"), args.Target, player, PopupType.LargeCaution);
_audio.PlayPvs(new SoundPathSpecifier("/Audio/_NF/Effects/bonk.ogg"), args.Target, AudioParams.Default.WithMaxDistance(30.0f).WithVolume(3.0f));

EnsureComp<CavemanAccentComponent>(args.Target);
},
Impact = LogImpact.Extreme,
Message = Loc.GetString("admin-smite-caveman-description")
};
args.Verbs.Add(caveman);
// End Frontier
}
}
29 changes: 29 additions & 0 deletions Content.Server/Speech/Components/AddAccentPickupComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Content.Server.Speech.Components;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server._NF.Speech.Components;

/// <summary>
/// Applies accent to user while they wear entity as a clothing.
/// </summary>
[RegisterComponent]
public sealed partial class AddAccentPickupComponent : Component
{
/// <summary>
/// Component name for accent that will be applied.
/// </summary>
[DataField("accent", required: true)]
public string Accent = default!;

/// <summary>
/// What <see cref="ReplacementAccentPrototype"/> to use.
/// Will be applied only with <see cref="ReplacementAccentComponent"/>.
/// </summary>
[DataField("replacement", customTypeSerializer: typeof(PrototypeIdSerializer<ReplacementAccentPrototype>))]
public string? ReplacementPrototype;

/// <summary>
/// Is that clothing is worn and affecting someones accent?
/// </summary>
public bool IsActive = false;
}
73 changes: 73 additions & 0 deletions Content.Server/_NF/Speech/Components/CavemanAccentComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Content.Server._NF.Speech.EntitySystems;

namespace Content.Server._NF.Speech.Components;

[RegisterComponent]
[Access(typeof(CavemanAccentSystem))]
public sealed partial class CavemanAccentComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("MaxWordLength")]
public static int MaxWordLength = 5; // so man not talk smart, any word up dis be gone

[ViewVariables]
public static readonly List<string> ForbiddenWords = new()
{
"accent-caveman-forbidden-words-0",
"accent-caveman-forbidden-words-1",
"accent-caveman-forbidden-words-2",
"accent-caveman-forbidden-words-3",
"accent-caveman-forbidden-words-4",
"accent-caveman-forbidden-words-5",
"accent-caveman-forbidden-words-6",
"accent-caveman-forbidden-words-7",
"accent-caveman-forbidden-words-8",
"accent-caveman-forbidden-words-9",
"accent-caveman-forbidden-words-10",
"accent-caveman-forbidden-words-11",
"accent-caveman-forbidden-words-12",
"accent-caveman-forbidden-words-13",
"accent-caveman-forbidden-words-14",
"accent-caveman-forbidden-words-15",
};

[ViewVariables]
public static readonly List<string> Numbers = new()
{
"accent-caveman-numbers-0",
"accent-caveman-numbers-1",
"accent-caveman-numbers-2",
"accent-caveman-numbers-3",
"accent-caveman-numbers-4",
"accent-caveman-numbers-5",
"accent-caveman-numbers-6",
"accent-caveman-numbers-7",
"accent-caveman-numbers-8",
"accent-caveman-numbers-9",
"accent-caveman-numbers-10",
};

[ViewVariables]
public const string LargeNumberString = "accent-caveman-numbers-many";

[ViewVariables]
public static readonly List<string> Grunts = new()
{
"accent-caveman-grunts-0",
"accent-caveman-grunts-1",
"accent-caveman-grunts-2",
"accent-caveman-grunts-3",
"accent-caveman-grunts-4",
"accent-caveman-grunts-5",
"accent-caveman-grunts-6",
"accent-caveman-grunts-7",
"accent-caveman-grunts-8",
"accent-caveman-grunts-9",
"accent-caveman-grunts-10",
"accent-caveman-grunts-11",
"accent-caveman-grunts-12",
"accent-caveman-grunts-13",
"accent-caveman-grunts-14",
};

}
51 changes: 51 additions & 0 deletions Content.Server/_NF/Speech/EntitySystems/AddAccentPickupSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Content.Server._NF.Speech.Components;
using Content.Server.Speech.Components;
using Content.Shared.Interaction.Events;
using Content.Shared.Item;

namespace Content.Server._NF.Speech.EntitySystems;

public sealed class AddAccentPickupSystem : EntitySystem
{
[Dependency] private readonly IComponentFactory _componentFactory = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AddAccentPickupComponent, GettingPickedUpAttemptEvent>(OnPickup);
SubscribeLocalEvent<AddAccentPickupComponent, DroppedEvent>(OnDropped);
}

private void OnPickup(EntityUid uid, AddAccentPickupComponent component, ref GettingPickedUpAttemptEvent args)
{
// does the user already has this accent?
var componentType = _componentFactory.GetRegistration(component.Accent).Type;
if (HasComp(args.User, componentType))
return;

// add accent to the user
var accentComponent = (Component) _componentFactory.GetComponent(componentType);
AddComp(args.User, accentComponent);

// snowflake case for replacement accent
if (accentComponent is ReplacementAccentComponent rep)
rep.Accent = component.ReplacementPrototype!;

component.IsActive = true;
}

private void OnDropped(EntityUid uid, AddAccentPickupComponent component, DroppedEvent args)
{
if (!component.IsActive)
return;

// try to remove accent
var componentType = _componentFactory.GetRegistration(component.Accent).Type;
if (EntityManager.HasComponent(args.User, componentType))
{
EntityManager.RemoveComponent(args.User, componentType);
}

component.IsActive = false;
}
}
152 changes: 152 additions & 0 deletions Content.Server/_NF/Speech/EntitySystems/CavemanAccentSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using Content.Server._NF.Speech.Components;
using Robust.Shared.Random;
using Content.Server.Speech;
using Content.Server.Speech.EntitySystems;
using System.Linq;
using Content.Server.Chat.Systems;

namespace Content.Server._NF.Speech.EntitySystems;

public sealed class CavemanAccentSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
[Dependency] private readonly ChatSystem _chat = default!;

public readonly string[] PunctuationStringsToRemove = { "'", "\"", ".", ",", "!", "?", ";", ":" }; // Leave hyphens

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<CavemanAccentComponent, AccentGetEvent>(OnAccentGet);
}

private string Convert(string message, CavemanAccentComponent component)
{
string msg = _replacement.ApplyReplacements(message, "caveman");

string[] words = msg.Split(' ', StringSplitOptions.RemoveEmptyEntries);
List<string> modifiedWords = new List<string>();

foreach (var word in words)
{
string endPunctuation = "";
int actualLength = word.Length;

for (int letterIndex = word.Length - 1; letterIndex >= 0; letterIndex--)
{
if (word[letterIndex] != '-' && char.IsPunctuation(word[letterIndex]))
{
endPunctuation = word[letterIndex] + endPunctuation;
actualLength = letterIndex; // Length of word = index of first punctuation
}
else
{
break;
}
}

var modifiedWord = word;

if (actualLength > CavemanAccentComponent.MaxWordLength)
{
modifiedWord = GetGrunt();
CapitalizeReplacement(word, ref modifiedWord);
modifiedWord += endPunctuation;

modifiedWords.Add(modifiedWord);

continue;
}

modifiedWord = TryRemovePunctuation(modifiedWord);

modifiedWord = TryConvertNumbers(modifiedWord);

// If it's all punctuation, append the punctuation to the last word if it exists, otherwise add a grunt.
if (modifiedWord.Length <= 0)
{
if (modifiedWords.Count > 0)
{
modifiedWords[^1] += endPunctuation;
continue;
}
else
{
modifiedWord = GetGrunt();
}
}

modifiedWord += endPunctuation;

modifiedWords.Add(modifiedWord);
}

if (modifiedWords.Count == 0)
{
modifiedWords.Add(GetGrunt());
}

return _chat.SanitizeMessageCapital(string.Join(' ', modifiedWords));
}

private void OnAccentGet(EntityUid uid, CavemanAccentComponent component, AccentGetEvent args)
{
args.Message = Convert(args.Message, component);
}

private string GetGrunt()
{
var grunt = Loc.GetString(_random.Pick(CavemanAccentComponent.Grunts));

if (_random.Prob(0.5f))
{
grunt += "-";
grunt += Loc.GetString(_random.Pick(CavemanAccentComponent.Grunts));
}
return grunt;
}

private void CapitalizeReplacement(string input, ref string replacement)
{
if (!input.Any(char.IsLower) && (input.Length > 1 || replacement.Length == 1))
{
replacement = replacement.ToUpperInvariant();
}
else if (input.Length >= 1 && replacement.Length >= 1 && char.IsUpper(input[0]))
{
replacement = replacement[0].ToString().ToUpper() + replacement[1..];
}
}

private string TryRemovePunctuation(string word)
{
foreach (var punctStr in PunctuationStringsToRemove)
{
word = word.Replace(punctStr, "");
}
return word;
}

private string TryConvertNumbers(string word)
{
int num;

if (int.TryParse(word, out num))
{
num = int.Max(0, num); //Negatives treated as zero.
if (num < CavemanAccentComponent.Numbers.Count)
{
return Loc.GetString(CavemanAccentComponent.Numbers[num]);
}
else
{
return Loc.GetString(CavemanAccentComponent.LargeNumberString);
}
}

return word;
}

}
Loading

0 comments on commit 1ac9b2b

Please sign in to comment.