Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tweak] Mood upgrade #931

Merged
merged 3 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Content.Server/Backmen/Mood/MoodComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public sealed partial class MoodComponent : Component
{
{ "HealthHeavyDamage", 0.8f },
{ "HealthSevereDamage", 0.5f },
{ "HealthOkayDamage", 0.35f },
{ "HealthLightDamage", 0.1f },
{ "HealthNoDamage", 0.05f }
};
Expand Down
19 changes: 19 additions & 0 deletions Content.Server/Backmen/Mood/MoodSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,28 @@ private void RemoveTimedOutEffect(EntityUid uid, string prototypeId, string? cat
comp.CategorisedEffects.Remove(category);
}

ReplaceMood(uid, prototypeId);
RefreshMood(uid, comp);
}

/// <summary>
/// Some moods specifically create a moodlet upon expiration. This is normally used for "Addiction" type moodlets,
/// such as a positive moodlet from an addictive substance that becomes a negative moodlet when a timer ends.
/// </summary>
/// <remarks>
/// Moodlets that use this should probably also share a category with each other, but this isn't necessarily required.
/// Only if you intend that "Re-using the drug" should also remove the negative moodlet.
/// </remarks>
private void ReplaceMood(EntityUid uid, string prototypeId)
{
if (!_prototypeManager.TryIndex<MoodEffectPrototype>(prototypeId, out var proto)
|| proto.MoodletOnEnd is null)
return;

var ev = new MoodEffectEvent(proto.MoodletOnEnd);
EntityManager.EventBus.RaiseLocalEvent(uid, ev);
}

private void OnMobStateChanged(EntityUid uid, MoodComponent component, MobStateChangedEvent args)
{
if (args.NewMobState == MobState.Dead && args.OldMobState != MobState.Dead)
Expand Down
35 changes: 35 additions & 0 deletions Content.Server/EntityEffects/Effects/ChemAddMoodlet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Content.Shared.Backmen.Mood;
using Content.Shared.EntityEffects;
using Content.Shared.Backmen.Mood;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;

namespace Content.Server.Chemistry.ReagentEffects;

/// <summary>
/// Adds a moodlet to an entity.
/// </summary>
[UsedImplicitly]
public sealed partial class ChemAddMoodlet : EntityEffect
{
protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var protoMan = IoCManager.Resolve<IPrototypeManager>();
return Loc.GetString("reagent-effect-guidebook-add-moodlet",
("amount", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).MoodChange),
("timeout", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).Timeout));
}
Comment on lines +15 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling and parameter usage

Several issues need attention:

  1. The method receives prototype parameter but resolves IPrototypeManager again via IoC
  2. Missing null checks and error handling for prototype resolution

Consider this improved implementation:

 protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
 {
-    var protoMan = IoCManager.Resolve<IPrototypeManager>();
+    if (!prototype.TryIndex<MoodEffectPrototype>(MoodPrototype.Id, out var moodEffect))
+    {
+        return Loc.GetString("reagent-effect-guidebook-add-moodlet-invalid");
+    }
     return Loc.GetString("reagent-effect-guidebook-add-moodlet",
-        ("amount", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).MoodChange),
-        ("timeout", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).Timeout));
+        ("amount", moodEffect.MoodChange),
+        ("timeout", moodEffect.Timeout));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var protoMan = IoCManager.Resolve<IPrototypeManager>();
return Loc.GetString("reagent-effect-guidebook-add-moodlet",
("amount", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).MoodChange),
("timeout", protoMan.Index<MoodEffectPrototype>(MoodPrototype.Id).Timeout));
}
protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
{
if (!prototype.TryIndex<MoodEffectPrototype>(MoodPrototype.Id, out var moodEffect))
{
return Loc.GetString("reagent-effect-guidebook-add-moodlet-invalid");
}
return Loc.GetString("reagent-effect-guidebook-add-moodlet",
("amount", moodEffect.MoodChange),
("timeout", moodEffect.Timeout));
}


public override void Effect(EntityEffectBaseArgs args)
{
var entityManager = IoCManager.Resolve<EntityManager>();
var ev = new MoodEffectEvent(MoodPrototype);
entityManager.EventBus.RaiseLocalEvent(args.TargetEntity, ev);
}
Comment on lines +23 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve dependency management and error handling

The current implementation has several areas for improvement:

  1. EntityManager should be dependency-injected rather than resolved per call
  2. Missing validation for target entity

Consider this improved implementation:

