Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

Up150624 #308

Merged
merged 17 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions Content.Client/Stack/StackSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Content.Client.Stack
{
[UsedImplicitly]
public sealed class StackSystem : SharedStackSystem
public sealed partial class StackSystem : SharedStackSystem // Frontier: add partial to class definition
{
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly ItemCounterSystem _counterSystem = default!;
Expand Down Expand Up @@ -56,20 +56,25 @@ private void OnAppearanceChange(EntityUid uid, StackComponent comp, ref Appearan
if (args.Sprite == null || comp.LayerStates.Count < 1)
return;

StackLayerData data = new StackLayerData(); // Frontier: use structure to store StackLayerData

// Skip processing if no actual
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out var actual, args.Component))
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out data.Actual, args.Component))
return;

if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out var maxCount, args.Component))
maxCount = comp.LayerStates.Count;
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out data.MaxCount, args.Component))
data.MaxCount = comp.LayerStates.Count;

if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out data.Hidden, args.Component))
data.Hidden = false;

if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out var hidden, args.Component))
hidden = false;
if (comp.LayerFunction != StackLayerFunction.None) // Frontier: use stack layer function to modify appearance if provided.
ApplyLayerFunction(uid, comp, ref data); // Frontier: definition in _NF/Stack/StackSystem.Layers.cs

if (comp.IsComposite)
_counterSystem.ProcessCompositeSprite(uid, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
_counterSystem.ProcessCompositeSprite(uid, data.Actual, data.MaxCount, comp.LayerStates, data.Hidden, sprite: args.Sprite);
else
_counterSystem.ProcessOpaqueSprite(uid, comp.BaseLayer, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
_counterSystem.ProcessOpaqueSprite(uid, comp.BaseLayer, data.Actual, data.MaxCount, comp.LayerStates, data.Hidden, sprite: args.Sprite);
}
}
}
56 changes: 56 additions & 0 deletions Content.Client/_NF/Stack/StackSystem.Layers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Content.Shared.Stacks.Components;
using Content.Shared.Stacks;

namespace Content.Client.Stack
{
/// <summary>
/// Data used to determine which layers of a stack's sprite are visible.
/// </summary>
public struct StackLayerData
{
public int Actual;
public int MaxCount;
public bool Hidden;
}

public sealed partial class StackSystem : SharedStackSystem
{
// Modifies a given stack component to adjust the layers to display.
private bool ApplyLayerFunction(EntityUid uid, StackComponent comp, ref StackLayerData data)
{
switch (comp.LayerFunction)
{
case StackLayerFunction.Threshold:
if (TryComp<StackLayerThresholdComponent>(uid, out var threshold))
{
ApplyThreshold(threshold, ref data);
return true;
}
break;
}
// No function applied.
return false;
}

/// <summary>
/// Sets Actual to the number of thresholds that Actual exceeds from the beginning of the list.
/// Sets MaxCount to the total number of thresholds plus one (for values under thresholds).
/// </summary>
private static void ApplyThreshold(StackLayerThresholdComponent comp, ref StackLayerData data)
{
// We must stop before we run out of thresholds or layers, whichever's smaller.
data.MaxCount = Math.Min(comp.Thresholds.Count + 1, data.MaxCount);
int newActual = 0;
foreach (var threshold in comp.Thresholds)
{
//If our value exceeds threshold, the next layer should be displayed.
//Note: we must ensure actual <= MaxCount.
if (data.Actual >= threshold && newActual < data.MaxCount)
newActual++;
else
break;
}
data.Actual = newActual;
}
}
}
10 changes: 10 additions & 0 deletions Content.Server/Body/Components/MetabolizerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ public sealed partial class MetabolizerComponent : Component
[DataField("maxReagents")]
public int MaxReagentsProcessable = 3;

/// <summary>
/// Frontier
///
/// How many poisons can this metabolizer process at once?
/// Used to nerf 'stacked poisons' where having 5+ different poisons in a syringe, even at low
/// quantity, would be muuuuch better than just one poison acting.
/// </summary>
[DataField("maxPoisons")]
public int MaxPoisonsProcessable = 3;

