[Fix] Mood system fix (#439)

* mood back

* fix ready
This commit is contained in:
HitPanda
2023-09-25 01:44:44 +03:00
committed by Aviu00
parent c58225fc98
commit 2cd1656188
47 changed files with 1221 additions and 7 deletions

View File

@@ -0,0 +1,37 @@
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
namespace Content.Client.White.Overlays;
public sealed class SaturationScaleOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _shader;
private const float Saturation = 0.5f;
public SaturationScaleOverlay()
{
IoCManager.InjectDependencies(this);
_shader = _prototypeManager.Index<ShaderPrototype>("SaturationScale").InstanceUnique();
}
protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture == null)
return;
_shader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
_shader.SetParameter("saturation", Saturation);
var handle = args.WorldHandle;
handle.UseShader(_shader);
handle.DrawRect(args.WorldBounds, Color.White);
handle.UseShader(null);
}
}

View File

@@ -0,0 +1,61 @@
using Content.Shared.GameTicking;
using Content.Shared.White.Overlays;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;
namespace Content.Client.White.Overlays;
public sealed class SaturationScaleSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly ILightManager _lightManager = default!;
private SaturationScaleOverlay _overlay = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SaturationScaleComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<SaturationScaleComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<SaturationScaleComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<SaturationScaleComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(RoundRestartCleanup);
_overlay = new();
}
private void RoundRestartCleanup(RoundRestartCleanupEvent ev)
{
_overlayMan.RemoveOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, SaturationScaleComponent component, PlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}
private void OnPlayerAttached(EntityUid uid, SaturationScaleComponent component, PlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnShutdown(EntityUid uid, SaturationScaleComponent component, ComponentShutdown args)
{
if (_player.LocalPlayer?.ControlledEntity == uid)
{
_overlayMan.RemoveOverlay(_overlay);
}
}
private void OnInit(EntityUid uid, SaturationScaleComponent component, ComponentInit args)
{
if (_player.LocalPlayer?.ControlledEntity == uid)
_overlayMan.AddOverlay(_overlay);
}
}

View File

@@ -2,6 +2,7 @@ using Content.Shared.Arcade;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Random; using Robust.Shared.Random;
using System.Linq; using System.Linq;
using Content.Shared.White.Mood;
namespace Content.Server.Arcade.BlockGame; namespace Content.Server.Arcade.BlockGame;
@@ -82,6 +83,10 @@ public sealed partial class BlockGame
{ {
_highScorePlacement = _arcadeSystem.RegisterHighScore(meta.EntityName, Points); _highScorePlacement = _arcadeSystem.RegisterHighScore(meta.EntityName, Points);
SendHighscoreUpdate(); SendHighscoreUpdate();
//WD start
var ev = new MoodEffectEvent("ArcadePlay");
_entityManager.EventBus.RaiseLocalEvent(meta.Owner, ev);
//WD end
} }
SendMessage(new BlockGameMessages.BlockGameGameOverScreenMessage(Points, _highScorePlacement?.LocalPlacement, _highScorePlacement?.GlobalPlacement)); SendMessage(new BlockGameMessages.BlockGameGameOverScreenMessage(Points, _highScorePlacement?.LocalPlacement, _highScorePlacement?.GlobalPlacement));
} }

View File

@@ -1,5 +1,6 @@
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Shared.White.Mood;
using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent; using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio; using Robust.Shared.Audio;
@@ -73,6 +74,9 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
if (!TryComp<ApcPowerReceiverComponent>(uid, out var power) || !power.Powered) if (!TryComp<ApcPowerReceiverComponent>(uid, out var power) || !power.Powered)
return; return;
if (msg.Session.AttachedEntity != null)
RaiseLocalEvent(msg.Session.AttachedEntity.Value, new MoodEffectEvent("ArcadePlay")); //WD edit
switch (msg.PlayerAction) switch (msg.PlayerAction)
{ {
case PlayerAction.Attack: case PlayerAction.Attack:

View File

@@ -7,6 +7,7 @@ using Content.Shared.Database;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.White.Mood;
using Robust.Shared.Containers; using Robust.Shared.Containers;
namespace Content.Server.Atmos.EntitySystems namespace Content.Server.Atmos.EntitySystems
@@ -203,6 +204,8 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage"); _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage");
} }
RaiseLocalEvent(uid, new MoodEffectEvent("MobLowPressure")); // WD edit
if (pressure <= Atmospherics.HazardLowPressure) if (pressure <= Atmospherics.HazardLowPressure)
{ {
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2); _alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2);
@@ -230,6 +233,8 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage"); _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage");
} }
RaiseLocalEvent(uid, new MoodEffectEvent("MobHighPressure")); // WD edit
if (pressure >= Atmospherics.HazardHighPressure) if (pressure >= Atmospherics.HazardHighPressure)
{ {
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2); _alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2);
@@ -247,6 +252,8 @@ namespace Content.Server.Atmos.EntitySystems
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} stopped taking pressure damage"); _adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} stopped taking pressure damage");
} }
_alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure); _alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure);
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("MobLowPressure")); // WD edit
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("MobHighPressure")); // WD edit
break; break;
} }
} }

View File

