Skip to content

Commit

Permalink
Deltamerge Part 1 (#1697)
Browse files Browse the repository at this point in the history
# Description

## **!!! DO NOT "Squash and commit", ONLY "Create a merge commit" !!!**

Merges a lot of PRs from Delta-V, most of these are plain YML changes so
they shouldn't cause wizmerge-like issues.
- DeltaV-Station/Delta-v#1008 
- DeltaV-Station/Delta-v#1077
- DeltaV-Station/Delta-v#1092
- DeltaV-Station/Delta-v#1094
- DeltaV-Station/Delta-v#1143
  - Excluded the lobby art with DeltaV branding.
- DeltaV-Station/Delta-v#1176
- DeltaV-Station/Delta-v#1209
- DeltaV-Station/Delta-v#1227
- DeltaV-Station/Delta-v#1252
- not directly cherry-picked due to harpy singing now being stored in a
different file, but implemented the same thing in
df50140
- DeltaV-Station/Delta-v#1261
- DeltaV-Station/Delta-v#1271
- DeltaV-Station/Delta-v#1272
- Also made available to Humans and Tajarans like the other Felinid
tails.
- DeltaV-Station/Delta-v#1426
- DeltaV-Station/Delta-v#1462
- DeltaV-Station/Delta-v#1542
- DeltaV-Station/Delta-v#1759
- DeltaV-Station/Delta-v#1763
- DeltaV-Station/Delta-v#1765
- DeltaV-Station/Delta-v#1780
- DeltaV-Station/Delta-v#1781
- DeltaV-Station/Delta-v#1804
- DeltaV-Station/Delta-v#1814
- TODO in another pr, vulp sprite for the colorable neck gaiter (PR only
adds vulp states to pre-existing black/red neck gaiters)
- DeltaV-Station/Delta-v#1828
  - Added to Loadouts for Corpsman, costs 2 points.
- DeltaV-Station/Delta-v#1838
- DeltaV-Station/Delta-v#1877
- DeltaV-Station/Delta-v#1905
  - Added to Loadout Uniforms, costs 1 point. 
- DeltaV-Station/Delta-v#1910
- DeltaV-Station/Delta-v#1935
- DeltaV-Station/Delta-v#1946
- DeltaV-Station/Delta-v#1994
- DeltaV-Station/Delta-v#1997
- DeltaV-Station/Delta-v#1998
- DeltaV-Station/Delta-v#2031
- DeltaV-Station/Delta-v#2089
- DeltaV-Station/Delta-v#2113
- DeltaV-Station/Delta-v#2213
- DeltaV-Station/Delta-v#2209
- DeltaV-Station/Delta-v#2210
- Prerequisite Wizden PR added:
space-wizards/space-station-14#29243
- Prerequisite Wizden PR added:
space-wizards/space-station-14#30856
- DeltaV-Station/Delta-v#2233
- DeltaV-Station/Delta-v#2245
- DeltaV-Station/Delta-v#2250
- DeltaV-Station/Delta-v#2266
- DeltaV-Station/Delta-v#2267
- DeltaV-Station/Delta-v#2294
- DeltaV-Station/Delta-v#2307
- DeltaV-Station/Delta-v#2318
- DeltaV-Station/Delta-v#2398
- DeltaV-Station/Delta-v#2410
- DeltaV-Station/Delta-v#2462
- DeltaV-Station/Delta-v#2478
- DeltaV-Station/Delta-v#2501
- DeltaV-Station/Delta-v#2503
- DeltaV-Station/Delta-v#2504
- Prerequisite Wizden PR added:
space-wizards/space-station-14#30957
- DeltaV-Station/Delta-v#2524
- DeltaV-Station/Delta-v#2539
- DeltaV-Station/Delta-v#2635
- Prerequisite Wizden PR added:
space-wizards/space-station-14#32193
- Prerequisite Wizden PR added:
space-wizards/space-station-14#32327

## Changelog

Too much changes to count so some changes are unlisted

:cl: Several Contributors
- add: Added Lone Digger by Caravan Palace to the jukebox! (by MilonPL)
- add: Added Deck The Halls by Kevin Macleod to the jukebox! (by
Lyndomen)
- tweak: Now medical belts have a slot for medkits. (by Radezolid)
- add: Added a way for muskets, flintlocks, and musket cartridges (NOT
.60) to be crafted. (by Tryded)
- add: Added Vulpkanin-specific sprites to a lot of helmets and masks.
(by Adrian16199, TadJohnson00)
- add: Security dogs (such as Laika) now have Vulpkanin vocal emotes.
Howl! (by Remuchi)
- add: Split the Emag into the Cryptographic Sequencer and the Airlock
Access Override. (by Warmechanic)
- add: Added Corpsman Glasses, no more getting flashed as Corpsman! Also
available in Loadouts. (by Unkn0wnGh0st333)
- add: Harpies can now mimic harps! (by TheOneWhoIsManyFrame)
- tweak: Cats will now play with mouse toys. (by Deltanedas)
- add: Added a black turtleneck, available in Loadouts! (by Aikakakah)
- add: Added the Binary Translator Key to the uplink costing 1 TC and
the listening post operative headset. (by Radezolid)
- add: Spesos now have a new pretty look transferred from the Frontier
Station. (by whatston3)
- add: The home-run bat has been re-added to the traitor uplink.
- add: Added the CrystalThistle, mutated from the Galaxythistle that
generates Quartzite which when heated produces glass sheets. (by
jimmy12or)
- add: Added a Ghost Pepper! A friendly looking Pepper that's so Spicy,
it hurts! (by jimmy12or)
- add: Added a Cosmic Revenant! A spooky mutation of the Ghost pepper
that produced Ectoplasm. (by jimmy12or)
- add: Added blue and purple tomato soup, made using Blue Tomatoes. (by
DisposableCrewmember42)
- add: Added new drinks: the double ice cream (by dge21) and Dr. Gibb
Blood Red (by BlitzTheSquishy).
- add: Some drink reactions now require shaking with the shaker or
stirring with a spoon. (by Vermidia)
- add: Added "Selene" wing customization option for moths (by
boogiebogus)
- add: Added the tiger tail sprite for Felinids, Humans and Tajarans.
(by Adrian16199)
- add: NanoTrasen has established business relations with HydroCo! You
can now order powdered milk and juice via your Logistics department. (by
DisposableCrewmember42)
- tweak: Bar and kitchen shelves no longer restrict the items that can
be placed in them. (by Velcroboy)
- tweak: Bookshelves can now fit any kind of item, not just books. (by
Deltanedas)
- add: New magic crayons have appeared in the sector, artists rejoice!
(by AvalonProto)
  • Loading branch information
sleepyyapril authored Feb 4, 2025
2 parents 5920082 + 5d5fdbe commit 9901f46
Show file tree
Hide file tree
Showing 339 changed files with 4,607 additions and 371 deletions.
11 changes: 11 additions & 0 deletions Content.Client/Crayon/CrayonSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ protected override void FrameUpdate(FrameEventArgs args)
}

