Skip to content

Commit

Permalink
Merge pull request #1460 from honeyed-lemons/mail-updates
Browse files Browse the repository at this point in the history
Mail CCVars and reward nerfs
  • Loading branch information
mqole authored Jan 25, 2025
2 parents 00cbeb1 + 2ed831c commit f3f5478
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 137 deletions.
145 changes: 26 additions & 119 deletions Content.Server/_DV/Mail/Components/MailTeleporterComponent.cs
Original file line number Diff line number Diff line change
@@ -1,127 +1,34 @@
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;

namespace Content.Server._DV.Mail.Components
namespace Content.Server._DV.Mail.Components;

/// <summary>
/// This is for the mail teleporter.
/// Random mail will be teleported to this every few minutes.
/// </summary>
[RegisterComponent]
public sealed partial class MailTeleporterComponent : Component
{
// Not starting accumulator at 0 so mail carriers have some deliveries to make shortly after roundstart.
[DataField]
public float Accumulator = 285f;

/// <summary>
/// This is for the mail teleporter.
/// Random mail will be teleported to this every few minutes.
/// The sound that's played when new mail arrives.
/// </summary>
[RegisterComponent]
public sealed partial class MailTeleporterComponent : Component
{

// Not starting accumulator at 0 so mail carriers have some deliveries to make shortly after roundstart.
[DataField]
public float Accumulator = 285f;

[DataField]
public TimeSpan TeleportInterval = TimeSpan.FromMinutes(5);

/// <summary>
/// The sound that's played when new mail arrives.
/// </summary>
[DataField]
public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");
/// <summary>
/// Imp : The VFX spawned when mail teleports in.
/// </summary>
[DataField]
public EntProtoId BeamInFx = "MailTelepadVFX";
/// <summary>
/// The MailDeliveryPoolPrototype that's used to select what mail this
/// teleporter can deliver.
/// </summary>
[DataField]
public string MailPool = "RandomDeltaVMailDeliveryPool"; // Frontier / DeltaV: Mail rework

/// <summary>
/// How many mail candidates do we need per actual delivery sent when
/// the mail goes out? The number of candidates is divided by this number
/// to determine how many deliveries will be teleported in.
/// It does not determine unique recipients. That is random.
/// </summary>
[DataField]
public int CandidatesPerDelivery = 8;

[DataField]
public int MinimumDeliveriesPerTeleport = 1;

/// <summary>
/// Do not teleport any more mail in, if there are at least this many
/// undelivered parcels.
/// </summary>
/// <remarks>
/// Currently this works by checking how many MailComponent entities
/// are sitting on the teleporter's tile.
///
/// It should be noted that if the number of actual deliveries to be
/// made based on the number of candidates divided by candidates per
/// delivery exceeds this number, the teleporter will spawn more mail
/// than this number.
///
/// This is just a simple check to see if anyone's been picking up the
/// mail lately to prevent entity bloat for the sake of performance.
/// </remarks>
[DataField]
public int MaximumUndeliveredParcels = 5;

/// <summary>
/// Any item that breaks or is destroyed in less than this amount of
/// damage is one of the types of items considered fragile.
/// </summary>
[DataField]
public int FragileDamageThreshold = 10;

/// <summary>
/// What's the bonus for delivering a fragile package intact?
/// </summary>
[DataField]
public int FragileBonus = 100;

/// <summary>
/// What's the malus for failing to deliver a fragile package?
/// </summary>
[DataField]
public int FragileMalus = -100;
[DataField]
public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");

/// <summary>
/// What's the chance for any one delivery to be marked as priority mail?
/// </summary>
[DataField]
public float PriorityChance = 0.1f;

/// <summary>
/// How long until a priority delivery is considered as having failed
/// if not delivered?
/// </summary>
[DataField]
public TimeSpan PriorityDuration = TimeSpan.FromMinutes(5);

/// <summary>
/// What's the bonus for delivering a priority package on time?
/// </summary>
[DataField]
public int PriorityBonus = 250;

/// <summary>
/// What's the malus for failing to deliver a priority package?
/// </summary>
[DataField]
public int PriorityMalus = -250;

// Frontier: Large mail
/// <summary>
/// What's the bonus for delivering a large package intact?
/// </summary>
[DataField]
public int LargeBonus = 1500; // DeltaV; 5000 to 1500

/// <summary>
/// What's the malus for failing to deliver a large package?
/// </summary>
[DataField]
public int LargeMalus = -500; // DeltaV; -250 to -500
// End Frontier: Large mail
}
/// <summary>
/// Imp : The VFX spawned when mail teleports in.
/// </summary>
[DataField]
public EntProtoId BeamInFx = "MailTelepadVFX";
/// <summary>
/// The MailDeliveryPoolPrototype that's used to select what mail this
/// teleporter can deliver.
/// </summary>
[DataField]
public string MailPool = "RandomDeltaVMailDeliveryPool"; // Frontier / DeltaV: Mail rework
}
35 changes: 22 additions & 13 deletions Content.Server/_DV/Mail/EntitySystems/MailSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Content.Server.Power.Components;
using Content.Server.Spawners.EntitySystems;
using Content.Server.Station.Systems;
using Content.Shared._DV.CCVars;
using Content.Shared._DV.Mail;
using Content.Shared.Access;
using Content.Shared.Access.Components;
Expand All @@ -40,6 +41,7 @@
using Content.Shared.Tag;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
Expand Down Expand Up @@ -69,6 +71,7 @@ public sealed class MailSystem : EntitySystem
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly IConfigurationManager _config = default!;