+[Dependency] private readonly IEntityManager _entityManager = default!;
+
 public override void Effect(EntityEffectBaseArgs args)
 {
-    var entityManager = IoCManager.Resolve<EntityManager>();
+    if (!_entityManager.EntityExists(args.TargetEntity))
+        return;
+
     var ev = new MoodEffectEvent(MoodPrototype);
-    entityManager.EventBus.RaiseLocalEvent(args.TargetEntity, ev);
+    _entityManager.EventBus.RaiseLocalEvent(args.TargetEntity, ev);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public override void Effect(EntityEffectBaseArgs args)
{
var entityManager = IoCManager.Resolve<EntityManager>();
var ev = new MoodEffectEvent(MoodPrototype);
entityManager.EventBus.RaiseLocalEvent(args.TargetEntity, ev);
}
[Dependency] private readonly IEntityManager _entityManager = default!;
public override void Effect(EntityEffectBaseArgs args)
{
if (!_entityManager.EntityExists(args.TargetEntity))
return;
var ev = new MoodEffectEvent(MoodPrototype);
_entityManager.EventBus.RaiseLocalEvent(args.TargetEntity, ev);
}


/// <summary>
/// The mood prototype to be applied to the using entity.
/// </summary>
[DataField(required: true)]
public ProtoId<MoodEffectPrototype> MoodPrototype = default!;
Comment on lines +30 to +34
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Mood system integration needs updates for new substances

The mood system has proper integration for nicotine and happiness with their respective benefit and withdrawal effects, but lotus oil and cosmic mirage are missing their mood effect definitions. The ChemAddMoodlet component is properly used in narcotics.yml for existing substances, suggesting a pattern to follow.

Required updates:

  • Add mood effect prototypes for lotus oil and cosmic mirage in Resources/Prototypes/_Backmen/Mood/drugs.yml
  • Add ChemAddMoodlet effects to the reagent definitions for lotus oil and cosmic mirage
🔗 Analysis chain

Verify mood system integration for substance dependencies

The field is well-defined, but let's verify its integration with the substances mentioned in the PR objectives (lotus oil, happiness, nicotine, and cosmic mirage).

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the mood system integration for chemical substances

# Check for mood effect prototypes related to the substances
echo "Checking mood effect prototypes..."
rg -l "MoodEffectPrototype" Resources/Prototypes/

# Check for ChemAddMoodlet usage in reagent definitions
echo "Checking reagent definitions..."
rg -A 5 "ChemAddMoodlet" Resources/Prototypes/Reagents/

Length of output: 1568


Script:

#!/bin/bash
# Let's verify the mood prototypes for the specific substances mentioned

# Check for mood prototypes related to lotus oil and cosmic mirage
echo "Checking for lotus oil and cosmic mirage related mood effects..."
rg -A 5 "LotusOil|CosmicMirage" Resources/Prototypes/

# Check for all mood effect definitions to understand available prototypes
echo "Checking all mood effect definitions..."
rg -A 5 "type: moodEffect" Resources/Prototypes/

# Check for lotus oil and cosmic mirage reagent definitions
echo "Checking lotus oil and cosmic mirage reagent definitions..."
rg -A 10 "id: (LotusOil|CosmicMirage)" Resources/Prototypes/Reagents/

Length of output: 17410

}
10 changes: 10 additions & 0 deletions Content.Shared/Backmen/Mood/MoodEffectPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,34 @@ public sealed class MoodEffectPrototype : IPrototype
public string ID { get; } = default!;

public string Description => Loc.GetString($"mood-effect-{ID}");

/// <summary>
/// If they already have an effect with the same category, the new one will replace the old one.
/// </summary>
[DataField, ValidatePrototypeId<MoodCategoryPrototype>]
public string? Category;

/// <summary>
/// How much should this moodlet modify an entity's Mood.
/// </summary>
[DataField(required: true)]
public float MoodChange;
Comment on lines +21 to 26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add range validation for MoodChange.

The MoodChange property should include bounds checking to prevent extreme or invalid mood values that could affect game balance.

Consider adding range validation:

     /// <summary>
     ///     How much should this moodlet modify an entity's Mood.
+    ///     Valid range is [-1.0, 1.0] where negative values represent negative moods.
     /// </summary>
     [DataField(required: true)]