@@ -20,6 +20,9 @@ using Content.Shared.Timing;
using Content.Shared.Toggleable; using Content.Shared.Toggleable;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
using Robust.Server.Audio; using Robust.Server.Audio;
using Content.Shared.White.Mood;
using Robust.Server.GameObjects;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Systems;
@@ -371,10 +374,12 @@ namespace Content.Server.Atmos.EntitySystems
if (!flammable.OnFire) if (!flammable.OnFire)
{ {
_alertsSystem.ClearAlert(uid, AlertType.Fire); _alertsSystem.ClearAlert(uid, AlertType.Fire);
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("OnFire")); // WD edit
continue; continue;
} }
_alertsSystem.ShowAlert(uid, AlertType.Fire); _alertsSystem.ShowAlert(uid, AlertType.Fire);
RaiseLocalEvent(uid, new MoodEffectEvent("OnFire")); // WD edit
if (flammable.FireStacks > 0) if (flammable.FireStacks > 0)
{ {

View File

@@ -15,6 +15,7 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.White.Mood;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -154,6 +155,8 @@ namespace Content.Server.Bible
_audio.PlayPvs(component.HealSoundPath, args.User); _audio.PlayPvs(component.HealSoundPath, args.User);
_delay.TryResetDelay((uid, useDelay)); _delay.TryResetDelay((uid, useDelay));
} }
RaiseLocalEvent(args.Target.Value, new MoodEffectEvent("GotBlessed")); // WD edit
} }
private void AddSummonVerb(EntityUid uid, SummonableComponent component, GetVerbsEvent<AlternativeVerb> args) private void AddSummonVerb(EntityUid uid, SummonableComponent component, GetVerbsEvent<AlternativeVerb> args)

View File

@@ -21,7 +21,8 @@ using Content.Shared.Mobs; // WD
using Content.Shared.Mobs.Components; // WD using Content.Shared.Mobs.Components; // WD
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Popups; // WD using Content.Shared.Popups; // WD
using Content.Shared.White.CPR.Events; // WD using Content.Shared.White.CPR.Events;
using Content.Shared.White.Mood; // WD
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.Audio; // WD using Robust.Server.Audio; // WD
using Robust.Shared.Audio; // WD using Robust.Shared.Audio; // WD
@@ -188,6 +189,7 @@ namespace Content.Server.Body.Systems
if (respirator.SuffocationCycles >= respirator.SuffocationCycleThreshold) if (respirator.SuffocationCycles >= respirator.SuffocationCycleThreshold)
{ {
_alertsSystem.ShowAlert(uid, AlertType.LowOxygen); _alertsSystem.ShowAlert(uid, AlertType.LowOxygen);
RaiseLocalEvent(uid, new MoodEffectEvent("Suffocating")); // WD edit
} }
_damageableSys.TryChangeDamage(uid, respirator.Damage, false, false); _damageableSys.TryChangeDamage(uid, respirator.Damage, false, false);
@@ -343,6 +345,8 @@ namespace Content.Server.Body.Systems
args.Repeat = true; args.Repeat = true;
else else
component.CPRPerformedBy = null; component.CPRPerformedBy = null;
RaiseLocalEvent(args.User, new MoodEffectEvent("SavedLife"));
} }
//WD end //WD end
} }

View File

@@ -27,6 +27,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Content.Server.Objectives; using Content.Server.Objectives;
using Content.Shared.White.Mood;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;
@@ -242,6 +243,8 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
_npcFaction.RemoveFaction(entity, "NanoTrasen", false); _npcFaction.RemoveFaction(entity, "NanoTrasen", false);
_npcFaction.AddFaction(entity, "Syndicate"); _npcFaction.AddFaction(entity, "Syndicate");
RaiseLocalEvent(mind.OwnedEntity.Value, new MoodEffectEvent("TraitorFocused")); // WD edit
// Give traitors their objectives // Give traitors their objectives
if (giveObjectives) if (giveObjectives)
{ {

View File

@@ -5,6 +5,7 @@ using Content.Shared.IdentityManagement;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.White.Mood;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -58,7 +59,21 @@ public sealed class InteractionPopupSystem : EntitySystem
if (_random.Prob(component.SuccessChance)) if (_random.Prob(component.SuccessChance))
{ {
if (component.InteractSuccessString != null) if (component.InteractSuccessString != null)
{
msg = Loc.GetString(component.InteractSuccessString, ("target", Identity.Entity(uid, EntityManager))); // Success message (localized). msg = Loc.GetString(component.InteractSuccessString, ("target", Identity.Entity(uid, EntityManager))); // Success message (localized).
//WD start
if (component.InteractSuccessString == "hugging-success-generic")
{
var ev = new MoodEffectEvent("BeingHugged");
RaiseLocalEvent(uid, ev);
}
else if (component.InteractSuccessString.Contains("petting-success-"))
{
var ev = new MoodEffectEvent("PetAnimal");
RaiseLocalEvent(args.User, ev);
}
//WD end
}
if (component.InteractSuccessSound != null) if (component.InteractSuccessSound != null)
sfx = component.InteractSuccessSound; sfx = component.InteractSuccessSound;

View File

@@ -11,6 +11,8 @@ using Content.Shared.Nutrition.Components;
using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Nutrition.EntitySystems;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Robust.Server.Audio; using Robust.Server.Audio;
using Content.Shared.White.Mood;
using Robust.Server.GameObjects;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -94,6 +96,8 @@ namespace Content.Server.Medical
// Force sound to play as spill doesn't work if solution is empty. // Force sound to play as spill doesn't work if solution is empty.
_audio.PlayPvs("/Audio/Effects/Fluids/splat.ogg", uid, AudioParams.Default.WithVariation(0.2f).WithVolume(-4f)); _audio.PlayPvs("/Audio/Effects/Fluids/splat.ogg", uid, AudioParams.Default.WithVariation(0.2f).WithVolume(-4f));
_popup.PopupEntity(Loc.GetString("disease-vomit", ("person", Identity.Entity(uid, EntityManager))), uid); _popup.PopupEntity(Loc.GetString("disease-vomit", ("person", Identity.Entity(uid, EntityManager))), uid);
RaiseLocalEvent(uid, new MoodEffectEvent("MobVomit"));
} }
} }
} }

View File

