Skip to content

Commit

Permalink
Merge branch 'master' into 2024-09-21-rgbb
Browse files Browse the repository at this point in the history
  • Loading branch information
dvir001 committed Sep 22, 2024
2 parents 933315b + 247ab91 commit aef511a
Show file tree
Hide file tree
Showing 91 changed files with 2,130 additions and 424 deletions.
150 changes: 149 additions & 1 deletion Content.Server/Forensics/Systems/ForensicScannerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using System.Linq;
using System.Text;
using Content.Server.Popups;
using Content.Server.Stack; // Frontier
using Content.Server._NF.Smuggling; // Frontier
using Content.Server._NF.Smuggling.Components; // Frontier
using Content.Server.Cargo.Systems; // Frontier
using Content.Server.Radio.EntitySystems; // Frontier
using Content.Shared.UserInterface;
using Content.Shared.DoAfter;
using Content.Shared.Fluids.Components;
Expand All @@ -9,13 +14,24 @@
using Content.Shared.Interaction;
using Content.Shared.Paper;
using Content.Shared.Verbs;
using Content.Shared.Stacks; // Frontier
using Content.Shared.Radio; // Frontier
using Content.Shared.Access.Systems; // Frontier
using Robust.Shared.Prototypes; // Frontier
using Content.Shared.Tag;
using Robust.Shared.Audio.Systems;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Timing;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Shared.Containers.ItemSlots; // Frontier
using Content.Server.Cargo.Components; // Frontier
using Content.Server._NF.SectorServices; // Frontier
using Content.Shared.FixedPoint; // Frontier
using Robust.Shared.Configuration; // Frontier
using Content.Shared._NF.CCVar;
using Content.Shared._NF.Bank; // Frontier

// todo: remove this stinky LINQy

namespace Content.Server.Forensics
Expand All @@ -33,6 +49,30 @@ public sealed class ForensicScannerSystem : EntitySystem
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly StackSystem _stackSystem = default!; // Frontier
[Dependency] private readonly SharedAudioSystem _audio = default!; // Frontier
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; // Frontier
[Dependency] private readonly RadioSystem _radio = default!; // Frontier
[Dependency] private readonly AccessReaderSystem _accessReader = default!; // Frontier
[Dependency] private readonly DeadDropSystem _deadDrop = default!; // Frontier
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!; // Frontier
[Dependency] private readonly CargoSystem _cargo = default!; // Frontier
[Dependency] private readonly SectorServiceSystem _service = default!; // Frontier
[Dependency] private readonly IConfigurationManager _cfg = default!; // Frontier

// Frontier: payout constants
// Temporary values, sane defaults, will be overwritten by CVARs.
private int _minFUCPayout = 2;

private const int ActiveUnusedDeadDropSpesoReward = 20000;
private const float ActiveUnusedDeadDropFUCReward = 2.0f;
private const int ActiveUsedDeadDropSpesoReward = 10000;
private const float ActiveUsedDeadDropFUCReward = 1.0f;
private const int InactiveUsedDeadDropSpesoReward = 5000;
private const float InactiveUsedDeadDropFUCReward = 0.5f;
private const int DropPodSpesoReward = 10000;
private const float DropPodFUCReward = 1.0f;
// End Frontier: payout constants

public override void Initialize()
{
Expand All @@ -45,7 +85,73 @@ public override void Initialize()
SubscribeLocalEvent<ForensicScannerComponent, ForensicScannerPrintMessage>(OnPrint);
SubscribeLocalEvent<ForensicScannerComponent, ForensicScannerClearMessage>(OnClear);
SubscribeLocalEvent<ForensicScannerComponent, ForensicScannerDoAfterEvent>(OnDoAfter);

Subs.CVar(_cfg, NFCCVars.SmugglingMinFucPayout, OnMinFucPayoutChanged, true); // Frontier
}

private void OnMinFucPayoutChanged(int newMin)
{
_minFUCPayout = newMin;
}