+    [DataField("moodChange", required: true)]
+    [ViewVariables(VVAccess.ReadWrite)]
+    public float MoodChange
+    {
+        get => _moodChange;
+        set => _moodChange = Math.Clamp(value, -1.0f, 1.0f);
+    }
-    public float MoodChange;
+    private float _moodChange;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <summary>
/// How much should this moodlet modify an entity's Mood.
/// </summary>
[DataField(required: true)]
public float MoodChange;
/// <summary>
/// How much should this moodlet modify an entity's Mood.
/// Valid range is [-1.0, 1.0] where negative values represent negative moods.
/// </summary>
[DataField(required: true)]
[DataField("moodChange", required: true)]
[ViewVariables(VVAccess.ReadWrite)]
public float MoodChange
{
get => _moodChange;
set => _moodChange = Math.Clamp(value, -1.0f, 1.0f);
}
private float _moodChange;


/// <summary>
/// How long, in Seconds, does this moodlet last? If omitted, the moodlet will last until canceled by any system.
/// </summary>
[DataField]
public int Timeout;
Comment on lines +27 to 32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add timeout validation and fix documentation.

The Timeout property needs validation and has a documentation style issue.

Apply these changes:

     /// <summary>
-    ///     How long, in Seconds, does this moodlet last? If omitted, the moodlet will last until canceled by any system.
+    ///     How long, in seconds, does this moodlet last? If omitted or zero, the moodlet will last until canceled by any system.
     /// </summary>
     [DataField]
-    public int Timeout;
+    public int Timeout
+    {
+        get => _timeout;
+        set => _timeout = Math.Max(0, value);
+    }
+    private int _timeout;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <summary>
/// How long, in Seconds, does this moodlet last? If omitted, the moodlet will last until canceled by any system.
/// </summary>
[DataField]
public int Timeout;
/// <summary>
/// How long, in seconds, does this moodlet last? If omitted or zero, the moodlet will last until canceled by any system.
/// </summary>
[DataField]
public int Timeout
{
get => _timeout;
set => _timeout = Math.Max(0, value);
}
private int _timeout;


/// <summary>
/// Should this moodlet be hidden from the player? EG: No popups or chat messages.
/// </summary>
[DataField]
public bool Hidden;

/// <summary>
/// When not null, this moodlet will replace itself with another Moodlet upon expiration.
/// </summary>
[DataField]
public ProtoId<MoodEffectPrototype>? MoodletOnEnd;
}
7 changes: 7 additions & 0 deletions Resources/Locale/en-US/guidebook/chemistry/effects.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,10 @@ reagent-effect-guidebook-plant-seeds-remove =
[1] Removes the
*[other] remove the
} seeds of the plant

reagent-effect-guidebook-add-moodlet =
modifies mood by {$amount}
{ $timeout ->
[0] indefinitely
*[other] for {$timeout} seconds
}
Comment on lines +408 to +413
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance mood effect description and maintain consistency

The new mood effect entry should follow the same chance-based pattern as other entries and provide clearer information about the mood effect.

 reagent-effect-guidebook-add-moodlet =
-    modifies mood by {$amount}
-    { $timeout ->
-        [0] indefinitely
-        *[other] for {$timeout} seconds
-    }
+    { $chance ->
+        [1] { $amount ->
+            [>0] Improves
+            *[other] Worsens
+        }
+        *[other] { $amount ->
+            [>0] improve
+            *[other] worsen
+        }
+    } mood by {NATURALFIXED($amount, 2)} points
+    { $timeout ->
+        [0] indefinitely
+        *[other] for {NATURALFIXED($timeout, 1)} {MANY("second", $timeout)}
+    }

This refactor:

  1. Follows the chance-based pattern used throughout the file
  2. Clarifies whether it's a positive or negative mood effect
  3. Uses consistent number formatting with NATURALFIXED
  4. Adds proper pluralization for time units
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
reagent-effect-guidebook-add-moodlet =
modifies mood by {$amount}
{ $timeout ->
[0] indefinitely
*[other] for {$timeout} seconds
}
reagent-effect-guidebook-add-moodlet =
{ $chance ->
[1] { $amount ->
[>0] Improves
*[other] Worsens
}
*[other] { $amount ->
[>0] improve
*[other] worsen
}
} mood by {NATURALFIXED($amount, 2)} points
{ $timeout ->
[0] indefinitely
*[other] for {NATURALFIXED($timeout, 1)} {MANY("second", $timeout)}
}

15 changes: 14 additions & 1 deletion Resources/Locale/en-US/mood/mood.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,17 @@ mood-effect-RevolutionFocused = VIVA LA REVOLUTION!!!

mood-effect-CultFocused = Dark Gods, grant me strength!

