Skip to content

Commit

Permalink
Merge branch 'Goob-Station:master' into SpaceLaw-ATTEMPT2
Browse files Browse the repository at this point in the history
  • Loading branch information
CerberusWolfie authored Jan 16, 2025
2 parents 0559c03 + 243632a commit 7c2dea7
Show file tree
Hide file tree
Showing 1,124 changed files with 19,851 additions and 8,488 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-docfx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x

- name: Install dependencies
run: dotnet restore
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-map-renderer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x

- name: Install dependencies
run: dotnet restore
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-test-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x

- name: Install dependencies
run: dotnet restore
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x

- name: Get Engine Tag
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x

- name: Install dependencies
run: dotnet restore
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/yaml-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Setup .NET Core
uses: actions/[email protected]
with:
dotnet-version: 9.0.100
dotnet-version: 9.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
6 changes: 5 additions & 1 deletion Content.Client/Clothing/ClientClothingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,14 @@ private void RenderEquipment(EntityUid equipee, EntityUid equipment, string slot
return;
}

var displacementData = inventory.Displacements.GetValueOrDefault(slot);

if (clothingComponent.RenderLayer != null)
slot = clothingComponent.RenderLayer;

// temporary, until layer draw depths get added. Basically: a layer with the key "slot" is being used as a
// bookmark to determine where in the list of layers we should insert the clothing layers.
bool slotLayerExists = sprite.LayerMapTryGet(slot, out var index);
var displacementData = inventory.Displacements.GetValueOrDefault(slot);

// add the new layers
foreach (var (key, layerData) in ev.Layers)
Expand Down
10 changes: 9 additions & 1 deletion Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,15 @@ private void ReloadProfilePreview()
if (Profile == null || !_entManager.EntityExists(PreviewDummy))
return;

_entManager.System<HumanoidAppearanceSystem>().LoadProfile(PreviewDummy, Profile);
if (_entManager.TryGetComponent<HumanoidAppearanceComponent>(PreviewDummy, out var humanoid))
{
var hiddenLayers = humanoid.HiddenLayers;
var appearanceSystem = _entManager.System<HumanoidAppearanceSystem>();
appearanceSystem.LoadProfile(PreviewDummy, Profile, humanoid);
// Reapply the hidden layers set from clothing
appearanceSystem.SetLayersVisibility(PreviewDummy, hiddenLayers, false, humanoid: humanoid);
}

SetPreviewRotation(_previewRotation);
TraitsTabs.UpdateTabMerging();
LoadoutsTabs.UpdateTabMerging();
Expand Down
4 changes: 2 additions & 2 deletions Content.Server/Ensnaring/EnsnareableSystem.Ensnaring.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ public void ForceFree(EntityUid ensnare, EnsnaringComponent component)

var target = component.Ensnared.Value;

_container.Remove(ensnare, ensnareable.Container, force: true);
_container.TryRemoveFromContainer(ensnare, force: true); // Goobstation - fix on ensnare entity remove
ensnareable.IsEnsnared = ensnareable.Container.ContainedEntities.Count > 0;
Dirty(component.Ensnared.Value, ensnareable);
component.Ensnared = null;

UpdateAlert(target, ensnareable);
var ev = new EnsnareRemoveEvent(component.WalkSpeed, component.SprintSpeed);
RaiseLocalEvent(ensnare, ev);
RaiseLocalEvent(target, ev);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Content.Server._Goobstation.Interaction.Components;

/// <summary>
/// Allows use item with component on stations only
/// </summary>
[RegisterComponent]
public sealed partial class UseOnStationOnlyComponent : Component
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Content.Server._Goobstation.Interaction.Components;
using Content.Server.Popups;
using Content.Server.Station.Systems;
using Content.Shared._Goobstation.Interaction;

namespace Content.Server._Goobstation.Interaction.Systems;

public sealed partial class UseOnStationOnlySystem : EntitySystem
{
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly PopupSystem _popup = default!;

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

SubscribeLocalEvent<UseOnStationOnlyComponent, UseInHandAttemptEvent>(OnUseAttempt);
}