// Frontier: add dead drop rewards
/// <summary>
/// Rewards the NFSD department for scanning a dead drop.
/// Gives some amount of spesos and FUC to the
/// </summary>
private void GiveReward(EntityUid uidOrigin, EntityUid target, int spesoAmount, FixedPoint2 fucAmount, string msg)
{
SoundSpecifier confirmSound = new SoundPathSpecifier("/Audio/Effects/Cargo/ping.ogg");
_audio.PlayPvs(_audio.GetSound(confirmSound), uidOrigin);

// Credit the NFSD's bank account (todo: split these)
if (spesoAmount > 0)
{
var queryBank = EntityQuery<StationBankAccountComponent>();
foreach (var account in queryBank)
{
_cargo.DeductFunds(account, -spesoAmount);
}
}
else
spesoAmount = 0;

if (fucAmount > 0)
{
// Accumulate sector-wide FUCs, pay out if min threshold met
if (TryComp<SectorDeadDropComponent>(_service.GetServiceEntity(), out var sectorDD))
{
sectorDD.FUCAccumulator += fucAmount;
if (sectorDD.FUCAccumulator >= _minFUCPayout)
{
// inherent floor
int payout = sectorDD.FUCAccumulator.Int();
sectorDD.FUCAccumulator -= payout;

var stackPrototype = _prototypeManager.Index<StackPrototype>("FrontierUplinkCoin");
_stackSystem.Spawn(payout, stackPrototype, Transform(target).Coordinates);
}
}
}
else
fucAmount = 0;

var channel = _prototypeManager.Index<RadioChannelPrototype>("Nfsd");
string msgString = Loc.GetString(msg);
if (fucAmount >= 1)
{
msgString = msgString + " " + Loc.GetString("forensic-reward-amount",
("spesos", BankSystemExtensions.ToSpesoString(spesoAmount)),
("fuc", BankSystemExtensions.ToFUCString(fucAmount.Int())));
}
else
{
msgString = msgString + " " + Loc.GetString("forensic-reward-amount-speso-only",
("spesos", BankSystemExtensions.ToSpesoString(spesoAmount)));
}
_radio.SendRadioMessage(uidOrigin, msgString, channel, uidOrigin);
}
// End Frontier: add dead drop rewards

