diff --git a/Content.Client/Standing/LayingDownSystem.cs b/Content.Client/Standing/LayingDownSystem.cs index 6cc5f7921ac..594883ac001 100644 --- a/Content.Client/Standing/LayingDownSystem.cs +++ b/Content.Client/Standing/LayingDownSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.ActionBlocker; +using Content.Shared.Buckle; using Content.Shared.Rotation; using Content.Shared.Standing; using Robust.Client.GameObjects; @@ -11,8 +11,9 @@ public sealed class LayingDownSystem : SharedLayingDownSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private readonly StandingStateSystem _standing = default!; [Dependency] private readonly AnimationPlayerSystem _animation = default!; - [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; + [Dependency] private readonly SharedBuckleSystem _buckle = default!; public override void Initialize() { @@ -26,7 +27,8 @@ public override void Initialize() private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveEvent args) { if (!_timing.IsFirstTimePredicted - || !_actionBlocker.CanMove(uid) + || !_standing.IsDown(uid) + || _buckle.IsBuckled(uid) || _animation.HasRunningAnimation(uid, "rotate") || !TryComp(uid, out var transform) || !TryComp(uid, out var sprite) diff --git a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs index 5654f9067b5..a84e21b997e 100644 --- a/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs +++ b/Content.Server/Chemistry/ReagentEffects/MakeSentient.cs @@ -41,7 +41,7 @@ public override void Effect(ReagentEffectArgs args) if (!knowledge.SpokenLanguages.Contains(fallback)) knowledge.SpokenLanguages.Add(fallback); - IoCManager.Resolve().GetEntitySystem().UpdateEntityLanguages(uid, speaker); + IoCManager.Resolve().GetEntitySystem().UpdateEntityLanguages(uid); // Stops from adding a ghost role to things like people who already have a mind if (entityManager.TryGetComponent(uid, out var mindContainer) && mindContainer.HasMind) diff --git a/Content.Server/Language/LanguageSystem.Networking.cs b/Content.Server/Language/LanguageSystem.Networking.cs index 572e2961fde..5f7f2742734 100644 --- a/Content.Server/Language/LanguageSystem.Networking.cs +++ b/Content.Server/Language/LanguageSystem.Networking.cs @@ -64,12 +64,7 @@ private void SendLanguageStateToClient(ICommonSession session, LanguageSpeakerCo // TODO this is really stupid and can be avoided if we just make everything shared... private void SendLanguageStateToClient(EntityUid uid, ICommonSession session, LanguageSpeakerComponent? component = null) { - var isUniversal = HasComp(uid); - if (!isUniversal) - Resolve(uid, ref component, logMissing: false); - - // I really don't want to call 3 getter methods here, so we'll just have this slightly hardcoded solution - var message = isUniversal || component == null + var message = !Resolve(uid, ref component, logMissing: false) ? new LanguagesUpdatedMessage(UniversalPrototype, [UniversalPrototype], [UniversalPrototype]) : new LanguagesUpdatedMessage(component.CurrentLanguage, component.SpokenLanguages, component.UnderstoodLanguages); diff --git a/Content.Server/Language/LanguageSystem.cs b/Content.Server/Language/LanguageSystem.cs index e68489e9e28..a1c30997e2d 100644 --- a/Content.Server/Language/LanguageSystem.cs +++ b/Content.Server/Language/LanguageSystem.cs @@ -2,7 +2,6 @@ using Content.Server.Language.Events; using Content.Shared.Language; using Content.Shared.Language.Components; -using Content.Shared.Language.Events; using Content.Shared.Language.Systems; using UniversalLanguageSpeakerComponent = Content.Shared.Language.Components.UniversalLanguageSpeakerComponent; @@ -16,8 +15,19 @@ public override void Initialize() InitializeNet(); SubscribeLocalEvent(OnInitLanguageSpeaker); + SubscribeLocalEvent(OnUniversalInit); + SubscribeLocalEvent(OnUniversalShutdown); } + private void OnUniversalShutdown(EntityUid uid, UniversalLanguageSpeakerComponent component, ComponentShutdown args) + { + RemoveLanguage(uid, UniversalPrototype); + } + + private void OnUniversalInit(EntityUid uid, UniversalLanguageSpeakerComponent component, MapInitEvent args) + { + AddLanguage(uid, UniversalPrototype); + } #region public api @@ -48,10 +58,9 @@ public bool CanSpeak(EntityUid speaker, string language, LanguageSpeakerComponen /// public LanguagePrototype GetLanguage(EntityUid speaker, LanguageSpeakerComponent? component = null) { - if (HasComp(speaker) || !Resolve(speaker, ref component, logMissing: false)) - return Universal; // Serves both as a fallback and uhhh something (TODO: fix this comment) - - if (string.IsNullOrEmpty(component.CurrentLanguage) || !_prototype.TryIndex(component.CurrentLanguage, out var proto)) + if (!Resolve(speaker, ref component, logMissing: false) + || string.IsNullOrEmpty(component.CurrentLanguage) + || !_prototype.TryIndex(component.CurrentLanguage, out var proto)) return Universal; return proto; @@ -63,13 +72,10 @@ public LanguagePrototype GetLanguage(EntityUid speaker, LanguageSpeakerComponent /// Typically, checking is sufficient. public List GetSpokenLanguages(EntityUid uid) { - if (HasComp(uid)) - return [UniversalPrototype]; + if (!TryComp(uid, out var component)) + return []; - if (TryComp(uid, out var component)) - return component.SpokenLanguages; - - return []; + return component.SpokenLanguages; } /// @@ -78,21 +84,17 @@ public List GetSpokenLanguages(EntityUid uid) /// Typically, checking is sufficient. public List GetUnderstoodLanguages(EntityUid uid) { - if (HasComp(uid)) - return [UniversalPrototype]; // This one is tricky because... well, they understand all of them, not just one. - - if (TryComp(uid, out var component)) - return component.UnderstoodLanguages; + if (!TryComp(uid, out var component)) + return []; - return []; + return component.UnderstoodLanguages; } public void SetLanguage(EntityUid speaker, string language, LanguageSpeakerComponent? component = null) { - if (!CanSpeak(speaker, language) || (HasComp(speaker) && language != UniversalPrototype)) - return; - - if (!Resolve(speaker, ref component) || component.CurrentLanguage == language) + if (!CanSpeak(speaker, language) + || !Resolve(speaker, ref component) + || component.CurrentLanguage == language) return; component.CurrentLanguage = language; @@ -106,12 +108,10 @@ public void AddLanguage( EntityUid uid, string language, bool addSpoken = true, - bool addUnderstood = true, - LanguageKnowledgeComponent? knowledge = null, - LanguageSpeakerComponent? speaker = null) + bool addUnderstood = true) { - if (knowledge == null) - knowledge = EnsureComp(uid); + EnsureComp(uid, out var knowledge); + EnsureComp(uid); if (addSpoken && !knowledge.SpokenLanguages.Contains(language)) knowledge.SpokenLanguages.Add(language); @@ -119,7 +119,7 @@ public void AddLanguage( if (addUnderstood && !knowledge.UnderstoodLanguages.Contains(language)) knowledge.UnderstoodLanguages.Add(language); - UpdateEntityLanguages(uid, speaker); + UpdateEntityLanguages(uid); } /// @@ -129,12 +129,10 @@ public void RemoveLanguage( EntityUid uid, string language, bool removeSpoken = true, - bool removeUnderstood = true, - LanguageKnowledgeComponent? knowledge = null, - LanguageSpeakerComponent? speaker = null) + bool removeUnderstood = true) { - if (knowledge == null) - knowledge = EnsureComp(uid); + if (!TryComp(uid, out var knowledge)) + return; if (removeSpoken) knowledge.SpokenLanguages.Remove(language); @@ -142,7 +140,7 @@ public void RemoveLanguage( if (removeUnderstood) knowledge.UnderstoodLanguages.Remove(language); - UpdateEntityLanguages(uid, speaker); + UpdateEntityLanguages(uid); } /// @@ -168,9 +166,9 @@ public bool EnsureValidLanguage(EntityUid entity, LanguageSpeakerComponent? comp /// /// Immediately refreshes the cached lists of spoken and understood languages for the given entity. /// - public void UpdateEntityLanguages(EntityUid entity, LanguageSpeakerComponent? languages = null) + public void UpdateEntityLanguages(EntityUid entity) { - if (!Resolve(entity, ref languages)) + if (!TryComp(entity, out var languages)) return; var ev = new DetermineEntityLanguagesEvent(); @@ -205,7 +203,7 @@ private void OnInitLanguageSpeaker(EntityUid uid, LanguageSpeakerComponent compo if (string.IsNullOrEmpty(component.CurrentLanguage)) component.CurrentLanguage = component.SpokenLanguages.FirstOrDefault(UniversalPrototype); - UpdateEntityLanguages(uid, component); + UpdateEntityLanguages(uid); } #endregion diff --git a/Content.Server/Language/TranslatorSystem.cs b/Content.Server/Language/TranslatorSystem.cs index a893993e884..c48b93a3930 100644 --- a/Content.Server/Language/TranslatorSystem.cs +++ b/Content.Server/Language/TranslatorSystem.cs @@ -85,8 +85,8 @@ private void OnTranslatorParentChanged(EntityUid translator, HandheldTranslatorC // If that is not the case, then OnProxyDetermineLanguages will remove this translator from HoldsTranslatorComponent.Translators. Timer.Spawn(0, () => { - if (Exists(args.OldParent) && TryComp(args.OldParent, out var speaker)) - _language.UpdateEntityLanguages(args.OldParent.Value, speaker); + if (Exists(args.OldParent) && HasComp(args.OldParent)) + _language.UpdateEntityLanguages(args.OldParent.Value); }); } @@ -108,7 +108,7 @@ private void OnTranslatorToggle(EntityUid translator, HandheldTranslatorComponen { // The first new spoken language added by this translator, or null var firstNewLanguage = translatorComp.SpokenLanguages.FirstOrDefault(it => !languageComp.SpokenLanguages.Contains(it)); - _language.UpdateEntityLanguages(holder, languageComp); + _language.UpdateEntityLanguages(holder); // Update the current language of the entity if necessary if (isEnabled && translatorComp.SetLanguageOnInteract && firstNewLanguage is {}) @@ -131,8 +131,8 @@ private void OnPowerCellSlotEmpty(EntityUid translator, HandheldTranslatorCompon _powerCell.SetPowerCellDrawEnabled(translator, false); OnAppearanceChange(translator, component); - if (_containers.TryGetContainingContainer(translator, out var holderCont) && TryComp(holderCont.Owner, out var languageComp)) - _language.UpdateEntityLanguages(holderCont.Owner, languageComp); + if (_containers.TryGetContainingContainer(translator, out var holderCont) && HasComp(holderCont.Owner)) + _language.UpdateEntityLanguages(holderCont.Owner); } private void CopyLanguages(BaseTranslatorComponent from, DetermineEntityLanguagesEvent to, LanguageKnowledgeComponent knowledge) diff --git a/Content.Server/Traits/Assorted/ForeignerTraitSystem.cs b/Content.Server/Traits/Assorted/ForeignerTraitSystem.cs index 58e974227ce..2c7274a13d5 100644 --- a/Content.Server/Traits/Assorted/ForeignerTraitSystem.cs +++ b/Content.Server/Traits/Assorted/ForeignerTraitSystem.cs @@ -46,7 +46,7 @@ private void OnSpawn(Entity entity, ref ComponentInit a if (TryGiveTranslator(entity.Owner, entity.Comp.BaseTranslator, entity.Comp.BaseLanguage, alternateLanguage, out var translator)) { - _languages.RemoveLanguage(entity, entity.Comp.BaseLanguage, entity.Comp.CantSpeak, entity.Comp.CantUnderstand, knowledge); + _languages.RemoveLanguage(entity, entity.Comp.BaseLanguage, entity.Comp.CantSpeak, entity.Comp.CantUnderstand); } } diff --git a/Content.Server/Traits/Assorted/LanguageKnowledgeModifierComponent.cs b/Content.Server/Traits/Assorted/LanguageKnowledgeModifierComponent.cs deleted file mode 100644 index 170dae40fa6..00000000000 --- a/Content.Server/Traits/Assorted/LanguageKnowledgeModifierComponent.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Content.Shared.Language; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; - -namespace Content.Server.Traits.Assorted; - -/// -/// Used for traits that modify entities' language knowledge. -/// -[RegisterComponent] -public sealed partial class LanguageKnowledgeModifierComponent : Component -{ - /// - /// List of languages this entity will learn to speak. - /// - [DataField("speaks")] - public List NewSpokenLanguages = new(); - - /// - /// List of languages this entity will learn to understand. - /// - [DataField("understands")] - public List NewUnderstoodLanguages = new(); -} diff --git a/Content.Server/Traits/Assorted/LanguageKnowledgeModifierSystem.cs b/Content.Server/Traits/Assorted/LanguageKnowledgeModifierSystem.cs deleted file mode 100644 index 9053c9404fe..00000000000 --- a/Content.Server/Traits/Assorted/LanguageKnowledgeModifierSystem.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Linq; -using Content.Server.Language; -using Content.Shared.Language.Components; - -namespace Content.Server.Traits.Assorted; - -public sealed class LanguageKnowledgeModifierSystem : EntitySystem -{ - [Dependency] private readonly LanguageSystem _languages = default!; - - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnStartup); - } - - private void OnStartup(Entity entity, ref ComponentInit args) - { - if (!TryComp(entity, out var knowledge)) - { - Log.Warning($"Entity {entity.Owner} does not have a LanguageKnowledge but has a LanguageKnowledgeModifier!"); - return; - } - - foreach (var spokenLanguage in entity.Comp.NewSpokenLanguages) - { - _languages.AddLanguage(entity, spokenLanguage, true, false, knowledge); - } - - foreach (var understoodLanguage in entity.Comp.NewUnderstoodLanguages) - { - _languages.AddLanguage(entity, understoodLanguage, false, true, knowledge); - } - } -} diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index 39812f65b6d..bd36b4ecefb 100644 --- a/Content.Server/Traits/TraitSystem.cs +++ b/Content.Server/Traits/TraitSystem.cs @@ -12,6 +12,7 @@ using Robust.Shared.Utility; using Content.Server.Abilities.Psionics; using Content.Shared.Psionics; +using Content.Server.Language; using Content.Shared.Mood; namespace Content.Server.Traits; @@ -26,6 +27,7 @@ public sealed class TraitSystem : EntitySystem [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly PsionicAbilitiesSystem _psionicAbilities = default!; [Dependency] private readonly IComponentFactory _componentFactory = default!; + [Dependency] private readonly LanguageSystem _languageSystem = default!; public override void Initialize() { @@ -66,6 +68,8 @@ public void AddTrait(EntityUid uid, TraitPrototype traitPrototype) AddTraitComponents(uid, traitPrototype); AddTraitActions(uid, traitPrototype); AddTraitPsionics(uid, traitPrototype); + AddTraitLanguage(uid, traitPrototype); + RemoveTraitLanguage(uid, traitPrototype); AddTraitMoodlets(uid, traitPrototype); } @@ -142,6 +146,72 @@ public void AddTraitPsionics(EntityUid uid, TraitPrototype traitPrototype) _psionicAbilities.InitializePsionicPower(uid, psionicPower, false); } + /// + /// Initialize languages given by a Trait. + /// + private void AddTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) + { + AddTraitLanguagesSpoken(uid, traitPrototype); + AddTraitLanguagesUnderstood(uid, traitPrototype); + } + + /// + /// If a trait includes any Spoken Languages, this sends them to LanguageSystem to be initialized. + /// + public void AddTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) + { + if (traitPrototype.LanguagesSpoken is null) + return; + + foreach (var language in traitPrototype.LanguagesSpoken) + _languageSystem.AddLanguage(uid, language, true, false); + } + + /// + /// If a trait includes any Understood Languages, this sends them to LanguageSystem to be initialized. + /// + public void AddTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) + { + if (traitPrototype.LanguagesUnderstood is null) + return; + + foreach (var language in traitPrototype.LanguagesUnderstood) + _languageSystem.AddLanguage(uid, language, false, true); + } + + /// + /// Remove Languages given by a Trait. + /// + private void RemoveTraitLanguage(EntityUid uid, TraitPrototype traitPrototype) + { + RemoveTraitLanguagesSpoken(uid, traitPrototype); + RemoveTraitLanguagesUnderstood(uid, traitPrototype); + } + + /// + /// Removes any Spoken Languages if defined by a trait. + /// + public void RemoveTraitLanguagesSpoken(EntityUid uid, TraitPrototype traitPrototype) + { + if (traitPrototype.RemoveLanguagesSpoken is null) + return; + + foreach (var language in traitPrototype.RemoveLanguagesSpoken) + _languageSystem.RemoveLanguage(uid, language, true, false); + } + + /// + /// Removes any Understood Languages if defined by a trait. + /// + public void RemoveTraitLanguagesUnderstood(EntityUid uid, TraitPrototype traitPrototype) + { + if (traitPrototype.RemoveLanguagesUnderstood is null) + return; + + foreach (var language in traitPrototype.RemoveLanguagesUnderstood) + _languageSystem.RemoveLanguage(uid, language, false, true); + } + /// /// If a trait includes any moodlets, this adds the moodlets to the receiving entity. /// While I can't stop you, you shouldn't use this to add temporary moodlets. diff --git a/Content.Shared/Standing/SharedLayingDownSystem.cs b/Content.Shared/Standing/SharedLayingDownSystem.cs index 47ad01949cb..7a82d4b7aa8 100644 --- a/Content.Shared/Standing/SharedLayingDownSystem.cs +++ b/Content.Shared/Standing/SharedLayingDownSystem.cs @@ -40,7 +40,8 @@ public override void Shutdown() private void ToggleStanding(ICommonSession? session) { - if (session?.AttachedEntity == null + if (session is not { AttachedEntity: { Valid: true } uid } _ + || !Exists(uid) || !HasComp(session.AttachedEntity) || _gravity.IsWeightless(session.AttachedEntity.Value)) return; diff --git a/Content.Shared/Traits/Prototypes/TraitPrototype.cs b/Content.Shared/Traits/Prototypes/TraitPrototype.cs index cd4b02a1e63..7c0e429a691 100644 --- a/Content.Shared/Traits/Prototypes/TraitPrototype.cs +++ b/Content.Shared/Traits/Prototypes/TraitPrototype.cs @@ -58,6 +58,30 @@ public sealed partial class TraitPrototype : IPrototype [DataField] public List? PsionicPowers { get; private set; } = default!; + /// + /// The list of all Spoken Languages that this trait adds. + /// + [DataField] + public List? LanguagesSpoken { get; private set; } = default!; + + /// + /// The list of all Understood Languages that this trait adds. + /// + [DataField] + public List? LanguagesUnderstood { get; private set; } = default!; + + /// + /// The list of all Spoken Languages that this trait removes. + /// + [DataField] + public List? RemoveLanguagesSpoken { get; private set; } = default!; + + /// + /// The list of all Understood Languages that this trait removes. + /// + [DataField] + public List? RemoveLanguagesUnderstood { get; private set; } = default!; + /// /// The list of all Moodlets that this trait adds. /// diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d7568628f6f..a233a61a2d4 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -6456,3 +6456,14 @@ Entries: id: 6371 time: '2024-09-19T03:29:41.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/929 +- author: VMSolidus + changes: + - type: Fix + message: >- + Fixed issues with the LayingDownSystem. Laying down no longer causes all + entities on your screen to lay down at once. Using any movement input no + longer causes the character to appear to the player as to be laying + down. + id: 6372 + time: '2024-09-19T20:37:51.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/933 diff --git a/Resources/Prototypes/Entities/Structures/Specific/oracle.yml b/Resources/Prototypes/Entities/Structures/Specific/oracle.yml index b60906b55e0..2161c6d80da 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/oracle.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/oracle.yml @@ -67,6 +67,13 @@ demandWhitelist: components: - Item + - type: LanguageSpeaker + currentLanguage: GalacticCommon + - type: LanguageKnowledge + speaks: + - GalacticCommon + understands: + - GalacticCommon - type: weightedRandomEntity diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml index 1a065b001c1..533cf314999 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Research/sophicscribe.yml @@ -48,3 +48,10 @@ - type: GuideHelp guides: - Psionics + - type: LanguageSpeaker + currentLanguage: GalacticCommon + - type: LanguageKnowledge + speaks: + - GalacticCommon + understands: + - GalacticCommon diff --git a/Resources/Prototypes/Traits/skills.yml b/Resources/Prototypes/Traits/skills.yml index fa79666c7ab..015c9f50233 100644 --- a/Resources/Prototypes/Traits/skills.yml +++ b/Resources/Prototypes/Traits/skills.yml @@ -102,12 +102,10 @@ id: SignLanguage category: Visual points: -2 - components: - - type: LanguageKnowledgeModifier - speaks: - - Sign - understands: - - Sign + languagesSpoken: + - Sign + languagesUnderstood: + - Sign - type: trait id: Voracious