diff --git a/Content.Server/NameIdentifier/NameIdentifierSystem.cs b/Content.Server/NameIdentifier/NameIdentifierSystem.cs index 0a9f87557a..1e5ed67a63 100644 --- a/Content.Server/NameIdentifier/NameIdentifierSystem.cs +++ b/Content.Server/NameIdentifier/NameIdentifierSystem.cs @@ -20,7 +20,7 @@ public sealed class NameIdentifierSystem : EntitySystem /// Free IDs available per . /// [ViewVariables] - public readonly Dictionary> CurrentIds = new(); + public readonly Dictionary> CurrentIds = []; public override void Initialize() { @@ -35,18 +35,22 @@ public sealed class NameIdentifierSystem : EntitySystem InitialSetupPrototypes(); } - private void OnComponentShutdown(EntityUid uid, NameIdentifierComponent component, ComponentShutdown args) + private void OnComponentShutdown(Entity ent, ref ComponentShutdown args) { - if (CurrentIds.TryGetValue(component.Group, out var ids)) + if (ent.Comp.Group is null) + return; + + if (CurrentIds.TryGetValue(ent.Comp.Group, out var ids) && ids.Count > 0) { // Avoid inserting the value right back at the end or shuffling in place: // just pick a random spot to put it and then move that one to the end. var randomIndex = _robustRandom.Next(ids.Count); var random = ids[randomIndex]; - ids[randomIndex] = component.Identifier; + ids[randomIndex] = ent.Comp.Identifier; ids.Add(random); } - _nameModifier.RefreshNameModifiers(uid); + + _nameModifier.RefreshNameModifiers(ent.Owner); } /// @@ -83,46 +87,53 @@ public sealed class NameIdentifierSystem : EntitySystem : $"{randomVal}"; } - private void OnMapInit(EntityUid uid, NameIdentifierComponent component, MapInitEvent args) + private void OnMapInit(Entity ent, ref MapInitEvent args) { - if (!_prototypeManager.TryIndex(component.Group, out var group)) + if (ent.Comp.Group is null) + return; + + if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) return; int id; string uniqueName; // If it has an existing valid identifier then use that, otherwise generate a new one. - if (component.Identifier != -1 && - CurrentIds.TryGetValue(component.Group, out var ids) && - ids.Remove(component.Identifier)) + if (ent.Comp.Identifier != -1 && + CurrentIds.TryGetValue(ent.Comp.Group, out var ids) && + ids.Remove(ent.Comp.Identifier)) { - id = component.Identifier; + id = ent.Comp.Identifier; uniqueName = group.Prefix is not null ? $"{group.Prefix}-{id}" : $"{id}"; } else { - uniqueName = GenerateUniqueName(uid, group, out id); - component.Identifier = id; + uniqueName = GenerateUniqueName(ent, group, out id); + ent.Comp.Identifier = id; } - component.FullIdentifier = group.FullName + ent.Comp.FullIdentifier = group.FullName ? uniqueName : $"({uniqueName})"; - Dirty(uid, component); - _nameModifier.RefreshNameModifiers(uid); + Dirty(ent); + _nameModifier.RefreshNameModifiers(ent.Owner); } private void OnRefreshNameModifiers(Entity ent, ref RefreshNameModifiersEvent args) { + if (ent.Comp.Group is null) + return; + // Don't apply the modifier if the component is being removed if (ent.Comp.LifeStage > ComponentLifeStage.Running) return; - if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) + if (!_prototypeManager.TryIndex(ent.Comp.Group, out var group)) return; + var format = group.FullName ? "name-identifier-format-full" : "name-identifier-format-append"; // We apply the modifier with a low priority to keep it near the base name // "Beep (Si-4562) the zombie" instead of "Beep the zombie (Si-4562)" @@ -188,13 +199,13 @@ public sealed class NameIdentifierSystem : EntitySystem foreach (var proto in set.Modified.Values) { - var name_proto = (NameIdentifierGroupPrototype) proto; + var name_proto = (NameIdentifierGroupPrototype)proto; // Only bother adding new ones. if (CurrentIds.ContainsKey(proto.ID)) continue; - var ids = GetOrCreateIdList(name_proto); + var ids = GetOrCreateIdList(name_proto); FillGroup(name_proto, ids); } } diff --git a/Content.Shared/NameIdentifier/NameIdentifierComponent.cs b/Content.Shared/NameIdentifier/NameIdentifierComponent.cs index 49be08a6a3..f9f9eef49b 100644 --- a/Content.Shared/NameIdentifier/NameIdentifierComponent.cs +++ b/Content.Shared/NameIdentifier/NameIdentifierComponent.cs @@ -1,5 +1,5 @@ using Robust.Shared.GameStates; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Prototypes; namespace Content.Shared.NameIdentifier; @@ -9,18 +9,18 @@ namespace Content.Shared.NameIdentifier; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class NameIdentifierComponent : Component { - [DataField("group", required: true, customTypeSerializer:typeof(PrototypeIdSerializer))] - public string Group = string.Empty; + [DataField] + public ProtoId? Group; /// /// The randomly generated ID for this entity. /// - [DataField("identifier"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField, AutoNetworkedField] public int Identifier = -1; /// /// The full name identifier for this entity. /// - [DataField("fullIdentifier"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + [DataField, AutoNetworkedField] public string FullIdentifier = string.Empty; } diff --git a/Resources/Locale/en-US/datasets/names/scurret_first.ftl b/Resources/Locale/en-US/datasets/names/scurret_first.ftl index 4bbbf943f0..a01a6db8bb 100644 --- a/Resources/Locale/en-US/datasets/names/scurret_first.ftl +++ b/Resources/Locale/en-US/datasets/names/scurret_first.ftl @@ -1,3 +1,19 @@ +# Scurrets from Planet Wawa have two parts to their name - a 'chosen' and 'qualitative' name. + +# The chosen name is picked by the scurret themselves, +# encompassing a trait or value they hold themselves +# to or have a high value for. Scurrets sometimes change this +# name to denote an important moment in their life. + +# It appears to be common for scurret sets to share the same +# chosen name, with the gaining of a pup's own chosen name +# signalling their transition to adulthood in the community. + +# Given the scurret language is untranslated, these names are +# usually guessed via charades or Pictionary. + +# When all else fails, to NT and her crews, Wa is as good a name as any. + names-scurret-first-dataset-1 = Wa names-scurret-first-dataset-2 = Calm names-scurret-first-dataset-3 = Contented @@ -34,3 +50,18 @@ names-scurret-first-dataset-33 = Wise names-scurret-first-dataset-34 = Alert names-scurret-first-dataset-35 = Uplifting names-scurret-first-dataset-36 = Considerate +names-scurret-first-dataset-37 = Surviving +names-scurret-first-dataset-38 = Meditating +names-scurret-first-dataset-39 = Hunting +names-scurret-first-dataset-40 = Watching +names-scurret-first-dataset-41 = Resting +names-scurret-first-dataset-42 = Delivering +names-scurret-first-dataset-43 = Swimming +names-scurret-first-dataset-44 = Swinging +names-scurret-first-dataset-45 = Exploding +names-scurret-first-dataset-46 = Romancing +names-scurret-first-dataset-47 = Far-Seeing +names-scurret-first-dataset-48 = Loyal +names-scurret-first-dataset-49 = Inquisitive +# After consulting with lawyers, NT added this one to the dictionary. +names-scurret-first-dataset-50 = Legally Distinct diff --git a/Resources/Locale/en-US/datasets/names/scurret_last.ftl b/Resources/Locale/en-US/datasets/names/scurret_last.ftl index effe2180f0..bac9b818d1 100644 --- a/Resources/Locale/en-US/datasets/names/scurret_last.ftl +++ b/Resources/Locale/en-US/datasets/names/scurret_last.ftl @@ -1,3 +1,19 @@ +# Scurrets from Planet Wawa have two parts to their name - a 'chosen' and 'qualitative' name. + +# The qualitative name is usually related to an important feature +# of Wawa's wetland habitats that the scurret is associated with +# by their community. + +# Scurret pups, due to both their quantity and complete lack +# of any survival instinct, lack a qualitative name entirely. +# Researchers believe their parents simply give them a number. + +# Given that the scurret language is untranslated, these names are +# usually deduced via the showing of photographs, annoyed and +# repeated pointing at nearby objects, or games of Pictionary. + +# When all else fails, to NT and her crews, Wa is as good a name as any. + names-scurret-last-dataset-1 = Wa names-scurret-last-dataset-2 = Trees names-scurret-last-dataset-3 = Plants @@ -6,12 +22,12 @@ names-scurret-last-dataset-5 = Rivers names-scurret-last-dataset-6 = Groves names-scurret-last-dataset-7 = Lakes names-scurret-last-dataset-8 = Marshes -names-scurret-last-dataset-9 = Spring +names-scurret-last-dataset-9 = Springs names-scurret-last-dataset-10 = Reeds names-scurret-last-dataset-11 = Sunshine names-scurret-last-dataset-12 = Rain names-scurret-last-dataset-13 = Clouds -names-scurret-last-dataset-14 = Snowfall +names-scurret-last-dataset-14 = Snowfalls names-scurret-last-dataset-15 = Stones names-scurret-last-dataset-16 = Pebbles names-scurret-last-dataset-17 = Fishes @@ -25,7 +41,7 @@ names-scurret-last-dataset-24 = Alders names-scurret-last-dataset-25 = Birches names-scurret-last-dataset-26 = Poplars names-scurret-last-dataset-27 = Marigolds -names-scurret-last-dataset-28 = Robins +names-scurret-last-dataset-28 = Rowans names-scurret-last-dataset-29 = Orchids names-scurret-last-dataset-30 = Rushes names-scurret-last-dataset-31 = Lillies @@ -33,4 +49,20 @@ names-scurret-last-dataset-32 = Violets names-scurret-last-dataset-33 = Maples names-scurret-last-dataset-34 = Oaks names-scurret-last-dataset-35 = Hazels +# AND SIR GIDEON OFNIR names-scurret-last-dataset-36 = the All-Knowing +names-scurret-last-dataset-37 = Tarns +names-scurret-last-dataset-38 = Waters +names-scurret-last-dataset-39 = Reservoirs +names-scurret-last-dataset-40 = Dams +names-scurret-last-dataset-41 = Moors +names-scurret-last-dataset-42 = Fens +names-scurret-last-dataset-43 = Temples +names-scurret-last-dataset-44 = Hills +names-scurret-last-dataset-45 = Copses +names-scurret-last-dataset-46 = Fields +names-scurret-last-dataset-47 = Ancestors +names-scurret-last-dataset-48 = Forests +names-scurret-last-dataset-49 = Secrets +# Nobody's quite sure how this one is in the dictionary. +names-scurret-last-dataset-50 = Space Ferret diff --git a/Resources/Prototypes/Datasets/Names/scurret.yml b/Resources/Prototypes/Datasets/Names/scurret.yml index b3ac08e2ad..9e23557b38 100644 --- a/Resources/Prototypes/Datasets/Names/scurret.yml +++ b/Resources/Prototypes/Datasets/Names/scurret.yml @@ -2,10 +2,10 @@ id: NamesFirstScurret values: prefix: names-scurret-first-dataset- - count: 36 + count: 50 - type: localizedDataset id: NamesLastScurret values: prefix: names-scurret-last-dataset- - count: 36 + count: 50 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index 19ba323a0a..1f0eb0f9e2 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -139,6 +139,14 @@ available: - enum.DamageStateVisualLayers.Base: scurret: ScurretColors + # They are of a mysterious gender. + - type: Grammar + attributes: + gender: epicene + proper: true + # Strips the name identifier from them, so they're just "Confident Waters" rather than "Confident Waters (123)" + - type: NameIdentifier + group: null # Emotional Support Scurrets have a ghost role and equipment. At the moment, these are intended to be used for admemes, but # feel free to hook them into random content. @@ -169,4 +177,4 @@ name: Emotional Support Scurret id: MobEmotionalSupportScurret parent: [MobScurret, MobBaseEmotionalSupportScurret] - description: Commonly known as Wawa, from the wetlands of Planet Wawa, these critters make up the bulk of Arnolds's Pizza's "loyal workforce". This one is here as a temp. + description: Commonly known as Wawa, from the wetlands of Planet Wawa, these critters make up the bulk of Arnold's Pizza's "loyal workforce". This one is here as a temp.