@@ -0,0 +1,107 @@
using Content.Shared.Alert;
using Content.Shared.FixedPoint;
using Content.Shared.White.Mood;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
namespace Content.Server.White.Mood;
[RegisterComponent]
public sealed partial class MoodComponent : Component
{
[DataField("currentMoodLevel"), ViewVariables(VVAccess.ReadOnly)]
public float CurrentMoodLevel;
[DataField("currentMoodThreshold"), ViewVariables(VVAccess.ReadOnly)]
public MoodThreshold CurrentMoodThreshold;
[DataField("lastThreshold"), ViewVariables(VVAccess.ReadOnly)]
public MoodThreshold LastThreshold;
[ViewVariables(VVAccess.ReadOnly)]
public readonly Dictionary<string, string> CategorisedEffects = new();
[ViewVariables(VVAccess.ReadOnly)]
public readonly Dictionary<string, float> UncategorisedEffects = new();
[DataField("slowdownSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
public float SlowdownSpeedModifier = 0.75f;
[DataField("increaseSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
public float IncreaseSpeedModifier = 1.15f;
[DataField("increaseCritThreshold"), ViewVariables(VVAccess.ReadWrite)]
public float IncreaseCritThreshold = 1.2f;
[DataField("decreaseCritThreshold"), ViewVariables(VVAccess.ReadWrite)]
public float DecreaseCritThreshold = 0.9f;
[ViewVariables(VVAccess.ReadOnly)]
public FixedPoint2 CritThresholdBeforeModify;
[DataField("moodThresholds", customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, float>))]
public Dictionary<MoodThreshold, float> MoodThresholds = new()
{
{ MoodThreshold.VeryVeryGood, 10.0f },
{ MoodThreshold.VeryGood, 8.0f },
{ MoodThreshold.Good, 7.0f },
{ MoodThreshold.Great, 6.0f },
{ MoodThreshold.Neutral, 5.0f },
{ MoodThreshold.NotGreat, 4.0f },
{ MoodThreshold.Bad, 3.0f },
{ MoodThreshold.VeryBad, 2.0f },
{ MoodThreshold.VeryVeryBad, 1.0f },
{ MoodThreshold.Dead, 0.0f }
};
[DataField("moodThresholdsAlerts", customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, AlertType>))]
public Dictionary<MoodThreshold, AlertType> MoodThresholdsAlerts = new()
{
{ MoodThreshold.Dead, AlertType.MoodDead },
{ MoodThreshold.VeryVeryBad, AlertType.VeryVeryBad },
{ MoodThreshold.VeryBad, AlertType.VeryBad },
{ MoodThreshold.Bad, AlertType.Bad },
{ MoodThreshold.NotGreat, AlertType.NotGreat },
{ MoodThreshold.Neutral, AlertType.Neutral },
{ MoodThreshold.Great, AlertType.Great },
{ MoodThreshold.Good, AlertType.Good },
{ MoodThreshold.VeryGood, AlertType.VeryGood },
{ MoodThreshold.VeryVeryGood, AlertType.VeryVeryGood },
{ MoodThreshold.Insane, AlertType.Insane }
};
[DataField("moodChangeValues", customTypeSerializer: typeof(DictionarySerializer<Enum, float>))]
public Dictionary<Enum, float> MoodChangeValues = new()
{
{ MoodChangeLevel.None , 0.0f },
{ MoodChangeLevel.Small , 0.3f },
{ MoodChangeLevel.Medium , 0.7f },
{ MoodChangeLevel.Big , 1.0f },
{ MoodChangeLevel.Huge , 1.3f },
{ MoodChangeLevel.Large , 2f }
};
[DataField("healthMoodEffectsThresholds", customTypeSerializer: typeof(DictionarySerializer<string, float>))]
public Dictionary<string, float> HealthMoodEffectsThresholds = new()
{
{ "HealthHeavyDamage", 80f },
{ "HealthSevereDamage", 50f },
{ "HealthLightDamage", 10f },
{ "HealthNoDamage", 5f }
};
}
[Serializable]
public enum MoodThreshold : ushort
{
Insane = 1,
VeryVeryBad = 2,
VeryBad = 3,
Bad = 4,
NotGreat = 5,
Neutral = 6,
Great = 7,
Good = 8,
VeryGood = 9,
VeryVeryGood = 10,
Dead = 0
}

View File

@@ -0,0 +1,415 @@
using Content.Server.Chat.Managers;
using Content.Shared.Alert;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Systems;
using Content.Shared.White.Mood;
using Content.Shared.White.Overlays;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.White.Mood;
public sealed class MoodSystem : EntitySystem
{
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
[Dependency] private readonly SharedJetpackSystem _jetpack = default!;
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MoodComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<MoodComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<MoodComponent, MoodEffectEvent>(OnMoodEffect);
SubscribeLocalEvent<MoodComponent, DamageChangedEvent>(OnDamageChange);
SubscribeLocalEvent<MoodComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMoveSpeed);
SubscribeLocalEvent<MoodComponent, MoodRemoveEffectEvent>(OnRemoveEffect);
}
private void OnRemoveEffect(EntityUid uid, MoodComponent component, MoodRemoveEffectEvent args)
{
if (component.UncategorisedEffects.TryGetValue(args.EffectId, out _))
RemoveTimedOutEffect(uid, component, args.EffectId);
else
{
foreach (var (category, id) in component.CategorisedEffects)
{
if (id == args.EffectId)
{
RemoveTimedOutEffect(uid, component, args.EffectId, category);
return;
}
}
}
}
private void OnRefreshMoveSpeed(EntityUid uid, MoodComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (component.CurrentMoodThreshold is > MoodThreshold.VeryBad and < MoodThreshold.VeryGood or MoodThreshold.Dead)
return;
if (_jetpack.IsUserFlying(uid))
return;
var modifier = GetMovementThreshold(component.CurrentMoodThreshold) switch
{
-1 => component.SlowdownSpeedModifier,
1 => component.IncreaseSpeedModifier,
_ => 1
};
args.ModifySpeed(modifier, modifier);
}
private void OnMoodEffect(EntityUid uid, MoodComponent component, MoodEffectEvent args)
{
if (!_prototypeManager.TryIndex<MoodEffectPrototype>(args.EffectId, out var prototype))
return;
ApplyEffect(uid, component, prototype);
}
private void ApplyEffect(EntityUid uid, MoodComponent component, MoodEffectPrototype prototype)
{
var amount = component.CurrentMoodLevel;
if (!component.MoodChangeValues.TryGetValue(prototype.MoodChange, out var value))
return;
//Apply categorised effect
if (prototype.Category != null)
{
if (component.CategorisedEffects.TryGetValue(prototype.Category, out var oldPrototypeId))
{
if (!_prototypeManager.TryIndex<MoodEffectPrototype>(oldPrototypeId, out var oldPrototype))
return;
if (prototype.ID != oldPrototype.ID)
{
if (!component.MoodChangeValues.TryGetValue(oldPrototype.MoodChange, out var oldValue))
return;
amount += (oldPrototype.PositiveEffect ? -oldValue : oldValue) + (prototype.PositiveEffect ? value : -value);
component.CategorisedEffects[prototype.Category] = prototype.ID;
}
}
else
{
component.CategorisedEffects.Add(prototype.Category, prototype.ID);
amount += prototype.PositiveEffect ? value : -value;
}
if (prototype.Timeout != 0)
Timer.Spawn(TimeSpan.FromMinutes(prototype.Timeout), () => RemoveTimedOutEffect(uid, component, prototype.ID, prototype.Category));
}
//Apply uncategorised effect
else
{
if (component.UncategorisedEffects.TryGetValue(prototype.ID, out _))
return;
var effectValue = prototype.PositiveEffect ? value : -value;
component.UncategorisedEffects.Add(prototype.ID, effectValue);
amount += effectValue;
if (prototype.Timeout != 0)
Timer.Spawn(TimeSpan.FromMinutes(prototype.Timeout), () => RemoveTimedOutEffect(uid, component, prototype.ID));
}
SetMood(uid, amount, component);
}
private void RemoveTimedOutEffect(EntityUid uid, MoodComponent comp, string prototypeId, string? category = null)
{
var amount = comp.CurrentMoodLevel;
if (category == null)
{
if (!comp.UncategorisedEffects.TryGetValue(prototypeId, out var value))
return;
amount += -value;
comp.UncategorisedEffects.Remove(prototypeId);
}
else
{
if (!comp.CategorisedEffects.TryGetValue(category, out var currentProtoId))
return;
if (currentProtoId != prototypeId)
return;
if (!_prototypeManager.TryIndex<MoodEffectPrototype>(currentProtoId, out var currentProto))
return;
if (!comp.MoodChangeValues.TryGetValue(currentProto.MoodChange, out var value))
return;
amount += currentProto.PositiveEffect ? -value : value;
comp.CategorisedEffects.Remove(category);
}
SetMood(uid, amount, 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);
}
else if (args.OldMobState == MobState.Dead && args.NewMobState != MobState.Dead)
{
ReapplyAllEffects(uid, component);
}
}
private void ReapplyAllEffects(EntityUid uid, MoodComponent component)
{
var amount = component.MoodThresholds[MoodThreshold.Neutral];
foreach (var (_, protoId) in component.CategorisedEffects)
{
if (!_prototypeManager.TryIndex<MoodEffectPrototype>(protoId, out var prototype))
return;
if (!component.MoodChangeValues.TryGetValue(prototype.MoodChange, out var value))
return;
amount += prototype.PositiveEffect ? value : -value;
}
foreach (var (_, value) in component.UncategorisedEffects)
{
amount += value;
}
SetMood(uid, amount, component, refresh: true);
}
private void OnInit(EntityUid uid, MoodComponent component, ComponentInit args)
{
_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var critThreshold);
if (critThreshold != null)
component.CritThresholdBeforeModify = critThreshold.Value;
var amount = component.MoodThresholds[MoodThreshold.Neutral];
SetMood(uid, amount, component, refresh: true);
}
public void SetMood(EntityUid uid, float amount, MoodComponent? component = null, bool force = false, bool refresh = false)
{
if (!Resolve(uid, ref component))
return;
if (component.CurrentMoodThreshold == MoodThreshold.Dead && !refresh)
return;
if (!force)
{
component.CurrentMoodLevel = Math.Clamp(amount,
component.MoodThresholds[MoodThreshold.Dead] + 0.1f,
component.MoodThresholds[MoodThreshold.VeryVeryGood]);
}
else
{
component.CurrentMoodLevel = amount;
}
UpdateCurrentThreshold(uid, component);
}
private void UpdateCurrentThreshold(EntityUid uid, MoodComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
var calculatedThreshold = GetMoodThreshold(component);
if (calculatedThreshold == component.CurrentMoodThreshold)
return;
component.CurrentMoodThreshold = calculatedThreshold;
DoMoodThresholdsEffects(uid, component);
}
private void DoMoodThresholdsEffects(EntityUid uid, MoodComponent? component = null, bool force = false)
{
if (!Resolve(uid, ref component))
return;
if (component.CurrentMoodThreshold == component.LastThreshold && !force)
return;
var modifier = GetMovementThreshold(component.CurrentMoodThreshold);
// Modify mob stats
if (modifier != GetMovementThreshold(component.LastThreshold))
{
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
SetCritThreshold(uid, component, modifier);
RefreshShaders(uid, modifier);
}
// Modify interface
if (component.MoodThresholdsAlerts.TryGetValue(component.CurrentMoodThreshold, out var alertId))
{
_alerts.ShowAlert(uid, alertId);
}
else
{
_alerts.ClearAlertCategory(uid, AlertCategory.Mood);
}
component.LastThreshold = component.CurrentMoodThreshold;
}
private void RefreshShaders(EntityUid uid, int modifier)
{
if (modifier == -1)
{
EnsureComp<SaturationScaleComponent>(uid);
}
else
{
RemComp<SaturationScaleComponent>(uid);
}
}
private void SetCritThreshold(EntityUid uid, MoodComponent component, int modifier)
{
if (!TryComp<MobThresholdsComponent>(uid, out var mobThresholds))
return;
if (!_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var key))
return;
var newKey = modifier switch
{
1 => FixedPoint2.New(key.Value.Float() * component.IncreaseCritThreshold),
-1 => FixedPoint2.New(key.Value.Float() * component.DecreaseCritThreshold),
_ => component.CritThresholdBeforeModify
};
component.CritThresholdBeforeModify = key.Value;
_mobThreshold.SetMobStateThreshold(uid, newKey, MobState.Critical, mobThresholds);
}
private MoodThreshold GetMoodThreshold(MoodComponent component, float? moodLevel = null)
{
moodLevel ??= component.CurrentMoodLevel;
var result = MoodThreshold.Dead;
var value = component.MoodThresholds[MoodThreshold.VeryVeryGood];
foreach (var threshold in component.MoodThresholds)
{
if (threshold.Value <= value && threshold.Value >= moodLevel)
{
result = threshold.Key;
value = threshold.Value;
}
}
return result;
}
private int GetMovementThreshold(MoodThreshold threshold)
{
return threshold switch
{
>= MoodThreshold.VeryGood => 1,
<= MoodThreshold.VeryBad => -1,
_ => 0
};
}
#region HealthStatusCheck
private void OnDamageChange(EntityUid uid, MoodComponent component, DamageChangedEvent args)
{
var damage = args.Damageable.TotalDamage.Float();
var protoId = "HealthNoDamage";
var value = component.HealthMoodEffectsThresholds["HealthNoDamage"];
foreach (var threshold in component.HealthMoodEffectsThresholds)
{
if (threshold.Value <= damage && threshold.Value >= value)
{
protoId = threshold.Key;
value = threshold.Value;
}
}
var ev = new MoodEffectEvent(protoId);
RaiseLocalEvent(uid, ev);
}
#endregion
}
[UsedImplicitly]
[DataDefinition]
public sealed partial class ShowMoodEffects : IAlertClick
{
public void AlertClicked(EntityUid uid)
{
var entityManager = IoCManager.Resolve<IEntityManager>();
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
var chatManager = IoCManager.Resolve<IChatManager>();
if (!entityManager.TryGetComponent<MoodComponent>(uid, out var comp))
return;
if (comp.CurrentMoodThreshold == MoodThreshold.Dead)
return;
if (!entityManager.TryGetComponent<ActorComponent>(uid, out var actorComp))
return;
var msgStart = Loc.GetString("mood-show-effects-start");
chatManager.ChatMessageToOne(ChatChannel.Emotes, msgStart, msgStart, EntityUid.Invalid, false,
actorComp.PlayerSession.ConnectedClient);
foreach (var (_, protoId) in comp.CategorisedEffects)
{
if (!prototypeManager.TryIndex<MoodEffectPrototype>(protoId, out var proto))
continue;
if (proto.Hidden)
continue;
SendDescToChat(proto, actorComp);
}
foreach (var (protoId, _) in comp.UncategorisedEffects)
{
if (!prototypeManager.TryIndex<MoodEffectPrototype>(protoId, out var proto))
continue;
if (proto.Hidden)
continue;
SendDescToChat(proto, actorComp);
}
}
private void SendDescToChat(MoodEffectPrototype proto, ActorComponent comp)
{
var chatManager = IoCManager.Resolve<IChatManager>();
var color = proto.PositiveEffect ? "#008000" : "#BA0000";
var msg = $"[font size=10][color={color}]{proto.Description}[/color][/font]";
chatManager.ChatMessageToOne(ChatChannel.Emotes, msg, msg, EntityUid.Invalid, false,
comp.PlayerSession.ConnectedClient);
}
}