private void UpdateUserInterface(EntityUid uid, ForensicScannerComponent component)
{
Expand Down Expand Up @@ -87,6 +193,48 @@ private void OnDoAfter(EntityUid uid, ForensicScannerComponent component, DoAfte
scanner.Residues = forensics.Residues.ToList();
}

// Frontier: contraband poster/pod scanning
if (_itemSlots.TryGetSlot(uid, "forensics_cartridge", out var itemSlot) && itemSlot.HasItem)
{
EntityUid target = args.Args.Target.Value;
if (TryComp<DeadDropComponent>(target, out var deadDrop))
{
// If there's a dead drop note present, pay out regardless and compromise the dead drop.
if (_gameTiming.CurTime >= deadDrop.NextDrop)
{
int spesoReward;
FixedPoint2 fucReward;
string msg;
if (deadDrop.DeadDropCalled)
{
spesoReward = ActiveUsedDeadDropSpesoReward;
fucReward = ActiveUsedDeadDropFUCReward;
msg = "forensic-reward-dead-drop-used-present";
}
else
{
spesoReward = ActiveUnusedDeadDropSpesoReward;
fucReward = ActiveUnusedDeadDropFUCReward;
msg = "forensic-reward-dead-drop-unused";
}
GiveReward(uid, target, spesoReward, fucReward, msg);
_deadDrop.CompromiseDeadDrop(target, deadDrop);
}
// Otherwise, if it's been used, pay out at a reduced rate and compromise it.
else if (deadDrop.DeadDropCalled)
{
GiveReward(uid, target, InactiveUsedDeadDropSpesoReward, InactiveUsedDeadDropFUCReward, "forensic-reward-dead-drop-used-gone");
_deadDrop.CompromiseDeadDrop(target, deadDrop);
}
}
else if (TryComp<ContrabandPodGridComponent>(Transform(target).GridUid, out var pod) && !pod.Scanned)
{
GiveReward(uid, target, DropPodSpesoReward, DropPodFUCReward, "forensic-reward-pod");
pod.Scanned = true;
}
}
// End Frontier: contraband poster/pod scanning

if (_tag.HasTag(args.Args.Target.Value, "DNASolutionScannable"))
{
scanner.SolutionDNAs = _forensicsSystem.GetSolutionsDNA(args.Args.Target.Value);
Expand Down
34 changes: 34 additions & 0 deletions Content.Server/Shipyard/Systems/ShipyardSystem.Consoles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
using Robust.Shared.Audio.Systems;
using Content.Shared.Access;
using Content.Shared.Tiles;
using Content.Server._NF.Smuggling.Components;

namespace Content.Server.Shipyard.Systems;

Expand Down Expand Up @@ -367,6 +368,17 @@ public void OnSellMessage(EntityUid uid, ShipyardConsoleComponent component, Shi

var shuttleName = ToPrettyString(shuttleUid); // Grab the name before it gets 1984'd

// Check for shipyard blacklisting components
var disableSaleQuery = GetEntityQuery<DisableShipyardSaleComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
var disableSaleMsg = FindDisableShipyardSaleObjects(shuttleUid, (ShipyardConsoleUiKey)args.UiKey, disableSaleQuery, xformQuery);
if (disableSaleMsg != null)
{
ConsolePopup(args.Actor, Loc.GetString(disableSaleMsg));
PlayDenySound(args.Actor, uid, component);
return;
}

var saleResult = TrySellShuttle(stationUid, shuttleUid, out var bill);
if (saleResult.Error != ShipyardSaleError.Success)
{
Expand Down Expand Up @@ -606,6 +618,28 @@ private void OnItemSlotChanged(EntityUid uid, ShipyardConsoleComponent component
return null;
}

/// <summary>
/// Looks for a living, sapient being aboard a particular entity.
/// </summary>
/// <param name="uid">The entity to search (e.g. a shuttle, a station)</param>
/// <param name="mobQuery">A query to get the MobState from an entity</param>
/// <param name="xformQuery">A query to get the transform component of an entity</param>
/// <returns>The name of the sapient being if one was found, null otherwise.</returns>
public string? FindDisableShipyardSaleObjects(EntityUid shuttle, ShipyardConsoleUiKey key, EntityQuery<DisableShipyardSaleComponent> disableSaleQuery, EntityQuery<TransformComponent> xformQuery)
{
var xform = xformQuery.GetComponent(shuttle);
var childEnumerator = xform.ChildEnumerator;

while (childEnumerator.MoveNext(out var child))
{
if (disableSaleQuery.TryGetComponent(child, out var disableSale)
&& !disableSale.AllowedShipyardTypes.Contains(key))
return disableSale.Reason;
}

return null;
}

private struct IDShipAccesses
{
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> Tags;
Expand Down
4 changes: 4 additions & 0 deletions Content.Server/Shipyard/Systems/ShipyardSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Content.Shared.Shipyard.Events;
using Content.Shared.Mobs.Components;
using Robust.Shared.Containers;
using Content.Server._NF.Smuggling.Components;

namespace Content.Server.Shipyard.Systems;

Expand Down Expand Up @@ -46,12 +47,15 @@ public enum ShipyardSaleError
Undocked, // Ship is not docked with the station.
OrganicsAboard, // Sapient intelligence is aboard, cannot sell, would delete the organics
InvalidShip, // Ship is invalid
MessageOverwritten, // Overwritten message.
}

// TODO: swap to strictly being a formatted message.
public struct ShipyardSaleResult
{
public ShipyardSaleError Error; // Whether or not the ship can be sold.
public string? OrganicName; // In case an organic is aboard, this will be set to the first that's aboard.
public string? OverwrittenMessage; // The message to write if Error is MessageOverwritten.
}

public override void Initialize()
Expand Down
4 changes: 4 additions & 0 deletions Content.Server/_NF/Forensics/ForensicsCartridgeComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Content.Server._NF.Forensics;

[RegisterComponent]
public sealed partial class ForensicsCartridgeComponent : Component;
7 changes: 7 additions & 0 deletions Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
using Content.Shared._NF.GameRule;
using Content.Server.Procedural;
using Content.Shared.Bank.Components;
using Content.Server._NF.GameTicking.Events;
using Content.Server.GameTicking.Events;
using Content.Server.GameTicking.Rules.Components;
using Content.Shared.Procedural;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
Expand All @@ -23,6 +26,7 @@
using Robust.Shared.Random;
using Robust.Shared.Map.Components;
using Content.Shared.Shuttles.Components;
using Content.Server._NF.GameTicking.Events;
using Content.Server.Shuttles.Systems;
using Content.Server.Cargo.Components;
using Content.Server.GameTicking;
Expand Down Expand Up @@ -161,6 +165,9 @@ protected override void Started(EntityUid uid, AdventureRuleComponent component,

base.Started(uid, component, gameRule, args);

// Using invalid entity, we don't have a relevant entity to reference here.
RaiseLocalEvent(EntityUid.Invalid, new StationsGeneratedEvent(), broadcast: true); // TODO: attach this to a meaningful entity.

var dungenTypes = _prototypeManager.EnumeratePrototypes<DungeonConfigPrototype>();

foreach (var dunGen in dungenTypes)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Robust.Shared.Prototypes;

namespace Content.Server.GameTicking.Rules.VariationPass.Components;

/// <summary>
/// This handles generating round-start dead drop hints.
/// </summary>
[RegisterComponent]
public sealed partial class DeadDropHintVariationPassComponent : Component
{
/// <summary>
/// Chance that a potential hint will be generated on a table.
/// Remember, the average number
/// </summary>
[DataField]
public float HintSpawnChance = 0.02f;

/// <summary>
/// The entity to spawn for a hint.
/// </summary>
[DataField]
public EntProtoId HintSpawnPrototype = "PaperDeadDropHint";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Content.Server._NF.Smuggling.Components;
using Content.Server.GameTicking.Rules.VariationPass.Components;
using Content.Shared.Climbing.Components;
using Content.Shared.Placeable;

namespace Content.Server.GameTicking.Rules.VariationPass;

/// <inheritdoc cref="DeadDropHintVariationPassComponent"/>
public sealed class DeadDropHintVariationPass : VariationPassSystem<DeadDropHintVariationPassComponent>
{
protected override void ApplyVariation(Entity<DeadDropHintVariationPassComponent> ent, ref StationVariationPassEvent args)
{
if (HasComp<StationDeadDropHintExemptComponent>(args.Station))
return;

// Best query for table-like objects: bonkable filters out grills.
var query = AllEntityQuery<BonkableComponent, PlaceableSurfaceComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var _, out var _, out var xform))
{
if (!IsMemberOfStation((uid, xform), ref args))
continue;

var prob = Random.NextFloat();
if (prob < ent.Comp.HintSpawnChance)
{
SpawnAttachedTo(ent.Comp.HintSpawnPrototype, xform.Coordinates);
}
}
}
}
11 changes: 11 additions & 0 deletions Content.Server/_NF/GameTicking/SectorGeneratedEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Content.Server._NF.GameTicking.Events;

/// <summary>
/// Raised once all of the stations have been generated.
/// </summary>
public sealed class StationsGeneratedEvent : EntityEventArgs
{
public StationsGeneratedEvent()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Server._NF.Smuggling.Components;

/// <summary>
/// Denotes a grid that is brought in via a dead drop.
/// </summary>
[RegisterComponent]
public sealed partial class ContrabandPodGridComponent : Component
{
/// <summary>
/// Maximum number of dead drops to spawn on the station.
/// </summary>
[DataField]
public bool Scanned = false;
}
Loading

0 comments on commit aef511a

Please sign in to comment.