diff --git a/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs b/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs index 37606d8656..4d50d91e16 100644 --- a/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs +++ b/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs @@ -66,7 +66,7 @@ private RadialMenu FormMenu() var mainContainer = new RadialContainer { - Radius = 36f / MathF.Sin(MathF.PI / crafting.Prototypes.Count) + Radius = 36f / MathF.Sin(MathF.PI / 2f / crafting.Prototypes.Count) }; foreach (var protoId in crafting.Prototypes) diff --git a/Content.Server/Chemistry/ReagentEffects/ChemAddMoodlet.cs b/Content.Server/Chemistry/ReagentEffects/ChemAddMoodlet.cs new file mode 100644 index 0000000000..f5bb629299 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/ChemAddMoodlet.cs @@ -0,0 +1,34 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Mood; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; + +namespace Content.Server.Chemistry.ReagentEffects; + +/// +/// Adds a moodlet to an entity. +/// +[UsedImplicitly] +public sealed partial class ChemAddMoodlet : ReagentEffect +{ + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + var protoMan = IoCManager.Resolve(); + return Loc.GetString("reagent-effect-guidebook-add-moodlet", + ("amount", protoMan.Index(MoodPrototype.Id).MoodChange), + ("timeout", protoMan.Index(MoodPrototype.Id).Timeout)); + } + + /// + /// The mood prototype to be applied to the using entity. + /// + [DataField(required: true)] + public ProtoId MoodPrototype = default!; + + public override void Effect(ReagentEffectArgs args) + { + var entityManager = IoCManager.Resolve(); + var ev = new MoodEffectEvent(MoodPrototype); + entityManager.EventBus.RaiseLocalEvent(args.SolutionEntity, ev); + } +} diff --git a/Content.Server/Mood/MoodSystem.cs b/Content.Server/Mood/MoodSystem.cs index f2dc87ffd6..7e4789bf14 100644 --- a/Content.Server/Mood/MoodSystem.cs +++ b/Content.Server/Mood/MoodSystem.cs @@ -53,8 +53,6 @@ public override void Initialize() SubscribeLocalEvent(OnDamageChange); SubscribeLocalEvent(OnRefreshMoveSpeed); SubscribeLocalEvent(OnRemoveEffect); - - SubscribeLocalEvent(OnTraitStartup); } private void OnShutdown(EntityUid uid, MoodComponent component, ComponentShutdown args) @@ -101,15 +99,6 @@ private void OnRefreshMoveSpeed(EntityUid uid, MoodComponent component, RefreshM args.ModifySpeed(1, modifier); } - private void OnTraitStartup(EntityUid uid, MoodModifyTraitComponent component, ComponentStartup args) - { - if (_debugMode - || component.MoodId is null) - return; - - RaiseLocalEvent(uid, new MoodEffectEvent($"{component.MoodId}")); - } - private void OnMoodEffect(EntityUid uid, MoodComponent component, MoodEffectEvent args) { if (_debugMode @@ -195,9 +184,28 @@ private void RemoveTimedOutEffect(EntityUid uid, string prototypeId, string? cat comp.CategorisedEffects.Remove(category); } + ReplaceMood(uid, prototypeId); RefreshMood(uid, comp); } + /// + /// 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. + /// + /// + /// 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. + /// + private void ReplaceMood(EntityUid uid, string prototypeId) + { + if (!_prototypeManager.TryIndex(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 (_debugMode) diff --git a/Content.Server/Power/Components/ActiveChargerComponent.cs b/Content.Server/Power/Components/ActiveChargerComponent.cs new file mode 100644 index 0000000000..9f75db853d --- /dev/null +++ b/Content.Server/Power/Components/ActiveChargerComponent.cs @@ -0,0 +1,7 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Power; + +namespace Content.Server.Power.Components; + +[RegisterComponent] +public sealed partial class ActiveChargerComponent : Component { } diff --git a/Content.Server/Power/Components/ChargingComponent.cs b/Content.Server/Power/Components/ChargingComponent.cs deleted file mode 100644 index db7c14f708..0000000000 --- a/Content.Server/Power/Components/ChargingComponent.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Power; - -namespace Content.Server.Power.Components -{ - [RegisterComponent] - public sealed partial class ChargingComponent : Component - { - /// - ///References the entity of the charger that is currently powering this battery - /// - public EntityUid ChargerUid; - - /// - ///References the component of the charger that is currently powering this battery - /// - public ChargerComponent ChargerComponent; - } -} diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs index 1c5d83b094..cbe61f6671 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -21,7 +21,6 @@ public override void Initialize() SubscribeLocalEvent(OnBatteryRejuvenate); SubscribeLocalEvent(CalculateBatteryPrice); SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); SubscribeLocalEvent(PreSync); SubscribeLocalEvent(PostSync); @@ -106,17 +105,6 @@ private void OnEmpPulse(EntityUid uid, BatteryComponent component, ref EmpPulseE UseCharge(uid, args.EnergyConsumption, component); } - // if a disabled battery is put into a recharged, - // allow the recharger to start recharging again after the disable ends - private void OnEmpDisabledRemoved(EntityUid uid, BatteryComponent component, ref EmpDisabledRemoved args) - { - if (!TryComp(uid, out var charging)) - return; - - var ev = new ChargerUpdateStatusEvent(); - RaiseLocalEvent(charging.ChargerUid, ref ev); - } - public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) { if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0) @@ -191,10 +179,6 @@ public bool IsFull(EntityUid uid, BatteryComponent? battery = null) if (!Resolve(uid, ref battery)) return false; - // If the battery is full, remove its charging component. - if (TryComp(uid, out _)) - RemComp(uid); - return battery.CurrentCharge / battery.MaxCharge >= 0.99f; } } diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index ae6b024162..db16dfa008 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -1,16 +1,13 @@ using Content.Server.Power.Components; -using Content.Server.Emp; using Content.Server.PowerCell; using Content.Shared.Examine; using Content.Shared.Power; using Content.Shared.PowerCell.Components; -using Content.Shared.Emp; using JetBrains.Annotations; using Robust.Shared.Containers; using System.Diagnostics.CodeAnalysis; using Content.Shared.Storage.Components; using Robust.Server.Containers; -using Content.Shared.Whitelist; namespace Content.Server.Power.EntitySystems; @@ -31,11 +28,6 @@ public override void Initialize() SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnEntityStorageInsertAttempt); SubscribeLocalEvent(OnChargerExamine); - - SubscribeLocalEvent(OnUpdateStatus); - - SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); } private void OnStartup(EntityUid uid, ChargerComponent component, ComponentStartup args) @@ -48,58 +40,21 @@ private void OnChargerExamine(EntityUid uid, ChargerComponent component, Examine args.PushMarkup(Loc.GetString("charger-examine", ("color", "yellow"), ("chargeRate", (int) component.ChargeRate))); } - private void StartChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - bool charge = true; - - if (HasComp(uid)) - charge = false; - else - if (!TryComp(target, out var battery)) - charge = false; - else - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - charge = false; - - // wrap functionality in an if statement instead of returning... - if (charge) - { - var charging = EnsureComp(target); - charging.ChargerUid = uid; - charging.ChargerComponent = component; - } - - // ...so the status always updates (for insertin a power cell) - UpdateStatus(uid, component); - } - - private void StopChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - if (HasComp(target)) - RemComp(target); - UpdateStatus(uid, component); - } - public override void Update(float frameTime) { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var charging)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var charger, out var containerComp)) { - if (!TryComp(charging.ChargerUid, out var chargerComponent)) + if (!_container.TryGetContainer(uid, charger.SlotId, out var container, containerComp)) continue; - if (charging.ChargerComponent.Status == CellChargerStatus.Off || charging.ChargerComponent.Status == CellChargerStatus.Empty) + if (charger.Status == CellChargerStatus.Empty || charger.Status == CellChargerStatus.Charged || container.ContainedEntities.Count == 0) continue; - if (HasComp(charging.ChargerUid)) - continue; - - if (!TryComp(uid, out var battery)) - continue; - - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - StopChargingBattery(charging.ChargerUid, charging.ChargerComponent, uid); - TransferPower(charging.ChargerUid, uid, charging.ChargerComponent, frameTime); + foreach (var contained in container.ContainedEntities) + { + TransferPower(uid, contained, charger, frameTime); + } } } @@ -116,7 +71,7 @@ private void OnInserted(EntityUid uid, ChargerComponent component, EntInsertedIn if (args.Container.ID != component.SlotId) return; - StartChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFromContainerMessage args) @@ -124,7 +79,7 @@ private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFrom if (args.Container.ID != component.SlotId) return; - StopChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } /// @@ -157,11 +112,6 @@ private void OnEntityStorageInsertAttempt(EntityUid uid, ChargerComponent compon args.Cancelled = true; } - private void OnUpdateStatus(EntityUid uid, ChargerComponent component, ref ChargerUpdateStatusEvent args) - { - UpdateStatus(uid, component); - } - private void UpdateStatus(EntityUid uid, ChargerComponent component) { var status = GetStatus(uid, component); @@ -176,6 +126,15 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) component.Status = status; + if (component.Status == CellChargerStatus.Charging) + { + AddComp(uid); + } + else + { + RemComp(uid); + } + switch (component.Status) { case CellChargerStatus.Off: @@ -187,7 +146,7 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Empty, appearance); break; case CellChargerStatus.Charging: - receiver.Load = component.ChargeRate; //does not scale with multiple slotted batteries + receiver.Load = component.ChargeRate; _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Charging, appearance); break; case CellChargerStatus.Charged: @@ -198,42 +157,6 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) throw new ArgumentOutOfRangeException(); } } - - private void OnEmpPulse(EntityUid uid, ChargerComponent component, ref EmpPulseEvent args) - { - // we don't care if we haven't been disabled - if (!args.Disabled) - return; - - // if the recharger is hit by an emp pulse, - // stop recharging contained batteries to save resources - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StopChargingBattery(uid, component, containedEntity); - } - } - - private void OnEmpDisabledRemoved(EntityUid uid, ChargerComponent component, ref EmpDisabledRemoved args) - { - // if an emp disable subsides, - // attempt to start charging all batteries - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StartChargingBattery(uid, component, containedEntity); - } - } private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) { @@ -255,28 +178,13 @@ private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) if (container.ContainedEntities.Count == 0) return CellChargerStatus.Empty; - var statusOut = CellChargerStatus.Off; - - foreach (var containedEntity in container.ContainedEntities) - { - // if none of the slotted items are actually batteries, represent the charger as off - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - // if all batteries are either EMP'd or fully charged, represent the charger as fully charged - statusOut = CellChargerStatus.Charged; - if (HasComp(containedEntity)) - continue; - - if (!HasComp(containedEntity)) - continue; + if (!SearchForBattery(container.ContainedEntities[0], out _, out var heldBattery)) + return CellChargerStatus.Off; - // if we have atleast one battery being charged, represent the charger as charging; - statusOut = CellChargerStatus.Charging; - break; - } + if (Math.Abs(heldBattery.MaxCharge - heldBattery.CurrentCharge) < 0.01) + return CellChargerStatus.Charged; - return statusOut; + return CellChargerStatus.Charging; } private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerComponent component, float frameTime) @@ -293,11 +201,11 @@ private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerCompone if (!SearchForBattery(targetEntity, out var batteryUid, out var heldBattery)) return; - _battery.TrySetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); // Just so the sprite won't be set to 99.99999% visibility if (heldBattery.MaxCharge - heldBattery.CurrentCharge < 0.01) { - _battery.TrySetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); } UpdateStatus(uid, component); @@ -315,6 +223,3 @@ private bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? return true; } } - -[ByRefEvent] -public record struct ChargerUpdateStatusEvent(); \ No newline at end of file diff --git a/Content.Server/Traits/Assorted/ModifyMoodTraitComponent.cs b/Content.Server/Traits/Assorted/ModifyMoodTraitComponent.cs deleted file mode 100644 index f9ae3b36f3..0000000000 --- a/Content.Server/Traits/Assorted/ModifyMoodTraitComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Content.Shared.Traits.Assorted.Components; - -/// -/// Used for traits that add a starting moodlet. -/// -[RegisterComponent] -public sealed partial class MoodModifyTraitComponent : Component -{ - [DataField] - public string? MoodId = null; -} diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index d6f13cb52a..39812f65b6 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.Shared.Mood; namespace Content.Server.Traits; @@ -65,6 +66,7 @@ public void AddTrait(EntityUid uid, TraitPrototype traitPrototype) AddTraitComponents(uid, traitPrototype); AddTraitActions(uid, traitPrototype); AddTraitPsionics(uid, traitPrototype); + AddTraitMoodlets(uid, traitPrototype); } /// @@ -139,4 +141,18 @@ public void AddTraitPsionics(EntityUid uid, TraitPrototype traitPrototype) if (_prototype.TryIndex(powerProto, out var psionicPower)) _psionicAbilities.InitializePsionicPower(uid, psionicPower, false); } + + /// + /// 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. + /// + public void AddTraitMoodlets(EntityUid uid, TraitPrototype traitPrototype) + { + if (traitPrototype.MoodEffects is null) + return; + + foreach (var moodProto in traitPrototype.MoodEffects) + if (_prototype.TryIndex(moodProto, out var moodlet)) + RaiseLocalEvent(uid, new MoodEffectEvent(moodlet.ID)); + } } diff --git a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs index e260280ae4..44bfb583dd 100644 --- a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs @@ -1,12 +1,14 @@ using Content.Shared.Chemistry.Components; using Content.Shared.FixedPoint; using Content.Shared.Popups; +using Robust.Shared.Network; using Robust.Shared.Random; namespace Content.Shared.Chemistry.EntitySystems; public sealed class RehydratableSystem : EntitySystem { + [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutions = default!; @@ -31,6 +33,9 @@ private void OnSolutionChange(Entity ent, ref SolutionCon // Try not to make this public if you can help it. private void Expand(Entity ent) { + if (_net.IsClient) + return; // no + var (uid, comp) = ent; var randomMob = _random.Pick(comp.PossibleSpawns); diff --git a/Content.Shared/Mood/MoodEffectPrototype.cs b/Content.Shared/Mood/MoodEffectPrototype.cs index ad21faec80..ab9bca0160 100644 --- a/Content.Shared/Mood/MoodEffectPrototype.cs +++ b/Content.Shared/Mood/MoodEffectPrototype.cs @@ -12,24 +12,34 @@ public sealed class MoodEffectPrototype : IPrototype public string ID { get; } = default!; public string Description => Loc.GetString($"mood-effect-{ID}"); + /// /// If they already have an effect with the same category, the new one will replace the old one. /// [DataField, ValidatePrototypeId] public string? Category; + /// /// How much should this moodlet modify an entity's Mood. /// [DataField(required: true)] public float MoodChange; + /// /// How long, in Seconds, does this moodlet last? If omitted, the moodlet will last until canceled by any system. /// [DataField] public int Timeout; + /// /// Should this moodlet be hidden from the player? EG: No popups or chat messages. /// [DataField] public bool Hidden; + + /// + /// When not null, this moodlet will replace itself with another Moodlet upon expiration. + /// + [DataField] + public ProtoId? MoodletOnEnd; } diff --git a/Content.Shared/Traits/Prototypes/TraitPrototype.cs b/Content.Shared/Traits/Prototypes/TraitPrototype.cs index 7bdff058ee..cd4b02a1e6 100644 --- a/Content.Shared/Traits/Prototypes/TraitPrototype.cs +++ b/Content.Shared/Traits/Prototypes/TraitPrototype.cs @@ -1,4 +1,5 @@ using Content.Shared.Customization.Systems; +using Content.Shared.Mood; using Content.Shared.Psionics; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -56,4 +57,10 @@ public sealed partial class TraitPrototype : IPrototype /// [DataField] public List? PsionicPowers { get; private set; } = default!; + + /// + /// The list of all Moodlets that this trait adds. + /// + [DataField] + public List>? MoodEffects { get; private set; } = default!; } diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index fdf35f8d5f..0be6b68d7e 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -6325,3 +6325,50 @@ Entries: id: 6359 time: '2024-09-14T05:44:56.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/889 +- author: VMSolidus + changes: + - type: Add + message: >- + Drug Addictions! Drug addictions are long lasting Moodlet-Pairs. The + first consisting of a temporary Mood bonus that is refreshed by + consuming the drug, and the second consisting of an extremely long + lasting mood penalty, which replaces the mood bonus should you go a long + enough time between consuming the drug in question. + - type: Add + message: Nicotine Addiction has been added as a new minor negative trait. + - type: Add + message: >- + Drugs/Reagents can now affect your character's Mood! Both with, and + without Addiction. + - type: Add + message: >- + TraitSystem has had functionality added for directly adding Moodlets to + a character upon joining the round, such as drug addictions, or + permanent mood modifications like Sanguine/Saturnine + - type: Add + message: >- + Lotophagoi Oil now induces an extremely powerful drug addiction, + providing an extremely large mood benefit for a short time. Which when + it wears off, creates an equally extreme mood penalty that lasts for a + very long time(or until you drink more Loto Oil). + id: 6360 + time: '2024-09-14T06:48:55.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/896 +- author: Mnemotechnician + changes: + - type: Fix + message: Cyborg recharging stations finally work again. + - type: Fix + message: >- + Rehydratable entities (such as monkey cubes) no longer spawn a second + client-side entity when rehydrated. + id: 6361 + time: '2024-09-14T17:55:41.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/888 +- author: VMSolidus + changes: + - type: Tweak + message: The Uncloneable trait is only worth one point now. + id: 6362 + time: '2024-09-14T18:01:21.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/868 diff --git a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl index db2f3816f6..dbb24a3caf 100644 --- a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl +++ b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl @@ -361,4 +361,11 @@ reagent-effect-guidebook-chem-reroll-psionic = { $chance -> [1] Allows *[other] allow - } a chance to get a different psionic power \ No newline at end of file + } a chance to get a different psionic power + +reagent-effect-guidebook-add-moodlet = + modifies mood by {$amount} + { $timeout -> + [0] indefinitely + *[other] for {$timeout} seconds + } \ No newline at end of file diff --git a/Resources/Locale/en-US/mood/mood.ftl b/Resources/Locale/en-US/mood/mood.ftl index bd64d52582..a931a30fb3 100644 --- a/Resources/Locale/en-US/mood/mood.ftl +++ b/Resources/Locale/en-US/mood/mood.ftl @@ -54,3 +54,16 @@ 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! + +# 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. \ No newline at end of file diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index e049af3c62..ff329a12a7 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -227,3 +227,7 @@ trait-description-AnomalousPositronics = Whether by intentional design from the manufacturer, black market modifications, or accidental omission, your positronic brain lacks its standard psionic insulation. As a being that can be argued to have a soul, this by extension means that it is possible for you to be influenced by the Noosphere. + +trait-name-AddictionNicotine = Nicotine Addiction +trait-description-AddictionNicotine = + You have an addiction to Nicotine, and will require frequent smoke breaks to keep your mood in check. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl b/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl index d630480759..1cdde91c4d 100644 --- a/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl +++ b/Resources/Locale/ru-RU/guidebook/chemistry/effects.ftl @@ -331,6 +331,12 @@ reagent-effect-guidebook-chem-reroll-psionic = [1] Даёт *[other] Даёт } шанс получить другую псионическую силу +reagent-effect-guidebook-add-moodlet = + увеличивает настроение на { $amount } + { $timeout -> + [0] бесконечность + *[other] { $timeout } секунд + } reagent-effect-guidebook-innoculate-zombie-infection = { $chance -> [1] Лечит diff --git a/Resources/Locale/ru-RU/mood/mood.ftl b/Resources/Locale/ru-RU/mood/mood.ftl index ef60aad484..b529ae6418 100644 --- a/Resources/Locale/ru-RU/mood/mood.ftl +++ b/Resources/Locale/ru-RU/mood/mood.ftl @@ -31,3 +31,12 @@ mood-effect-TraitorFocused = У меня есть цель, и я ее дост mood-effect-RevolutionFocused = ДА ЗДРАВСТВУЕТ РЕВОЛЮЦИЯ!!! mood-effect-CultFocused = Тёмные Боги, даруйте мне силу! mood-effect-TraitSanguine = Мне не о чем беспокоиться. Я уверен, что в конце концов все будет хорошо! +# Addictions +mood-effect-LotoTranscendence = + Я МОГУ ВИДЕТЬ ВСЕ, ЧТО ЕСТЬ, КОГДА-ЛИБО БУДЕТ И КОГДА-ЛИБО БЫЛО. ВСЕ БЫТИЕ ОТКРЫЛОСЬ МОЕМУ РАЗУМУ! + Я ДОЛЖЕН ЗАПОЛУЧИТЬ ВСЕ. Я ДОЛЖЕН ЗНАТЬ ВСЕ. АБСОЛЮТНО ВСЕ. НАВСЕГДА! +mood-effect-LotoEnthrallment = + Он убежал от меня... Сердце всего бытия ушло из моей души, оставив после себя пустоту, которую я не могу вынести. + Я боюсь, что увяну, если не смогу снова испить из чаши знания. +mood-effect-NicotineBenefit = У меня такое чувство, будто я всю жизнь стоял и только что сел. +mood-effect-NicotineWithdrawal = Мне бы сейчас пойти и прикурить немного. diff --git a/Resources/Locale/ru-RU/traits/traits.ftl b/Resources/Locale/ru-RU/traits/traits.ftl index d0c52f4cc9..945dd5740c 100644 --- a/Resources/Locale/ru-RU/traits/traits.ftl +++ b/Resources/Locale/ru-RU/traits/traits.ftl @@ -175,3 +175,5 @@ trait-description-AnomalousPositronics = Будь то преднамеренный дизайн от производителя, модификации на черном рынке или случайное упущение, вашему позитронному мозгу не хватает стандартной псионической изоляции. Как существо, у которого, как можно утверждать, есть душа, это, в более широком смысле, означает, что вы можете подвергаться влиянию Ноосферы. +trait-name-AddictionNicotine = Никотиновая зависимость +trait-description-AddictionNicotine = У вас зависимость от никотина, и вам понадобятся частые перекуры, чтобы сохранить свой рассудок. diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml index f3ca1c758d..fde82ecb6c 100644 --- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml @@ -104,6 +104,9 @@ - type: Tag tags: - HidesTail + - CanPilot + - FootstepSound + - DoorBumpOpener - type: ScentTracker - type: Flashable eyeDamageChance: 0.3 diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index 2baead2d33..7cd347fd41 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -62,6 +62,9 @@ - type: Tag tags: - HidesTail + - CanPilot + - FootstepSound + - DoorBumpOpener - type: LanguageKnowledge speaks: - GalacticCommon diff --git a/Resources/Prototypes/Mood/drugs.yml b/Resources/Prototypes/Mood/drugs.yml new file mode 100644 index 0000000000..470abc5e3d --- /dev/null +++ b/Resources/Prototypes/Mood/drugs.yml @@ -0,0 +1,34 @@ +# 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: 7200 #2 hours + category: "LotophagoiAddiction" + +- type: moodCategory + id: LotophagoiAddiction + +# 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" + +- type: moodCategory + id: NicotineAddiction \ No newline at end of file diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml index 325f856388..8ae8ee802b 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml @@ -68,6 +68,9 @@ - type: Tag tags: - HidesTail + - CanPilot + - FootstepSound + - DoorBumpOpener - type: LanguageKnowledge speaks: - GalacticCommon diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index 2ab323c309..ca85fd15b3 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -212,6 +212,11 @@ plantMetabolism: - !type:PlantAdjustHealth amount: -5 + metabolisms: + Narcotic: + effects: + - !type:ChemAddMoodlet + moodPrototype: NicotineBenefit # TODO: Replace these nonstandardized effects with generic brain damage - type: reagent @@ -260,7 +265,7 @@ type: Add time: 5 refresh: false - - !type:ChemRerollPsionic #Nyano - Summary: lets the imbiber become psionic. + - !type:ChemRerollPsionic #Nyano - Summary: lets the imbiber become psionic. conditions: - !type:ReagentThreshold reagent: SpaceDrugs diff --git a/Resources/Prototypes/Reagents/psionic.yml b/Resources/Prototypes/Reagents/psionic.yml index 3e8415fc0e..f17a84047a 100644 --- a/Resources/Prototypes/Reagents/psionic.yml +++ b/Resources/Prototypes/Reagents/psionic.yml @@ -92,6 +92,12 @@ - !type:GenericStatusEffect key: SlurredSpeech component: TelepathicRepeater + - !type:ChemAddMoodlet + moodPrototype: LotoTranscendence + conditions: + - !type:ReagentThreshold + reagent: LotophagoiOil + min: 5 - type: reagent id: Ectoplasm diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index 51099839ac..34e1354158 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -65,7 +65,7 @@ - type: trait id: Uncloneable category: Physical - points: 4 + points: 1 requirements: - !type:CharacterJobRequirement inverted: true diff --git a/Resources/Prototypes/Traits/neutral.yml b/Resources/Prototypes/Traits/neutral.yml index a4e449f1c0..c7fa8d914e 100644 --- a/Resources/Prototypes/Traits/neutral.yml +++ b/Resources/Prototypes/Traits/neutral.yml @@ -63,9 +63,8 @@ inverted: true traits: - Sanguine - components: - - type: MoodModifyTrait - moodId: TraitSaturnine + moodEffects: + - TraitSaturnine - type: trait id: Sanguine @@ -81,6 +80,22 @@ inverted: true traits: - Saturnine - components: - - type: MoodModifyTrait - moodId: TraitSanguine \ No newline at end of file + moodEffects: + - TraitSanguine + +- type: trait + id: AddictionNicotine + category: Mental + points: 1 + requirements: + - !type:CharacterJobRequirement + inverted: true + jobs: + - Borg + - MedicalBorg + - !type:CharacterSpeciesRequirement + inverted: true + species: + - IPC + moodEffects: + - NicotineWithdrawal \ No newline at end of file diff --git a/Resources/Prototypes/_LostParadise/Entities/Mobs/Species/Shark/Entities/Mobs/Species/Shark.yml b/Resources/Prototypes/_LostParadise/Entities/Mobs/Species/Shark/Entities/Mobs/Species/Shark.yml index 34e7903bbd..1c3792805f 100644 --- a/Resources/Prototypes/_LostParadise/Entities/Mobs/Species/Shark/Entities/Mobs/Species/Shark.yml +++ b/Resources/Prototypes/_LostParadise/Entities/Mobs/Species/Shark/Entities/Mobs/Species/Shark.yml @@ -49,6 +49,9 @@ - type: Tag tags: - HidesTail + - CanPilot + - FootstepSound + - DoorBumpOpener - type: Vocal sounds: Male: MaleHuman