mood-effect-TraitSanguine = I have nothing to worry about. I'm sure everything will turn out well in the end!
mood-effect-TraitSanguine = I have nothing to worry about. I'm sure everything will turn out well in the end!

# Addictions
mood-effect-LotoTranscendence =
I CAN SEE ALL THAT IS, ALL THAT WILL EVER BE, AND ALL THAT EVER WAS. ALL OF CREATION HAS OPENED TO MY MIND!
I MUST HAVE IT ALL. I MUST KNOW IT ALL. ALL OF IT. FOREVER!
mood-effect-LotoEnthrallment =
It has fled from me... The heart of all creation is gone from my soul, leaving behind an emptiness I cannot bear.
I fear that I will wither to nothing if I cannot drink from the cup of knowledge once again.

mood-effect-NicotineBenefit =
I feel as if I have been standing my entire life and I just sat down.
mood-effect-NicotineWithdrawal =
I could really go for a smoke right now.
2 changes: 2 additions & 0 deletions Resources/Locale/ru-RU/backmen/guidebook/guides.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ guide-entry-surgery = Хирургия
guide-entry-partmanipulation = Манипулирование конечностями
guide-entry-organmanipulation = Манипулирование органами
guide-entry-utilitysurgeries = Особые применения
guide-entry-special-actions = Особые действия
guide-entry-mood = Настроение
Comment on lines +19 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Missing English translations for new guide entries

The Russian translations are correctly added, but the corresponding English entries guide-entry-special-actions and guide-entry-mood are missing in the English locale file. While the guidebook prototypes and content exist, the English locale entries need to be added for consistency.

  • Add guide-entry-special-actions = Special Actions to Resources/Locale/en-US/backmen/guidebook/guides.ftl
  • Add guide-entry-mood = Mood to Resources/Locale/en-US/backmen/guidebook/guides.ftl
🔗 Analysis chain

LGTM! Verify guide content integration.

The new translations follow the established naming convention and appear to be correctly translated to Russian.

Let's verify the integration with the corresponding English locale and guide content:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the new guide entries exist in English locale and guidebook prototypes

# Check English locale for corresponding entries
echo "Checking English locale..."
rg "guide-entry-(special-actions|mood)" Resources/Locale/en-US/

# Check guidebook prototypes for corresponding entries
echo "Checking guidebook prototypes..."
rg "(?i)(special-actions|mood)" Resources/Prototypes/_Backmen/Guidebook/

Length of output: 625


Script:

#!/bin/bash
# Let's check if the English locale file exists and contains these entries
echo "Checking English locale file content..."
fd "guides.ftl" Resources/Locale/en-US/ --exec cat {}

# Also check the actual guide content file
echo -e "\nChecking mood guide content..."
fd "Mood.xml" Resources/ServerInfo/_Backmen/Guidebook/ --exec cat {}

Length of output: 7880

30 changes: 30 additions & 0 deletions Resources/Locale/ru-RU/backmen/mood/mood.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mood-effect-ThirstParched = МНЕ НУЖНА ВОДА!

mood-effect-HealthNoDamage = Я не чувствую никакой боли.
mood-effect-HealthLightDamage = Небольшая царапина, мне не так уж и больно.
mood-effect-HealthOkayDamage = Я чувствую неслабую боль.
mood-effect-HealthSevereDamage = Я не могу стерпеть эту боль!
mood-effect-HealthHeavyDamage = Агония захватывает мою душу!

Expand Down Expand Up @@ -66,3 +67,32 @@ mood-effect-SurgeryNoHand = Я не чувствую своей руки!
mood-effect-SurgeryNoTorso = Я не чувствую своего тела!

mood-effect-SurgeryPain = В моём теле проводят операцию, я чувствую сильнейшую боль!

reagent-effect-guidebook-add-moodlet =
Изменяет настроение на {$amount} единиц { $timeout ->
[0] indefinitely
*[other] на {$timeout} секунд, вызывает зависимость
}

# Addictions
mood-effect-LotoTranscendence =
Я ВИЖУ ВСЁ СУЩЕЕ, КОТОРОЕ ВСЕГДА БЫЛО И ВСЕГДА БУДЕТ. ВСЁ МИРОЗДАНИЕ ОТКРЫЛОСЬ МОЕМУ РАЗУМУ!
Я ДОЛЖЕН ЗНАТЬ ЭТО. Я ДОЛЖЕН ХРАНИТЬ ВСЁ ЭТО. ВСЁ. ВЕЧНО!
mood-effect-LotoEnthrallment =
Оно ушло от меня... Сердце всего сущего пропало из моей души, оставляя неописуемую пустоту внутри.
Чувствую словно вот-вот иссушусь если не выпью из чаши знаний снова.