View File

@@ -10,6 +10,7 @@ public enum AlertCategory
Breathing, Breathing,
Buckled, Buckled,
Health, Health,
Mood, //WD-edit
Internals, Internals,
Stamina, Stamina,
Piloting, Piloting,

View File

@@ -25,6 +25,20 @@ namespace Content.Shared.Alert
Bleeding, Bleeding,
BorgBattery, BorgBattery,
BorgBatteryNone, BorgBatteryNone,
//WD start
Insane,
VeryVeryBad,
VeryBad,
Bad,
NotGreat,
Neutral,
Great,
Good,
VeryGood,
VeryVeryGood,
MoodDead,
//WD end
CultBuffed,
PilotingShuttle, PilotingShuttle,
Peckish, Peckish,
Starving, Starving,

View File

@@ -30,6 +30,7 @@ using Content.Shared.Verbs;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Content.Shared.White.EndOfRoundStats.CuffedTime; using Content.Shared.White.EndOfRoundStats.CuffedTime;
using Content.Shared.White.Mood;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -172,9 +173,15 @@ namespace Content.Shared.Cuffs
_actionBlocker.UpdateCanMove(uid); _actionBlocker.UpdateCanMove(uid);
if (component.CanStillInteract) if (component.CanStillInteract)
{
_alerts.ClearAlert(uid, AlertType.Handcuffed); _alerts.ClearAlert(uid, AlertType.Handcuffed);
RaiseLocalEvent(uid, new MoodRemoveEffectEvent("Handcuffed")); //WD edit
}
else else
{
_alerts.ShowAlert(uid, AlertType.Handcuffed); _alerts.ShowAlert(uid, AlertType.Handcuffed);
RaiseLocalEvent(uid, new MoodEffectEvent("Handcuffed")); // WD edit
}
var ev = new CuffedStateChangeEvent(); var ev = new CuffedStateChangeEvent();
RaiseLocalEvent(uid, ref ev); RaiseLocalEvent(uid, ref ev);