_parent.UIUpdateNeeded = false;

// Frontier: unlimited crayon, Delta V Port
if (_parent.Capacity == int.MaxValue)
{
_label.SetMarkup(Robust.Shared.Localization.Loc.GetString("crayon-drawing-label-unlimited",
("color", _parent.Color),
("state", _parent.SelectedState)));
return;
}
// End Frontier, Delta V Port

_label.SetMarkup(Robust.Shared.Localization.Loc.GetString("crayon-drawing-label",
("color",_parent.Color),
("state",_parent.SelectedState),
Expand Down
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;
}
}
}
8 changes: 8 additions & 0 deletions Content.Packaging/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"profiles": {
"WSL": {
"commandName": "WSL2",
"distributionName": ""
}
}
}
57 changes: 47 additions & 10 deletions Content.Server/Chemistry/EntitySystems/ReactionMixerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.DoAfter;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Nutrition.EntitySystems;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Popups;

Expand All @@ -10,34 +13,68 @@ public sealed partial class ReactionMixerSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainers = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ReactionMixerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<ReactionMixerComponent, ShakeEvent>(OnShake);
SubscribeLocalEvent<ReactionMixerComponent, ReactionMixDoAfterEvent>(OnDoAfter);
}

private void OnAfterInteract(Entity<ReactionMixerComponent> entity, ref AfterInteractEvent args)
{
if (!args.Target.HasValue || !args.CanReach)
if (!args.Target.HasValue || !args.CanReach || !entity.Comp.MixOnInteract)
return;

var mixAttemptEvent = new MixingAttemptEvent(entity);
RaiseLocalEvent(entity, ref mixAttemptEvent);
if (mixAttemptEvent.Cancelled)
{
if (!MixAttempt(entity, args.Target.Value, out var solution))
return;
}

if (!_solutionContainers.TryGetMixableSolution(args.Target.Value, out var solution, out _))
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, entity.Comp.TimeToMix, new ReactionMixDoAfterEvent(), entity, args.Target.Value, entity);