private void OnUseAttempt(Entity<UseOnStationOnlyComponent> item, ref UseInHandAttemptEvent args)
{
if (_station.GetOwningStation(args.User) is not null)
return;

_popup.PopupEntity(Loc.GetString("use-on-station-only-not-on-station"), args.User, args.User);
args.Cancel();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Content.Server._Goobstation.Spawn.Components;

/// <summary>
/// Ensures that related entity will be on station (like NTR or BSO lockers) and will be not duplicate.
/// If station have unique entity - item with this component will be deleted.
/// </summary>
[RegisterComponent]
public sealed partial class UniqueEntityCheckerComponent : Component
{
/// <summary>
/// Name of marker in UniqueEntityMarker
/// </summary>
[DataField]
public string? MarkerName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Content.Server._Goobstation.Spawn.Components;

/// <summary>
/// Component-marker for unique entity
/// </summary>
[RegisterComponent]
public sealed partial class UniqueEntityMarkerComponent : Component
{
/// <summary>
/// Marker name that would be used in check
/// </summary>
[DataField]
public string? MarkerName;

/// <summary>
/// If true - marker will work on grids with StationDataComponent
/// If false - marker will work globally
/// </summary>
[DataField]
public bool StationOnly = true;
}
43 changes: 43 additions & 0 deletions Content.Server/_Goobstation/Spawn/Systems/UniqueEntitySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Content.Server._Goobstation.Spawn.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;

namespace Content.Server._Goobstation.Spawn.Systems;

public sealed partial class UniqueEntitySystem : EntitySystem
{
[Dependency] private readonly StationSystem _station = default!;

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

SubscribeLocalEvent<UniqueEntityCheckerComponent, ComponentInit>(OnComponentInit);
}

public void OnComponentInit(Entity<UniqueEntityCheckerComponent> checker, ref ComponentInit args)
{
var comp = checker.Comp;

if (string.IsNullOrEmpty(comp.MarkerName))
return;

var query = EntityQueryEnumerator<UniqueEntityMarkerComponent, TransformComponent>();

while (query.MoveNext(out var uid, out var marker, out var xform))
{
if (string.IsNullOrEmpty(marker.MarkerName)
|| marker.MarkerName != comp.MarkerName
|| uid == checker.Owner)
continue;

// Check if marker on station
if (marker.StationOnly && _station.GetOwningStation(uid, xform) is null)
continue;

// Delete it if found unique entity
QueueDel(checker);
return;
}
}
}
2 changes: 1 addition & 1 deletion Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ public static readonly CVarDef<bool>
/// If you are intending to decrease the trait points availability, or modify the costs of traits, consider temporarily disabling this.
/// </summary>
public static readonly CVarDef<bool> TraitsPunishCheaters =
CVarDef.Create("game.traits_punish_cheaters", true, CVar.REPLICATED);
CVarDef.Create("game.traits_punish_cheaters", false, CVar.REPLICATED);

/// <summary>
/// Whether to allow characters to select loadout items.
Expand Down
7 changes: 7 additions & 0 deletions Content.Shared/Clothing/Components/ClothingComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ public sealed partial class ClothingComponent : Component
[Access(typeof(ClothingSystem), typeof(InventorySystem), Other = AccessPermissions.ReadExecute)]
public SlotFlags Slots = SlotFlags.NONE;

/// <summary>
/// The actual sprite layer to render this entity's equipped sprite to, overriding the layer determined by the slot.
/// </summary>
[DataField]
[Access(typeof(ClothingSystem))]
public string? RenderLayer;

[DataField]
public SoundSpecifier? EquipSound;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,11 @@ public sealed partial class HideLayerClothingComponent : Component
/// </summary>
[DataField]
public bool HideOnToggle = false;

/// <summary>
/// If true, the layer will always be hidden even if the layer
/// is not present in the equipee's HumanoidAppearanceComponent.HideLayerOnEquip field.
/// </summary>
[DataField]
public bool Force = false;
}
23 changes: 20 additions & 3 deletions Content.Shared/Clothing/EntitySystems/ClothingSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Content.Shared.Body.Part;
using Content.Shared.Body.Systems;
using Content.Shared.Clothing.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
Expand Down Expand Up @@ -30,6 +32,7 @@ public override void Initialize()
SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<ClothingComponent, ItemMaskToggledEvent>(OnMaskToggled);
SubscribeLocalEvent<ClothingComponent, GettingPickedUpAttemptEvent>(OnPickedUp);
SubscribeLocalEvent<HumanoidAppearanceComponent, BodyPartAddedEvent>(OnPartAttachedToBody, after: [typeof(SharedBodySystem)]);

SubscribeLocalEvent<ClothingComponent, ClothingEquipDoAfterEvent>(OnEquipDoAfter);
SubscribeLocalEvent<ClothingComponent, ClothingUnequipDoAfterEvent>(OnUnequipDoAfter);
Expand Down Expand Up @@ -88,11 +91,11 @@ private void QuickEquip(
}
}

