diff --git a/Content.Server/Delivery/DeliverySystem.cs b/Content.Server/Delivery/DeliverySystem.cs index 0ddfde49ae..5fc9b53316 100644 --- a/Content.Server/Delivery/DeliverySystem.cs +++ b/Content.Server/Delivery/DeliverySystem.cs @@ -135,20 +135,6 @@ public sealed partial class DeliverySystem : SharedDeliverySystem DirtyField(ent.Owner, ent.Comp, nameof(DeliveryComponent.WasPenalized)); } - /// - /// Gathers the total multiplier for a delivery. - /// This is done by components having subscribed to GetDeliveryMultiplierEvent and having added onto it. - /// - /// The delivery for which to get the multiplier. - /// Total multiplier. - private float GetDeliveryMultiplier(Entity ent) - { - var ev = new GetDeliveryMultiplierEvent(); - RaiseLocalEvent(ent, ref ev); - - return ev.Multiplier; - } - public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Shared/Delivery/DeliveryModifierSystem.cs b/Content.Shared/Delivery/DeliveryModifierSystem.cs new file mode 100644 index 0000000000..505975732c --- /dev/null +++ b/Content.Shared/Delivery/DeliveryModifierSystem.cs @@ -0,0 +1,30 @@ +using Robust.Shared.Random; + +namespace Content.Shared.Delivery; + +/// +/// System responsible for managing multipliers and logic for different delivery modifiers. +/// +public sealed partial class DeliveryModifierSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRandomMultiplierMapInit); + SubscribeLocalEvent(OnGetRandomMultiplier); + } + + private void OnRandomMultiplierMapInit(Entity ent, ref MapInitEvent args) + { + ent.Comp.CurrentMultiplierOffset = _random.NextFloat(ent.Comp.MinMultiplierOffset, ent.Comp.MaxMultiplierOffset); + Dirty(ent); + } + + private void OnGetRandomMultiplier(Entity ent, ref GetDeliveryMultiplierEvent args) + { + args.AdditiveMultiplier += ent.Comp.CurrentMultiplierOffset; + } +} diff --git a/Content.Shared/Delivery/DeliveryRandomMultiplierComponent.cs b/Content.Shared/Delivery/DeliveryRandomMultiplierComponent.cs new file mode 100644 index 0000000000..d753d8aff2 --- /dev/null +++ b/Content.Shared/Delivery/DeliveryRandomMultiplierComponent.cs @@ -0,0 +1,32 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Delivery; + +/// +/// Component given to deliveries. +/// Applies a random multiplier to the delivery on init. +/// Added additively to the total multiplier. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(DeliveryModifierSystem))] +public sealed partial class DeliveryRandomMultiplierComponent : Component +{ + /// + /// The highest the random multiplier can go. + /// + [DataField] + public float MaxMultiplierOffset = 0.2f; + + /// + /// The lowest the random multiplier can go. + /// + [DataField] + public float MinMultiplierOffset = -0.2f; + + /// + /// The current multiplier this component provides. + /// Gets randomized between MaxMultiplierOffset and MinMultiplierOffset on MapInit. + /// + [DataField, AutoNetworkedField] + public float CurrentMultiplierOffset; +} diff --git a/Content.Shared/Delivery/SharedDeliverySystem.cs b/Content.Shared/Delivery/SharedDeliverySystem.cs index 53c5224940..1667035dac 100644 --- a/Content.Shared/Delivery/SharedDeliverySystem.cs +++ b/Content.Shared/Delivery/SharedDeliverySystem.cs @@ -54,12 +54,23 @@ public abstract class SharedDeliverySystem : EntitySystem var jobTitle = ent.Comp.RecipientJobTitle ?? Loc.GetString("delivery-recipient-no-job"); var recipientName = ent.Comp.RecipientName ?? Loc.GetString("delivery-recipient-no-name"); - if (ent.Comp.IsOpened) + using (args.PushGroup(nameof(DeliveryComponent), 1)) { - args.PushText(Loc.GetString("delivery-already-opened-examine")); + if (ent.Comp.IsOpened) + { + args.PushText(Loc.GetString("delivery-already-opened-examine")); + } + + args.PushText(Loc.GetString("delivery-recipient-examine", ("recipient", recipientName), ("job", jobTitle))); } - args.PushText(Loc.GetString("delivery-recipient-examine", ("recipient", recipientName), ("job", jobTitle))); + if (ent.Comp.IsLocked) + { + var multiplier = GetDeliveryMultiplier(ent); + var totalSpesos = Math.Round(ent.Comp.BaseSpesoReward * multiplier); + + args.PushMarkup(Loc.GetString("delivery-earnings-examine", ("spesos", totalSpesos))); + } } private void OnSpawnerExamine(Entity ent, ref ExaminedEvent args) @@ -235,6 +246,20 @@ public abstract class SharedDeliverySystem : EntitySystem _appearance.SetData(uid, DeliverySpawnerVisuals.Contents, contents > 0); } + /// + /// Gathers the total multiplier for a delivery. + /// This is done by components having subscribed to GetDeliveryMultiplierEvent and having added onto it. + /// + /// The delivery for which to get the multiplier. + /// Total multiplier. + protected float GetDeliveryMultiplier(Entity ent) + { + var ev = new GetDeliveryMultiplierEvent(); + RaiseLocalEvent(ent, ref ev); + + return ev.AdditiveMultiplier * ev.MultiplicativeMultiplier; + } + protected virtual void GrantSpesoReward(Entity ent) { } protected virtual void HandlePenalty(Entity ent, string? reason = null) { } @@ -243,13 +268,16 @@ public abstract class SharedDeliverySystem : EntitySystem } /// -/// Used to gather the multiplier from all different delivery components. +/// Used to gather the total multiplier for deliveries. +/// This is done by various modifier components subscribing to this and adding accordingly. /// +/// The additive multiplier. +/// The multiplicative multiplier. [ByRefEvent] -public record struct GetDeliveryMultiplierEvent(float Multiplier) +public record struct GetDeliveryMultiplierEvent(float AdditiveMultiplier, float MultiplicativeMultiplier) { // we can't use an optional parameter because the default parameterless constructor defaults everything - public GetDeliveryMultiplierEvent() : this(1.0f) { } + public GetDeliveryMultiplierEvent() : this(1.0f, 1.0f) { } } /// diff --git a/Resources/Locale/en-US/delivery/delivery-component.ftl b/Resources/Locale/en-US/delivery/delivery-component.ftl index a6bbc79343..5903094690 100644 --- a/Resources/Locale/en-US/delivery/delivery-component.ftl +++ b/Resources/Locale/en-US/delivery/delivery-component.ftl @@ -1,5 +1,6 @@ delivery-recipient-examine = This one is meant for {$recipient}, {$job}. delivery-already-opened-examine = It was already opened. +delivery-earnings-examine = Delivering this will earn the station [color=yellow]{$spesos}[/color] spesos. delivery-recipient-no-name = Unnamed delivery-recipient-no-job = Unknown diff --git a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml index 19789cd7eb..2ff5e9daf7 100644 --- a/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml +++ b/Resources/Prototypes/Entities/Objects/Deliveries/deliveries.yml @@ -36,6 +36,7 @@ failPopup: fingerprint-reader-fail failGlovesPopup: fingerprint-reader-fail-gloves - type: Delivery + - type: DeliveryRandomMultiplier - type: ContainerContainer containers: delivery: !type:Container