mood-effect-NicotineBenefit =
Чувствую себя будто стоял всю жизнь и только что присел.
mood-effect-NicotineWithdrawal =
Стоило бы немного покурить.

mood-effect-SpaceDrugsBenefit =
Я так... Расслаблен...
mood-effect-SpaceDrugsWithdrawal =
Я снова хочу расплыться в удовольствии и окунуться в Космический Мираж!

mood-effect-HappinessBenefit =
ВУХУУУУУУ СЧААААСТЬЕЕЕЕЕЕЕЕ
mood-effect-HappinessWithdrawal =
После приступа истерики мне так грустно...
2 changes: 2 additions & 0 deletions Resources/Prototypes/Guidebook/newplayer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
text: "/ServerInfo/Guidebook/NewPlayer/Controls/Controls.xml"
children:
- Radio
- SpecialActions # backmen: laying-down & surgery
- Mood # backmen: mood

- type: guideEntry
id: Radio
Expand Down
17 changes: 17 additions & 0 deletions Resources/Prototypes/Reagents/narcotics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@
plantMetabolism:
- !type:PlantAdjustHealth
amount: -5
metabolisms:
Narcotic:
effects:
- !type:ChemAddMoodlet
moodPrototype: NicotineBenefit

# TODO: Replace these nonstandardized effects with generic brain damage
- type: reagent
Expand Down Expand Up @@ -264,6 +269,12 @@
type: Add
time: 5
refresh: false
- !type:ChemAddMoodlet
moodPrototype: SpaceDrugsBenefit
conditions:
- !type:ReagentThreshold
reagent: SpaceDrugs
min: 6

- type: reagent
id: Bananadine
Expand Down Expand Up @@ -464,3 +475,9 @@
type: Add
time: 5
refresh: false
- !type:ChemAddMoodlet
moodPrototype: HappinessBenefit
conditions:
- !type:ReagentThreshold
reagent: Happiness
min: 6
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
- type: entity
id: GuidebookMoodPerfect
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood9

- type: entity
id: GuidebookMoodExceptional
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood8

- type: entity
id: GuidebookMoodGreat
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood7

- type: entity
id: GuidebookMoodGood
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood6

- type: entity
id: GuidebookMoodNeutral
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood5

- type: entity
id: GuidebookMoodMeh
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood4

- type: entity
id: GuidebookMoodBad
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood3

- type: entity
id: GuidebookMoodTerrible
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood2

- type: entity
id: GuidebookMoodHorrible
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood1

- type: entity
id: GuidebookMoodDead
name: Mood
categories: [ HideSpawnMenu ]
components:
- type: Sprite
sprite: Interface/Alerts/mood.rsi
state: mood_happiness_bad
9 changes: 9 additions & 0 deletions Resources/Prototypes/_Backmen/Guidebook/newplayer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- type: guideEntry
id: SpecialActions
name: guide-entry-special-actions
text: "/ServerInfo/_Backmen/Guidebook/Controls/SpecialActions.xml"

- type: guideEntry
id: Mood
name: guide-entry-mood
text: "/ServerInfo/_Backmen/Guidebook/Controls/Mood.xml"
Comment on lines +6 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Documentation needs updating to cover new substance dependencies

The Mood.xml file exists but lacks specific documentation about the new substance dependencies introduced in this PR (lotus oil, happiness, nicotine, and cosmic mirage). While it mentions substance dependencies in general terms, it should be updated to include:

  • Specific information about the new substances and their mood effects
  • Details about dependency mechanics for lotus oil, happiness, nicotine, and cosmic mirage
  • Any unique characteristics or withdrawal symptoms of these substances
🔗 Analysis chain

Verify mood guide content alignment with new features

The guide entry structure is correct. Since this PR introduces significant changes to the mood system (including substance dependencies for lotus oil, happiness, nicotine, and cosmic mirage), we should verify that the referenced XML file includes comprehensive documentation of these new features.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Mood.xml file exists and contains documentation for new features
# Expected: File should exist and contain content about new mood mechanics and substance dependencies

# Search for the XML file
fd "Mood.xml" --type f

# If found, check its content for new feature documentation
fd "Mood.xml" --type f --exec cat {} \; | grep -iE "(dependency|substance|lotus|happiness|nicotine|cosmic|mirage)"