/// <summary>
/// A list of metabolism groups that this metabolizer will act on, in order of precedence.
/// </summary>
Expand Down
17 changes: 9 additions & 8 deletions Content.Server/Body/Systems/MetabolizerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private void TryMetabolize(Entity<MetabolizerComponent, OrganComponent?, Solutio
var list = solution.Contents.ToArray();
_random.Shuffle(list);

int reagents = 0;
int poisons = 0; // frontier modified
foreach (var (reagent, quantity) in list)
{
if (!_prototypeManager.TryIndex<ReagentPrototype>(reagent.Prototype, out var proto))
Expand All @@ -158,10 +158,10 @@ private void TryMetabolize(Entity<MetabolizerComponent, OrganComponent?, Solutio

continue;
}

// we're done here entirely if this is true
if (reagents >= ent.Comp1.MaxReagentsProcessable)
return;
// frontier modified
// Already processed all poisons, skip to the next reagent.
if (poisons >= ent.Comp1.MaxPoisonsProcessable && proto.Metabolisms.ContainsKey("Poison"))
continue;


// loop over all our groups and see which ones apply
Expand Down Expand Up @@ -219,9 +219,10 @@ private void TryMetabolize(Entity<MetabolizerComponent, OrganComponent?, Solutio
if (mostToRemove > FixedPoint2.Zero)
{
solution.RemoveReagent(reagent, mostToRemove);

// We have processed a reagant, so count it towards the cap
reagents += 1;
// frontier modified
// We have processed a poison, so count it towards the cap
if (proto.Metabolisms.ContainsKey("Poison"))
poisons++;
}
}

Expand Down
10 changes: 9 additions & 1 deletion Content.Server/Medical/CryoPodSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,15 @@ public override void Update(float frameTime)
continue;
}

var solutionToInject = _solutionContainerSystem.SplitSolution(containerSolution.Value, cryoPod.BeakerTransferAmount);
// frontier

// Filter out a fixed amount of each reagent from the cryo pod's beaker
var solutionToInject = _solutionContainerSystem.SplitSolutionReagentsEvenly(containerSolution.Value, cryoPod.BeakerTransferAmount);
// for every .25 units used, .5 units per second are added to the body, making cryo-pod more efficient than injections
solutionToInject.ScaleSolution(cryoPod.PotencyMultiplier);

// End frontier

_bloodstreamSystem.TryAddToChemicals(patient.Value, solutionToInject, bloodstream);
_reactiveSystem.DoEntityReaction(patient.Value, solutionToInject, ReactionMethod.Injection);
}
Expand Down
38 changes: 21 additions & 17 deletions Content.Server/Nyanotrasen/Mail/Components/MailComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@ namespace Content.Server.Mail.Components
[RegisterComponent]
public sealed partial class MailComponent : SharedMailComponent
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("recipient")]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string Recipient = "None";

[ViewVariables(VVAccess.ReadWrite)]
[DataField("recipientJob")]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string RecipientJob = "None";

[ViewVariables(VVAccess.ReadWrite)]
[DataField("recipientStation")]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string RecipientStation = "None";

// Why do we not use LockComponent?
// Because this can't be locked again,
// and we have special conditions for unlocking,
// and we don't want to add a verb.
[ViewVariables(VVAccess.ReadWrite)]
[DataField("isLocked")]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool IsLocked = true;

/// <summary>
Expand All @@ -36,7 +32,7 @@ public sealed partial class MailComponent : SharedMailComponent
/// This is useful for broken fragile packages and packages that were
/// not delivered in time.
/// </remarks>
[DataField("isProfitable")]
[DataField]
public bool IsProfitable = true;

/// <summary>
Expand All @@ -46,7 +42,7 @@ public sealed partial class MailComponent : SharedMailComponent
/// This can be set to true in the YAML files for a mail delivery to
/// always be Fragile, despite its contents.
/// </remarks>
[DataField("isFragile")]
[DataField]
public bool IsFragile = false;

/// <summary>
Expand All @@ -62,43 +58,51 @@ public sealed partial class MailComponent : SharedMailComponent
/// This can be set to true in the YAML files for a mail delivery to
/// always be Priority.
/// </remarks>
[DataField("isPriority")]
[DataField]
public bool IsPriority = false;

// Frontier: large mail
/// <summary>
/// Whether this parcel is large.
/// </summary>
[DataField]
public bool IsLarge = false;
// End Frontier: large mail

/// <summary>
/// What will be packaged when the mail is spawned.
/// </summary>
[DataField("contents")]
[DataField]
public List<EntitySpawnEntry> Contents = new();

/// <summary>
/// The amount that cargo will be awarded for delivering this mail.
/// </summary>
[DataField("bounty")]
[DataField]
public int Bounty = 7500; // Frontier 750<7500