View File

@@ -4,6 +4,9 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.Components;
using Content.Shared.Rejuvenate; using Content.Shared.Rejuvenate;
using Content.Shared.White.Mood;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -18,6 +21,7 @@ public sealed class HungerSystem : EntitySystem
[Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
[Dependency] private readonly SharedJetpackSystem _jetpack = default!; [Dependency] private readonly SharedJetpackSystem _jetpack = default!;
[Dependency] private readonly INetManager _net = default!; // WD edit
public override void Initialize() public override void Initialize()
{ {
@@ -26,7 +30,7 @@ public sealed class HungerSystem : EntitySystem
SubscribeLocalEvent<HungerComponent, EntityUnpausedEvent>(OnUnpaused); SubscribeLocalEvent<HungerComponent, EntityUnpausedEvent>(OnUnpaused);
SubscribeLocalEvent<HungerComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<HungerComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<HungerComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<HungerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<HungerComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); //SubscribeLocalEvent<HungerComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); WD-edit
SubscribeLocalEvent<HungerComponent, RejuvenateEvent>(OnRejuvenate); SubscribeLocalEvent<HungerComponent, RejuvenateEvent>(OnRejuvenate);
} }
@@ -115,10 +119,18 @@ public sealed class HungerSystem : EntitySystem
if (component.CurrentThreshold == component.LastThreshold && !force) if (component.CurrentThreshold == component.LastThreshold && !force)
return; return;
if (GetMovementThreshold(component.CurrentThreshold) != GetMovementThreshold(component.LastThreshold)) //WD start
if (_net.IsServer)
{
var ev = new MoodEffectEvent("Hunger" + component.CurrentThreshold);
RaiseLocalEvent(uid, ev);
}
/*if (GetMovementThreshold(component.CurrentThreshold) != GetMovementThreshold(component.LastThreshold))
{ {
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid); _movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
} }*/
//WD end
if (component.HungerThresholdAlerts.TryGetValue(component.CurrentThreshold, out var alertId)) if (component.HungerThresholdAlerts.TryGetValue(component.CurrentThreshold, out var alertId))
{ {

View File

@@ -1,6 +1,7 @@
using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.Components;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using Content.Shared.White.Mood;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Content.Shared.Nutrition.EntitySystems namespace Content.Shared.Nutrition.EntitySystems
@@ -44,6 +45,8 @@ namespace Content.Shared.Nutrition.EntitySystems
{ {
_appearance.SetData(uid, CreamPiedVisuals.Creamed, value, appearance); _appearance.SetData(uid, CreamPiedVisuals.Creamed, value, appearance);
} }
RaiseLocalEvent(uid, new MoodEffectEvent("Creampied")); // WD edit
} }
private void OnCreamPieLand(EntityUid uid, CreamPieComponent component, ref LandEvent args) private void OnCreamPieLand(EntityUid uid, CreamPieComponent component, ref LandEvent args)