[Dependency] private readonly LogisticStatsSystem _logisticsStatsSystem = default!;

Expand Down Expand Up @@ -96,18 +99,20 @@ public override void Update(float frameTime)
{
base.Update(frameTime);

var interval = _config.GetCVar(DCCVars.MailTeleportIntervalInMinutes);
var query = EntityQueryEnumerator<MailTeleporterComponent>();

while (query.MoveNext(out var uid, out var mailTeleporter))
{
if (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
continue;

mailTeleporter.Accumulator += frameTime;

if (mailTeleporter.Accumulator < mailTeleporter.TeleportInterval.TotalSeconds)
if (mailTeleporter.Accumulator < TimeSpan.FromMinutes(interval).TotalSeconds)
continue;

mailTeleporter.Accumulator -= (float)mailTeleporter.TeleportInterval.TotalSeconds;
mailTeleporter.Accumulator -= (float)TimeSpan.FromMinutes(interval).TotalSeconds;
SpawnMail(uid, mailTeleporter);
}
}
Expand Down Expand Up @@ -457,13 +462,13 @@ public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailReci
_sawmill.Error($"Can't insert {ToPrettyString(entity)} into new mail delivery {ToPrettyString(uid)}! Deleting it.");
QueueDel(entity);
}
else if (!mailComp.IsFragile && IsEntityFragile(entity, component.FragileDamageThreshold))
else if (!mailComp.IsFragile && IsEntityFragile(entity, _config.GetCVar(DCCVars.MailFragileDamageThreshold)))
{
mailComp.IsFragile = true;
}
}

if (_random.Prob(component.PriorityChance))
if (_random.Prob(_config.GetCVar(DCCVars.MailPriorityChances)))
mailComp.IsPriority = true;