# Check for any TODO markers that might indicate incomplete documentation
fd "Mood.xml" --type f --exec grep -l "TODO" {} \;

Length of output: 250


Script:

#!/bin/bash
# Let's directly examine the content of the Mood.xml file
cat "Resources/ServerInfo/_Backmen/Guidebook/Controls/Mood.xml"

Length of output: 2298

68 changes: 68 additions & 0 deletions Resources/Prototypes/_Backmen/Mood/drugs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Drugs should be paired up in Trios of "Bonus, Penalty, Category"

# Lotophagoi Oil
- type: moodEffect
id: LotoTranscendence
moodChange: 30
timeout: 900 #15 minutes
moodletOnEnd: LotoEnthrallment
category: "LotophagoiAddiction"

- type: moodEffect
id: LotoEnthrallment
moodChange: -30
timeout: 3600 #1 hour
category: "LotophagoiAddiction"

- type: moodCategory
id: LotophagoiAddiction

Comment on lines +3 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Balance concerns with Lotophagoi Oil effects are valid and require adjustment

Comparing with other mood effects in the codebase:

  • Other drugs have significantly lower effects: Nicotine (+5/-7), Space Drugs (+15/-20), Happiness (+20/-20)
  • Standard timeouts are much shorter: 5-10 minutes for benefits, 10-20 minutes for withdrawal
  • Even severe conditions like "Heavy Damage" only cause -20 mood change

The Lotophagoi Oil's +30/-30 mood changes and 15min/1hour durations are indeed excessive and could create gameplay imbalance.

🔗 Analysis chain

Review balance of Lotophagoi Oil effects.

The mood effects for Lotophagoi Oil are significantly stronger than other substances:

  • Highest mood changes (+30/-30)
  • Longest durations (15min benefit/1hour withdrawal)
    This could lead to this substance being overpowered or the primary choice for players.

Consider:

  • Gradually increasing withdrawal effects over time
  • Implementing diminishing returns for repeated use
  • Adding additional negative side effects to balance the strong positive effect

Let me gather more information about other mood effects to compare with Lotophagoi Oil.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any gameplay balance configurations or documentation
rg -g "!*.yml" "Lotophagoi|lotus.*oil" -A 5

Length of output: 1030


Script:

#!/bin/bash
# Search for other mood effects in yml files to compare values
rg "type: moodEffect" -A 4 Resources/Prototypes/

Length of output: 16242

# Nicotine
- type: moodEffect
id: NicotineBenefit
moodChange: 5
timeout: 600 #10 minutes
moodletOnEnd: NicotineWithdrawal
category: "NicotineAddiction"

- type: moodEffect
id: NicotineWithdrawal
moodChange: -7 #No timeout
category: "NicotineAddiction"

Comment on lines +28 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Verify the missing timeout for nicotine withdrawal.

The nicotine withdrawal effect has no timeout specified, which differs from other withdrawal effects. This could result in a permanent negative mood effect.

If this is intentional, please document it explicitly. Otherwise, consider adding a timeout similar to other withdrawal effects:

 - type: moodEffect
   id: NicotineWithdrawal
   moodChange: -7 #No timeout
   category: "NicotineAddiction"
+  timeout: 1800 #30 minutes
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- type: moodEffect
id: NicotineWithdrawal
moodChange: -7 #No timeout
category: "NicotineAddiction"
- type: moodEffect
id: NicotineWithdrawal
moodChange: -7 #No timeout
category: "NicotineAddiction"
timeout: 1800 #30 minutes

- type: moodCategory
id: NicotineAddiction

# Space drugs
- type: moodEffect
id: SpaceDrugsBenefit
moodChange: 15
timeout: 480 #6 minutes
moodletOnEnd: SpaceDrugsWithdrawal
category: "SpaceDrugsAddiction"

- type: moodEffect
id: SpaceDrugsWithdrawal
moodChange: -20
category: "SpaceDrugsAddiction"
timeout: 1200 #20 minutes

- type: moodCategory
id: SpaceDrugsAddiction

# Happiness
- type: moodEffect
id: HappinessBenefit
moodChange: 20
timeout: 300 #5 minutes
moodletOnEnd: HappinessWithdrawal
category: "HappinessAddiction"

- type: moodEffect
id: HappinessWithdrawal
moodChange: -20
category: "HappinessAddiction"
timeout: 600 #10 minutes

- type: moodCategory
id: HappinessAddiction
Loading
Loading