/// <summary>
/// Penalty if the mail is destroyed.
/// </summary>
[DataField("penalty")]
[DataField]
public int Penalty = -250;

/// <summary>
/// The sound that's played when the mail's lock is broken.
/// </summary>
[DataField("penaltySound")]
[DataField]
public SoundSpecifier PenaltySound = new SoundPathSpecifier("/Audio/Machines/Nuke/angry_beep.ogg");

/// <summary>
/// The sound that's played when the mail's opened.
/// </summary>
[DataField("openSound")]
[DataField]
public SoundSpecifier OpenSound = new SoundPathSpecifier("/Audio/Effects/packetrip.ogg");

/// <summary>
/// The sound that's played when the mail's lock has been emagged.
/// </summary>
[DataField("emagSound")]
[DataField]
public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks");

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public sealed partial class MailTeleporterComponent : Component
/// teleporter can deliver.
/// </summary>
[DataField("mailPool")]
public string MailPool = "RandomMailDeliveryPool";
public string MailPool = "RandomNFMailDeliveryPool"; // Frontier: use our own mail pool (TODO: migrate to frontier.yml instance?)

/// <summary>
/// How many mail candidates do we need per actual delivery sent when
Expand Down Expand Up @@ -104,5 +104,19 @@ public sealed partial class MailTeleporterComponent : Component
/// </summary>
[DataField("priorityMalus")]
public int PriorityMalus = -250;

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

/// <summary>
/// What's the malus for failing to deliver a large package?
/// </summary>
[DataField("largeMalus")]
public int LargeMalus = -250;
// End Frontier: Large mail
}
}
20 changes: 16 additions & 4 deletions Content.Server/Nyanotrasen/Mail/MailCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public sealed class MailToCommand : IConsoleCommand
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;

private readonly string _blankMailPrototype = "MailAdminFun";
private readonly string _blankLargeMailPrototype = "MailLargeAdminFun"; // Frontier: large mail
private readonly string _container = "storagebase";
private readonly string _mailContainer = "contents";

Expand Down Expand Up @@ -56,6 +57,16 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

// Frontier: Large Mail
bool isLarge = false;
if (args.Length > 4 && !Boolean.TryParse(args[4], out isLarge))
{
shell.WriteError(Loc.GetString("shell-invalid-bool"));
return;
}
var mailPrototype = isLarge ? _blankLargeMailPrototype : _blankMailPrototype;
// End Frontier


var _mailSystem = _entitySystemManager.GetEntitySystem<MailSystem>();
var _containerSystem = _entitySystemManager.GetEntitySystem<SharedContainerSystem>();
Expand All @@ -66,9 +77,9 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

if (!_prototypeManager.HasIndex<EntityPrototype>(_blankMailPrototype))
if (!_prototypeManager.HasIndex<EntityPrototype>(mailPrototype)) // Frontier: _blankMailPrototype<mailPrototype
{
shell.WriteLine(Loc.GetString("command-mailto-no-blankmail", ("blankMail", _blankMailPrototype)));
shell.WriteLine(Loc.GetString("command-mailto-no-blankmail", ("blankMail", mailPrototype))); // Frontier: _blankMailPrototype<mailPrototype
return;
}

Expand All @@ -90,12 +101,12 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

var mailUid = _entityManager.SpawnEntity(_blankMailPrototype, _entityManager.GetComponent<TransformComponent>(containerUid).Coordinates);
var mailUid = _entityManager.SpawnEntity(mailPrototype, _entityManager.GetComponent<TransformComponent>(containerUid).Coordinates); // Frontier: _blankMailPrototype<mailPrototype
var mailContents = _containerSystem.EnsureContainer<Container>(mailUid, _mailContainer);

if (!_entityManager.TryGetComponent(mailUid, out MailComponent? mailComponent))
{
shell.WriteLine(Loc.GetString("command-mailto-bogus-mail", ("blankMail", _blankMailPrototype), ("requiredMailComponent", nameof(MailComponent))));
shell.WriteLine(Loc.GetString("command-mailto-bogus-mail", ("blankMail", mailPrototype), ("requiredMailComponent", nameof(MailComponent)))); // Frontier: _blankMailPrototype<mailPrototype
return;
}

Expand All @@ -104,6 +115,7 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)

mailComponent.IsFragile = isFragile;
mailComponent.IsPriority = isPriority;
mailComponent.IsLarge = isLarge;

_mailSystem.SetupMail(mailUid, teleporterComponent, recipient.Value);

Expand Down
Loading
Loading