From 3e4ef88d5991daf8f18654dd0eb952de325b9150 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Sat, 10 Aug 2024 04:54:52 +0800 Subject: [PATCH] fix(mood): improve mood calculation Fixes a bug surrounding the neutral threshold (50) being added twice in `SetMood`, resulting in 100 mood for everyone. Fixes the `NetMoodComponent` field `CurrentMoodLevel` not being synced properly with `MoodComponent`. This also refactors `MoodSystem` to centralize mood calculations to `RefreshMood` and `SetMood`. For consistency reasons, death is now a moodlet that gets added upon death, and removed upon revival. Only `RefreshMood` should ever get to call `SetMood`. I have more ideas on refactoring `MoodSystem` in separate PRs. --- Content.Server/Mood/MoodSystem.cs | 60 ++++++++----------- .../Mood/generic_negativeEffects.yml | 5 ++ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/Content.Server/Mood/MoodSystem.cs b/Content.Server/Mood/MoodSystem.cs index 252780d58cc..ae09a25f72f 100644 --- a/Content.Server/Mood/MoodSystem.cs +++ b/Content.Server/Mood/MoodSystem.cs @@ -1,4 +1,4 @@ -using Content.Server.Chat.Managers; +using Content.Server.Chat.Managers; using Content.Server.Popups; using Content.Shared.Alert; using Content.Shared.Chat; @@ -94,8 +94,6 @@ private void OnMoodEffect(EntityUid uid, MoodComponent component, MoodEffectEven private void ApplyEffect(EntityUid uid, MoodComponent component, MoodEffectPrototype prototype, float eventModifier = 1, float eventOffset = 0) { - var amount = component.CurrentMoodLevel; - //Apply categorised effect if (prototype.Category != null) { @@ -107,14 +105,12 @@ private void ApplyEffect(EntityUid uid, MoodComponent component, MoodEffectProto if (prototype.ID != oldPrototype.ID) { SendEffectText(uid, prototype); - amount += prototype.MoodChange - oldPrototype.MoodChange; component.CategorisedEffects[prototype.Category] = prototype.ID; } } else { component.CategorisedEffects.Add(prototype.Category, prototype.ID); - amount += prototype.MoodChange; } if (prototype.Timeout != 0) @@ -132,16 +128,12 @@ private void ApplyEffect(EntityUid uid, MoodComponent component, MoodEffectProto SendEffectText(uid, prototype); component.UncategorisedEffects.Add(prototype.ID, moodChange); - amount += moodChange; - SetMood(uid, moodChange, component); if (prototype.Timeout != 0) Timer.Spawn(TimeSpan.FromSeconds(prototype.Timeout), () => RemoveTimedOutEffect(uid, prototype.ID)); - - return; } - SetMood(uid, amount, component); + RefreshMood(uid, component); } private void SendEffectText(EntityUid uid, MoodEffectPrototype prototype) @@ -155,14 +147,10 @@ private void RemoveTimedOutEffect(EntityUid uid, string prototypeId, string? cat if (!TryComp(uid, out var comp)) return; - var amount = comp.CurrentMoodLevel; - if (category == null) { if (!comp.UncategorisedEffects.TryGetValue(prototypeId, out var value)) return; - - amount -= value; comp.UncategorisedEffects.Remove(prototypeId); } else @@ -171,26 +159,33 @@ private void RemoveTimedOutEffect(EntityUid uid, string prototypeId, string? cat || currentProtoId != prototypeId || !_prototypeManager.TryIndex(currentProtoId, out var currentProto)) return; - - amount -= currentProto.MoodChange; comp.CategorisedEffects.Remove(category); } - SetMood(uid, amount, comp); + RefreshMood(uid, comp); } private void OnMobStateChanged(EntityUid uid, MoodComponent component, MobStateChangedEvent args) { if (args.NewMobState == MobState.Dead && args.OldMobState != MobState.Dead) - SetMood(uid, component.MoodThresholds[MoodThreshold.Dead], component, true); - + { + var ev = new MoodEffectEvent("Dead"); + RaiseLocalEvent(uid, ev); + } else if (args.OldMobState == MobState.Dead && args.NewMobState != MobState.Dead) - ReapplyAllEffects(uid, component); + { + var ev = new MoodRemoveEffectEvent("Dead"); + RaiseLocalEvent(uid, ev); + } + RefreshMood(uid, component); } - private void ReapplyAllEffects(EntityUid uid, MoodComponent component) + // + // Recalculate the mood level of an entity by summing up all moodlets. + // + private void RefreshMood(EntityUid uid, MoodComponent component) { - var amount = component.MoodThresholds[MoodThreshold.Neutral]; + var amount = 0f; foreach (var (_, protoId) in component.CategorisedEffects) { @@ -213,16 +208,14 @@ private void OnInit(EntityUid uid, MoodComponent component, ComponentStartup arg component.CritThresholdBeforeModify = critThreshold.Value; EnsureComp(uid); - var amount = component.MoodThresholds[MoodThreshold.Neutral]; - SetMood(uid, amount, component, refresh: true); + RefreshMood(uid, component); } - public void SetMood(EntityUid uid, float amount, MoodComponent? component = null, bool force = false, bool refresh = false) + private void SetMood(EntityUid uid, float amount, MoodComponent? component = null, bool force = false, bool refresh = false) { if (!_config.GetCVar(CCVars.DoMoodSystem) || !Resolve(uid, ref component) - || component.CurrentMoodThreshold == MoodThreshold.Dead && !refresh - || component.CurrentMoodLevel == amount) + || component.CurrentMoodThreshold == MoodThreshold.Dead && !refresh) return; var neutral = component.MoodThresholds[MoodThreshold.Neutral]; @@ -236,18 +229,17 @@ public void SetMood(EntityUid uid, float amount, MoodComponent? component = null amount = ev.MoodChangedAmount; } + var newMoodLevel = amount + neutral; if (!force) - { - component.CurrentMoodLevel = Math.Clamp(amount, - component.MoodThresholds[MoodThreshold.Dead] + neutral, + newMoodLevel = Math.Clamp(amount + neutral, + component.MoodThresholds[MoodThreshold.Dead], component.MoodThresholds[MoodThreshold.Perfect]); - } - else - component.CurrentMoodLevel = amount + neutral; + + component.CurrentMoodLevel = newMoodLevel; if (TryComp(uid, out var mood)) { - mood.CurrentMoodLevel = amount; + mood.CurrentMoodLevel = component.CurrentMoodLevel; mood.NeutralMoodThreshold = component.MoodThresholds.GetValueOrDefault(MoodThreshold.Neutral); } diff --git a/Resources/Prototypes/Mood/generic_negativeEffects.yml b/Resources/Prototypes/Mood/generic_negativeEffects.yml index 792d18f1fe6..1f8b7098993 100644 --- a/Resources/Prototypes/Mood/generic_negativeEffects.yml +++ b/Resources/Prototypes/Mood/generic_negativeEffects.yml @@ -49,3 +49,8 @@ id: TraitSaturnine description: "Everything kind of sucks. I hate this job. " moodChange: -20 + +- type: moodEffect + id: Dead + description: "You are dead." + moodChange: -1000