View File

@@ -6,6 +6,11 @@ using Content.Shared.Rejuvenate;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Content.Shared.Movement.Components;
using Content.Shared.Alert;
using Content.Shared.Movement.Systems;
using Content.Shared.Rejuvenate;
using Content.Shared.White.Mood;
namespace Content.Shared.Nutrition.EntitySystems; namespace Content.Shared.Nutrition.EntitySystems;
@@ -26,7 +31,7 @@ public sealed class ThirstSystem : EntitySystem
_sawmill = Logger.GetSawmill("thirst"); _sawmill = Logger.GetSawmill("thirst");
SubscribeLocalEvent<ThirstComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); //SubscribeLocalEvent<ThirstComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); WD-edit
SubscribeLocalEvent<ThirstComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<ThirstComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ThirstComponent, RejuvenateEvent>(OnRejuvenate); SubscribeLocalEvent<ThirstComponent, RejuvenateEvent>(OnRejuvenate);
SubscribeLocalEvent<ThirstComponent, EntityUnpausedEvent>(OnUnpaused); SubscribeLocalEvent<ThirstComponent, EntityUnpausedEvent>(OnUnpaused);
@@ -114,11 +119,13 @@ public sealed class ThirstSystem : EntitySystem
private void UpdateEffects(EntityUid uid, ThirstComponent component) private void UpdateEffects(EntityUid uid, ThirstComponent component)
{ {
if (IsMovementThreshold(component.LastThirstThreshold) != IsMovementThreshold(component.CurrentThirstThreshold) && //WD start
/*if (IsMovementThreshold(component.LastThirstThreshold) != IsMovementThreshold(component.CurrentThirstThreshold) &&
TryComp(uid, out MovementSpeedModifierComponent? movementSlowdownComponent)) TryComp(uid, out MovementSpeedModifierComponent? movementSlowdownComponent))
{ {
_movement.RefreshMovementSpeedModifiers(uid, movementSlowdownComponent); _movement.RefreshMovementSpeedModifiers(uid, movementSlowdownComponent);
} }*/
//WD end
// Update UI // Update UI
if (ThirstComponent.ThirstThresholdAlertTypes.TryGetValue(component.CurrentThirstThreshold, out var alertId)) if (ThirstComponent.ThirstThresholdAlertTypes.TryGetValue(component.CurrentThirstThreshold, out var alertId))
@@ -130,6 +137,11 @@ public sealed class ThirstSystem : EntitySystem
_alerts.ClearAlertCategory(uid, AlertCategory.Thirst); _alerts.ClearAlertCategory(uid, AlertCategory.Thirst);
} }
//WD start
var ev = new MoodEffectEvent("Thirst" + component.CurrentThirstThreshold);
RaiseLocalEvent(uid, ev);
//WD end
switch (component.CurrentThirstThreshold) switch (component.CurrentThirstThreshold)
{ {
case ThirstThreshold.OverHydrated: case ThirstThreshold.OverHydrated:

View File

@@ -3,6 +3,7 @@ using Content.Shared.Mindshield.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Revolutionary.Components; using Content.Shared.Revolutionary.Components;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.White.Mood;
namespace Content.Shared.Revolutionary; namespace Content.Shared.Revolutionary;
@@ -15,8 +16,22 @@ public sealed class SharedRevolutionarySystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<MindShieldComponent, MapInitEvent>(MindShieldImplanted); SubscribeLocalEvent<MindShieldComponent, MapInitEvent>(MindShieldImplanted);
SubscribeLocalEvent<RevolutionaryComponent, ComponentInit>(OnInit); // WD EDIT
SubscribeLocalEvent<RevolutionaryComponent, ComponentShutdown>(OnShutdown); // WD EDIT
} }
// WD START
private void OnShutdown(Entity<RevolutionaryComponent> ent, ref ComponentShutdown args)
{
RaiseLocalEvent(ent, new MoodRemoveEffectEvent("RevolutionFocused"));
}
private void OnInit(Entity<RevolutionaryComponent> ent, ref ComponentInit args)
{
RaiseLocalEvent(ent, new MoodEffectEvent("RevolutionFocused"));
}
// WD END
/// <summary> /// <summary>
/// When the mindshield is implanted in the rev it will popup saying they were deconverted. In Head Revs it will remove the mindshield component. /// When the mindshield is implanted in the rev it will popup saying they were deconverted. In Head Revs it will remove the mindshield component.
/// </summary> /// </summary>

View File

@@ -4,6 +4,7 @@ using Content.Shared.Inventory;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Content.Shared.StepTrigger.Systems; using Content.Shared.StepTrigger.Systems;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.White.Mood;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
@@ -78,6 +79,8 @@ public sealed class SlipperySystem : EntitySystem
_stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true); _stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true);
RaiseLocalEvent(other, new MoodEffectEvent("MobSlipped")); // WD edit
// Preventing from playing the slip sound when you are already knocked down. // Preventing from playing the slip sound when you are already knocked down.
if (playSound) if (playSound)
{ {

View File

@@ -0,0 +1,31 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Shared.White.Mood;
[Prototype("moodEffect")]
public sealed class MoodEffectPrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; } = default!;
[DataField("desc", required: true)]
public string Description = string.Empty;
[DataField("moodChange", customTypeSerializer: typeof(EnumSerializer), required: true)]
public Enum MoodChange = default!;
[DataField("positiveEffect", required: true)]
public bool PositiveEffect;
[DataField("timeout")]
public int Timeout;
[DataField("hidden")]
public bool Hidden;
//If mob already has effect of the same category, the new one will replace the old one.
[DataField("category")]
public string? Category;
}