_doAfterSystem.TryStartDoAfter(doAfterArgs);
}

private void OnDoAfter(Entity<ReactionMixerComponent> entity, ref ReactionMixDoAfterEvent args)
{
//Do again to get the solution again
if (!MixAttempt(entity, args.Target!.Value, out var solution))
return;

_popup.PopupEntity(Loc.GetString(entity.Comp.MixMessage, ("mixed", Identity.Entity(args.Target.Value, EntityManager)), ("mixer", Identity.Entity(entity.Owner, EntityManager))), args.User, args.User);
_popup.PopupEntity(Loc.GetString(entity.Comp.MixMessage, ("mixed", Identity.Entity(args.Target!.Value, EntityManager)), ("mixer", Identity.Entity(entity.Owner, EntityManager))), args.User, args.User);

_solutionContainers.UpdateChemicals(solution!.Value, true, entity.Comp);

var afterMixingEvent = new AfterMixingEvent(entity, args.Target!.Value);
RaiseLocalEvent(entity, afterMixingEvent);
}

private void OnShake(Entity<ReactionMixerComponent> entity, ref ShakeEvent args)
{
if (!MixAttempt(entity, entity, out var solution))
return;

_solutionContainers.UpdateChemicals(solution.Value, true, entity.Comp);
_solutionContainers.UpdateChemicals(solution!.Value, true, entity.Comp);

var afterMixingEvent = new AfterMixingEvent(entity, args.Target.Value);
var afterMixingEvent = new AfterMixingEvent(entity, entity);
RaiseLocalEvent(entity, afterMixingEvent);
}

private bool MixAttempt(EntityUid ent, EntityUid target, out Entity<SolutionComponent>? solution)
{
solution = null;
var mixAttemptEvent = new MixingAttemptEvent(ent);
RaiseLocalEvent(ent, ref mixAttemptEvent);
if (mixAttemptEvent.Cancelled)
{
return false;
}

if (!_solutionContainers.TryGetMixableSolution(target, out solution, out _))
return false;

return true;
}
}
11 changes: 8 additions & 3 deletions Content.Server/Crayon/CrayonSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,14 @@ private void OnCrayonAfterInteract(EntityUid uid, CrayonComponent component, Aft
if (component.UseSound != null)
_audio.PlayPvs(component.UseSound, uid, AudioParams.Default.WithVariation(0.125f));

// Decrease "Ammo"
component.Charges--;
Dirty(uid, component);
// Frontier: check if crayon is infinite, Delta V Port
if (component.Charges != int.MaxValue)
{
// Decrease "Ammo"
component.Charges--;
Dirty(uid, component);
}
// End Frontier, Delta V Port

_adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{EntityManager.ToPrettyString(args.User):user} drew a {component.Color:color} {component.SelectedState}");
args.Handled = true;
Expand Down
21 changes: 21 additions & 0 deletions Content.Shared/Chemistry/Reaction/ReactionMixerComponent.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.DoAfter;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;

namespace Content.Shared.Chemistry.Reaction;

Expand All @@ -19,9 +21,28 @@ public sealed partial class ReactionMixerComponent : Component
[ViewVariables]
[DataField]
public LocId MixMessage = "default-mixing-success";

/// <summary>
/// Defines if interacting is enough to mix with this component
/// </summary>
[ViewVariables]
[DataField]
public bool MixOnInteract = true;

/// <summary>
/// How long it takes to mix with this
/// </summary>
[ViewVariables]
[DataField]
public TimeSpan TimeToMix = TimeSpan.Zero;
}