private void ToggleVisualLayers(EntityUid equipee, HashSet<HumanoidVisualLayers> layers, HashSet<HumanoidVisualLayers> appearanceLayers)
private void ToggleVisualLayers(EntityUid equipee, HashSet<HumanoidVisualLayers> layers, HashSet<HumanoidVisualLayers> appearanceLayers, bool force = false)
{
foreach (HumanoidVisualLayers layer in layers)
{
if (!appearanceLayers.Contains(layer))
if (!force && !appearanceLayers.Contains(layer))
break;

InventorySystem.InventorySlotEnumerator enumerator = _invSystem.GetSlotEnumerator(equipee);
Expand Down Expand Up @@ -191,6 +194,20 @@ private void OnPickedUp(Entity<ClothingComponent> ent, ref GettingPickedUpAttemp
args.Cancel();
}

// Yes, this is exclusive C# just so that high heels selected from loadouts still hide the feet layers
// after Shitmed (SharedBodySystem.PartAppearance) initializes the feet parts setting their layer visibility to true.
private void OnPartAttachedToBody(Entity<HumanoidAppearanceComponent> ent, ref BodyPartAddedEvent args)
{
var enumerator = _invSystem.GetSlotEnumerator(ent.Owner);
while (enumerator.NextItem(out var item))
{
if (!TryComp<HideLayerClothingComponent>(item, out var comp))
continue;

CheckEquipmentForLayerHide(item, ent.Owner);
}
}

private void OnEquipDoAfter(Entity<ClothingComponent> ent, ref ClothingEquipDoAfterEvent args)
{
if (args.Handled || args.Cancelled || args.Target is not { } target)
Expand All @@ -210,7 +227,7 @@ private void OnUnequipDoAfter(Entity<ClothingComponent> ent, ref ClothingUnequip
private void CheckEquipmentForLayerHide(EntityUid equipment, EntityUid equipee)
{
if (TryComp(equipment, out HideLayerClothingComponent? clothesComp) && TryComp(equipee, out HumanoidAppearanceComponent? appearanceComp))
ToggleVisualLayers(equipee, clothesComp.Slots, appearanceComp.HideLayersOnEquip);
ToggleVisualLayers(equipee, clothesComp.Slots, appearanceComp.HideLayersOnEquip, clothesComp.Force);
}

#region Public API
Expand Down
13 changes: 13 additions & 0 deletions Content.Shared/Ensnaring/SharedEnsnareableSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,23 @@ public override void Initialize()
SubscribeLocalEvent<EnsnareableComponent, EnsnareEvent>(OnEnsnare);
SubscribeLocalEvent<EnsnareableComponent, EnsnareRemoveEvent>(OnEnsnareRemove);
SubscribeLocalEvent<EnsnareableComponent, EnsnaredChangedEvent>(OnEnsnareChange);
//SubscribeLocalEvent<EnsnaringComponent, ProjectileHitEvent>(OnProjectileHit); // Goobstation - TODO: add after ensnareable refactor
SubscribeLocalEvent<EnsnareableComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<EnsnareableComponent, ComponentHandleState>(OnHandleState);
}

// // Goobstation - TODO: add after ensnareable refactor
// private void OnProjectileHit(EntityUid uid, EnsnaringComponent component, ProjectileHitEvent args)
// {
// if (!component.CanThrowTrigger)
// return;
//
// if (TryEnsnare(args.Target, uid, component))
// {
// _audio.PlayPvs(component.EnsnareSound, uid);
// }
// }

private void OnHandleState(EntityUid uid, EnsnareableComponent component, ref ComponentHandleState args)
{
if (args.Current is not EnsnareableComponentState state)
Expand Down
9 changes: 9 additions & 0 deletions Content.Shared/Interaction/SharedInteractionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Content.Shared.CombatMode;
using Content.Shared.Database;
using Content.Shared.Ghost;
using Content.Shared._Goobstation.Interaction;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
using Content.Shared.Input;
Expand Down Expand Up @@ -1166,6 +1167,14 @@ public bool UseInHandInteraction(
if (checkCanUse && !_actionBlockerSystem.CanUseHeldEntity(user, used))
return false;

// Goobstation [
var useAttemptEv = new UseInHandAttemptEvent(user);
RaiseLocalEvent(used, useAttemptEv);

if (useAttemptEv.Cancelled)
return false;
// ] Goobstation

var useMsg = new UseInHandEvent(user);
RaiseLocalEvent(used, useMsg, true);
if (useMsg.Handled)
Expand Down
3 changes: 3 additions & 0 deletions Content.Shared/Preferences/HumanoidCharacterProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -478,14 +478,17 @@ public void EnsureValid(ICommonSession session, IDependencyCollection collection

var antags = AntagPreferences
.Where(id => prototypeManager.TryIndex<AntagPrototype>(id, out var antag) && antag.SetPreference)
.Distinct()
.ToList();

var traits = TraitPreferences
.Where(prototypeManager.HasIndex<TraitPrototype>)
.Distinct()
.ToList();

var loadouts = LoadoutPreferences
.Where(l => prototypeManager.HasIndex<LoadoutPrototype>(l.LoadoutName))
.Distinct()
.ToList();

Name = name;
Expand Down
9 changes: 9 additions & 0 deletions Content.Shared/_Goobstation/Interaction/InteractionEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Content.Shared._Goobstation.Interaction;

/// <summary>
/// UseAttempt, but for item.
/// </summary>
public sealed class UseInHandAttemptEvent(EntityUid user) : CancellableEntityEventArgs
{
public EntityUid User { get; } = user;
}
Loading

0 comments on commit 7c2dea7

Please sign in to comment.