View File

@@ -0,0 +1,36 @@
using Robust.Shared.Serialization;
namespace Content.Shared.White.Mood;
[Serializable, NetSerializable]
public enum MoodChangeLevel : byte
{
None,
Small,
Medium,
Big,
Huge,
Large
}
[Serializable, NetSerializable]
public sealed partial class MoodEffectEvent : EntityEventArgs
{
public string EffectId;
public MoodEffectEvent(string effectId)
{
EffectId = effectId;
}
}
[Serializable, NetSerializable]
public sealed partial class MoodRemoveEffectEvent : EntityEventArgs
{
public string EffectId;
public MoodRemoveEffectEvent(string effectId)
{
EffectId = effectId;
}
}

View File

@@ -0,0 +1,8 @@
using Robust.Shared.GameStates;
namespace Content.Shared.White.Overlays;
[RegisterComponent, NetworkedComponent]
public sealed partial class SaturationScaleComponent : Component
{
}

View File

@@ -0,0 +1,22 @@
alerts-mood-insane-name = Безумие
alerts-mood-insane-desc = В моей душе тлеют мрак и безнадежность, мир обречен на абсолютное зло.
alerts-mood-very-very-bad-name = Печально
alerts-mood-very-very-bad-desc = Я борюсь с болями и страхами, моя судьба - череда мучений и страданий.
alerts-mood-very-bad-name = Очень плохо
alerts-mood-very-bad-desc = Моя жизнь иссякла, как кровь из раны, и вокруг лишь мрак и отчаяние.
alerts-mood-bad-name = Плохо
alerts-mood-bad-desc = Силы покидают меня, и каждый день становится тяжелым испытанием.
alerts-mood-not-great-name = Нехорошо
alerts-mood-not-great-desc = Мир полон угроз и боли, и мои надежды медленно умирают.
alerts-mood-neutral-name = Нормально
alerts-mood-neutral-desc = Я продолжаю свой путь, несмотря на угрозы и лишения, ища хоть малейший свет во мраке.
alerts-mood-great-name = Неплохо
alerts-mood-great-desc = В этом мире полном страданий, я обретаю небольшое облегчение и надежду.
alerts-mood-good-name = Хорошо
alerts-mood-good-desc = Моя сила восстанавливается, и мир кажется меньшим злом и болью.
alerts-mood-very-good-name = Очень хорошо
alerts-mood-very-good-desc = Я ощущаю в себе силы и надежду на лучшие дни, несмотря на угрозы, что таятся вокруг.
alerts-mood-very-very-good-name = Великолепно
alerts-mood-very-very-good-desc = Моя душа полна света и силы, и я готов сразиться с тьмой в этом жестоком мире.
alerts-mood-dead-name = Мёртв
alerts-mood-dead-desc = Вечная пустота окутала меня, и мир больше не имеет власти над моей душой.

View File

@@ -0,0 +1 @@
mood-show-effects-start = [font size=12]Настроение:[/font]

View File

@@ -6,6 +6,7 @@
order: order:
- category: Health - category: Health
- alertType: Bleeding - alertType: Bleeding
- category: Mood # WD edit
- category: Stamina - category: Stamina
- alertType: SuitPower - alertType: SuitPower
- category: Internals - category: Internals

View File

@@ -234,6 +234,7 @@
- type: ExaminableClothes - type: ExaminableClothes
- type: CharacterInformation - type: CharacterInformation
- type: Penetrated - type: Penetrated
- type: Mood
- type: entity - type: entity
save: false save: false

View File

@@ -99,3 +99,8 @@
id: Cataracts id: Cataracts
kind: source kind: source
path: "/Textures/Shaders/cataracts.swsl" path: "/Textures/Shaders/cataracts.swsl"
- type: shader
id: SaturationScale
kind: source
path: "/Textures/Shaders/White/saturationscale.swsl"

View File