[ByRefEvent]
public record struct MixingAttemptEvent(EntityUid Mixed, bool Cancelled = false);

public readonly record struct AfterMixingEvent(EntityUid Mixed, EntityUid Mixer);

[Serializable, NetSerializable]
public sealed partial class ReactionMixDoAfterEvent : SimpleDoAfterEvent
{
}
15 changes: 15 additions & 0 deletions Content.Shared/Emag/Components/EmagComponent.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Content.Shared.Emag.Systems;
using Content.Shared.Tag;
using Content.Shared.Whitelist;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization;
Expand All @@ -17,4 +18,18 @@ public sealed partial class EmagComponent : Component
[DataField("emagImmuneTag", customTypeSerializer: typeof(PrototypeIdSerializer<TagPrototype>)), ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public string EmagImmuneTag = "EmagImmune";

// DeltaV - Add a whitelist/blacklist to the Emag
/// <summary>
/// Whitelist that entities must be on to work.
/// </summary>
[DataField]
public EntityWhitelist? Whitelist;

/// <summary>
/// Blacklist that entities must be off to work.
/// </summary>
[DataField]
public EntityWhitelist? Blacklist;
// End of DeltaV code
}
11 changes: 11 additions & 0 deletions Content.Shared/Emag/Systems/EmagSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Content.Shared.Popups;
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Tag;
using Content.Shared.Whitelist;

namespace Content.Shared.Emag.Systems;

Expand All @@ -23,6 +24,7 @@ public sealed class EmagSystem : EntitySystem
[Dependency] private readonly SharedChargesSystem _charges = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!; // DeltaV - Add a whitelist/blacklist to the Emag

public override void Initialize()
{
Expand Down Expand Up @@ -50,6 +52,15 @@ public bool TryUseEmag(EntityUid uid, EntityUid user, EntityUid target, EmagComp
if (_tag.HasTag(target, comp.EmagImmuneTag))
return false;

// DeltaV - Add a whitelist / blacklist to the Emag
if (_whitelist.IsWhitelistFail(comp.Whitelist, target)
|| _whitelist.IsBlacklistPass(comp.Blacklist, target))
{
_popup.PopupClient(Loc.GetString("emag-invalid-target", ("emag", uid), ("target", target)), user, user);
return false;
}
// End of DeltaV code

TryComp<LimitedChargesComponent>(uid, out var charges);
if (_charges.IsEmpty(uid, charges))
{
Expand Down
4 changes: 3 additions & 1 deletion Content.Shared/EntityTable/EntitySelectors/EntSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ namespace Content.Shared.EntityTable.EntitySelectors;
/// </summary>
public sealed partial class EntSelector : EntityTableSelector
{
[DataField(required: true)]
public const string IdDataFieldTag = "id";

[DataField(IdDataFieldTag, required: true)]
public EntProtoId Id;

[DataField]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.TypeSerializers.Interfaces;

namespace Content.Shared.EntityTable.EntitySelectors;

[TypeSerializer]
public sealed class EntityTableTypeSerializer :
ITypeReader<EntityTableSelector, MappingDataNode>
{
public ValidationNode Validate(ISerializationManager serializationManager,
MappingDataNode node,
IDependencyCollection dependencies,
ISerializationContext? context = null)
{
if (node.Has(EntSelector.IdDataFieldTag))
return serializationManager.ValidateNode<EntSelector>(node, context);

return new ErrorNode(node, "Custom validation not supported! Please specify the type manually!");
}

public EntityTableSelector Read(ISerializationManager serializationManager,
MappingDataNode node,
IDependencyCollection dependencies,
SerializationHookContext hookCtx,
ISerializationContext? context = null,
ISerializationManager.InstantiationDelegate<EntityTableSelector>? instanceProvider = null)
{
var type = typeof(EntityTableSelector);
if (node.Has(EntSelector.IdDataFieldTag))
type = typeof(EntSelector);

return (EntityTableSelector) serializationManager.Read(type, node, context)!;
}
}
Loading

0 comments on commit 9901f46

Please sign in to comment.