// This needs to override both the random probability and the
Expand All @@ -474,31 +479,35 @@ public void SetupMail(EntityUid uid, MailTeleporterComponent component, MailReci
mailComp.RecipientJob = recipient.Job;
mailComp.Recipient = recipient.Name;

// Imp: Set base bounty and penalty
mailComp.Bounty += _config.GetCVar(DCCVars.MailDefaultBounty);
mailComp.Penalty += _config.GetCVar(DCCVars.MailDefaultPenelty);

// Frontier: Large mail bonus
var mailEntityStrings = mailComp.IsLarge ? MailConstants.MailLarge : MailConstants.Mail;
if (mailComp.IsLarge)
{
mailComp.Bounty += component.LargeBonus;
mailComp.Penalty += component.LargeMalus;
mailComp.Bounty += _config.GetCVar(DCCVars.MailLargeBonus);
mailComp.Penalty += _config.GetCVar(DCCVars.MailLargeMalus);
}
// End Frontier

if (mailComp.IsFragile)
{
mailComp.Bounty += component.FragileBonus;
mailComp.Penalty += component.FragileMalus;
mailComp.Bounty += _config.GetCVar(DCCVars.MailFragileBonus);
mailComp.Penalty += _config.GetCVar(DCCVars.MailFragileMalus);
_appearance.SetData(uid, MailVisuals.IsFragile, true);
}

if (mailComp.IsPriority)
{
mailComp.Bounty += component.PriorityBonus;
mailComp.Penalty += component.PriorityMalus;
mailComp.Bounty += _config.GetCVar(DCCVars.MailPriorityBonus);
mailComp.Penalty += _config.GetCVar(DCCVars.MailPriorityMalus);
_appearance.SetData(uid, MailVisuals.IsPriority, true);

mailComp.PriorityCancelToken = new CancellationTokenSource();

Timer.Spawn((int) component.PriorityDuration.TotalMilliseconds,
Timer.Spawn((int) TimeSpan.FromMinutes(_config.GetCVar(DCCVars.MailPriorityDuration)).TotalMilliseconds,
() =>
{
// DeltaV - Expired mail recorded to logistic stats
Expand Down Expand Up @@ -635,7 +644,7 @@ private void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null)
return;
}

if (GetUndeliveredParcelCount(uid) >= component.MaximumUndeliveredParcels)
if (GetUndeliveredParcelCount(uid) >= _config.GetCVar(DCCVars.MailMaximumUndeliveredParcels))
return;

var candidateList = GetMailRecipientCandidates(uid);
Expand All @@ -652,7 +661,7 @@ private void SpawnMail(EntityUid uid, MailTeleporterComponent? component = null)
return;
}

var deliveryCount = component.MinimumDeliveriesPerTeleport + candidateList.Count / component.CandidatesPerDelivery;
var deliveryCount = 1 + candidateList.Count / _config.GetCVar(DCCVars.MailCandidatesPerDelivery);

for (var i = 0; i < deliveryCount; i++)
{
Expand Down
9 changes: 6 additions & 3 deletions Content.Server/_DV/Mail/MailCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using Content.Server._DV.Mail.Components;
using Content.Server._DV.Mail.EntitySystems;
using Content.Server.Administration;
using Content.Shared._DV.CCVars;
using Content.Shared._DV.Mail;
using Content.Shared.Administration;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
Expand All @@ -20,13 +22,13 @@ public sealed class MailToCommand : IConsoleCommand
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IConfigurationManager _config = default!;

private const string BlankMailPrototype = "MailAdminFun";
private const string BlankLargeMailPrototype = "MailLargeAdminFun"; // Frontier: large mail
private const string Container = "storagebase";
private const string MailContainer = "contents";


public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 4)
Expand Down Expand Up @@ -125,7 +127,7 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)

var teleporterQueue = containerSystem.EnsureContainer<Container>((EntityUid)teleporterUid, "queued");
containerSystem.Insert(mailUid, teleporterQueue);
shell.WriteLine(Loc.GetString("command-mailto-success", ("timeToTeleport", teleporterComponent.TeleportInterval.TotalSeconds - teleporterComponent.Accumulator)));
shell.WriteLine(Loc.GetString("command-mailto-success", ("timeToTeleport", TimeSpan.FromMinutes(_config.GetCVar(DCCVars.MailTeleportIntervalInMinutes)).TotalSeconds - teleporterComponent.Accumulator)));
}
}

Expand All @@ -137,12 +139,13 @@ public sealed class MailNowCommand : IConsoleCommand
public string Help => Loc.GetString("command-mailnow-help", ("command", Command));

[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IConfigurationManager _config = default!;

public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
foreach (var mailTeleporter in _entityManager.EntityQuery<MailTeleporterComponent>())
{
mailTeleporter.Accumulator += (float) mailTeleporter.TeleportInterval.TotalSeconds - mailTeleporter.Accumulator;
mailTeleporter.Accumulator += (float) TimeSpan.FromMinutes(_config.GetCVar(DCCVars.MailTeleportIntervalInMinutes)).TotalSeconds - mailTeleporter.Accumulator;
}

shell.WriteLine(Loc.GetString("command-mailnow-success"));
Expand Down
Loading

0 comments on commit f3f5478

Please sign in to comment.