@@ -0,0 +1,110 @@
# Moods
- type: alert
id: Insane
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood_insane
name: alerts-mood-insane-name
description: alerts-mood-insane-desc
- type: alert
id: VeryVeryBad
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood1
name: alerts-mood-very-very-bad-name
description: alerts-mood-very-very-bad-desc
- type: alert
id: VeryBad
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood2
name: alerts-mood-very-bad-name
description: alerts-mood-very-bad-desc
- type: alert
id: Bad
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood3
name: alerts-mood-bad-name
description: alerts-mood-bad-desc
- type: alert
id: NotGreat
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood4
name: alerts-mood-not-great-name
description: alerts-mood-not-great-desc
- type: alert
id: Neutral
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood5
name: alerts-mood-neutral-name
description: alerts-mood-neutral-desc
- type: alert
id: Great
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood6
name: alerts-mood-great-name
description: alerts-mood-great-desc
- type: alert
id: Good
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood7
name: alerts-mood-good-name
description: alerts-mood-good-desc
- type: alert
id: VeryGood
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood8
name: alerts-mood-very-good-name
description: alerts-mood-very-good-desc
- type: alert
id: VeryVeryGood
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood9
name: alerts-mood-very-very-good-name
description: alerts-mood-very-very-good-desc
- type: alert
id: MoodDead
category: Mood
onClick: !type:ShowMoodEffects { }
icons:
- sprite: /Textures/White/Interface/Alerts/mood.rsi
state: mood_happiness_bad
name: alerts-mood-dead-name
description: alerts-mood-dead-desc

View File

@@ -0,0 +1,51 @@
- type: moodEffect
id: Handcuffed
desc: "Кажется мои выходки кто-то заметил."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
- type: moodEffect
id: Suffocating
desc: "НЕ.. МОГУ... ДЫШАТЬ..."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
timeout: 1
- type: moodEffect
id: OnFire
desc: "ГОРЮ!!!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
- type: moodEffect
id: Creampied
desc: "Меня окремили. На вкус как пирог."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 3
- type: moodEffect
id: MobSlipped
desc: "Опять поскальзываюсь. Надо быть аккуратней."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 3
- type: moodEffect
id: MobVomit
desc: "Меня только что вырвало. Мерзость."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 8
- type: moodEffect
id: MobLowPressure
desc: "Меня сейчас разорвёт наружу!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
- type: moodEffect
id: MobHighPressure
desc: "На меня оказывается огромное давление!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false

View File

@@ -0,0 +1,52 @@
- type: moodEffect
id: BeingHugged
desc: "Обнимашки - круто."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
timeout: 2
- type: moodEffect
id: ArcadePlay
desc: "Я весело поиграл в интересную аркаду."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
timeout: 8
- type: moodEffect
id: GotBlessed
desc: "Меня благословили."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
timeout: 8
- type: moodEffect
id: PetAnimal
desc: "Животные такие милые! Не могу перестать их гладить!"
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
timeout: 5
- type: moodEffect
id: SavedLife
desc: "Так приятно спасать чью-то жизнь."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
timeout: 8
- type: moodEffect
id: TraitorFocused #Used for traitors to boost their goals completion.
desc: "У меня есть цель, и я добьюсь её, во что бы то ни стало!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
- type: moodEffect
id: RevolutionFocused #Used for revolution
desc: "СЛАВА РЕВОЛЮЦИИ!!!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
- type: moodEffect
id: CultFocused
desc: "Знаю правду, славим великого!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: true

View File

@@ -0,0 +1,87 @@
#Hunger
- type: moodEffect
id: HungerOverfed
desc: "Во мне столько жира..."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Hunger"
- type: moodEffect
id: HungerOkay
desc: "Мой желудок полон!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
category: "Hunger"
- type: moodEffect
id: HungerPeckish
desc: "Хочу есть."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
category: "Hunger"
- type: moodEffect
id: HungerStarving
desc: "Голодаю!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
category: "Hunger"
#Thirst
- type: moodEffect
id: ThirstOverHydrated
desc: "СЛИШКОМ МНОГО ВОДЫ..."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Thirst"
- type: moodEffect
id: ThirstOkay
desc: "Не хочу пить."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
category: "Thirst"
- type: moodEffect
id: ThirstThirsty
desc: "Хочу пить."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
category: "Thirst"
- type: moodEffect
id: ThirstParched
desc: "ВОДЫ!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
category: "Thirst"
#Health
- type: moodEffect
id: HealthNoDamage
desc: "Чувствую себя лишённым боли."
moodChange: enum.MoodChangeLevel.None
positiveEffect: true
hidden: true
category: "Health"
- type: moodEffect
id: HealthLightDamage
desc: "Мои ссадины жгутся."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Health"
- type: moodEffect
id: HealthSevereDamage
desc: "Сильная боль пронзает меня."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
category: "Health"
- type: moodEffect
id: HealthHeavyDamage
desc: "Агония гложет мою душу!"
moodChange: enum.MoodChangeLevel.Large
positiveEffect: false
category: "Health"

View File

@@ -0,0 +1,12 @@
uniform highp float saturation; // Between 0 and 2;
uniform sampler2D SCREEN_TEXTURE;
void fragment() {
highp vec4 color = texture(SCREEN_TEXTURE, UV);
highp float brightness = (color.r + color.g + color.b) / 3.0;
color.rgb = mix(vec3(brightness), color.rgb, saturation);
COLOR = color;
}

View File

@@ -0,0 +1,60 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from NSV13 at b6b1e2bf2cc60455851317d8e82cca8716d9dac1",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "mood1"
},
{
"name": "mood2"
},
{
"name": "mood3"
},
{
"name": "mood4"
},
{
"name": "mood5"
},
{
"name": "mood6"
},
{
"name": "mood7"
},
{
"name": "mood8"
},
{
"name": "mood9"
},
{
"name": "mood_insane",
"delays": [
[
0.07,
0.07,
0.07,
0.07,
0.07,
0.07,
0.07,
0.07,
0.07
]
]
},
{
"name": "mood_happiness_good"
},
{
"name": "mood_happiness_bad"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB