Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jannie qol #6

Merged
merged 2 commits into from
Feb 16, 2025
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
51 changes: 51 additions & 0 deletions Content.Client/_White/ItemSlotPicker/ItemSlotPickerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Content.Shared._White.ItemSlotPicker;
using Content.Shared.Interaction;
using Content.Shared._White.ItemSlotPicker.UI;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Shared.Containers;
using Robust.Shared.Timing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Content.Client._White.ItemSlotPicker;

public sealed class ItemSlotPickerSystem : SharedItemSlotPickerSystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IGameTiming _timing = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ItemSlotPickerComponent, EntInsertedIntoContainerMessage>(EntInserted);
SubscribeLocalEvent<ItemSlotPickerComponent, EntRemovedFromContainerMessage>(EntRemoved);
}

private void EntInserted(EntityUid uid, ItemSlotPickerComponent comp, EntInsertedIntoContainerMessage args)
{
if (!_timing.IsFirstTimePredicted ||
_player.LocalEntity is not EntityUid player ||
!_ui.IsUiOpen(uid, ItemSlotPickerKey.Key, player))
return;
var msg = new ItemSlotPickerContentsChangedMessage();
msg.Actor = player;
_ui.RaiseUiMessage(uid, ItemSlotPickerKey.Key, msg);
}

private void EntRemoved(EntityUid uid, ItemSlotPickerComponent comp, EntRemovedFromContainerMessage args)
{
if (!_timing.IsFirstTimePredicted ||
_player.LocalEntity is not EntityUid player ||
!_ui.IsUiOpen(uid, ItemSlotPickerKey.Key, player))
return;
var msg = new ItemSlotPickerContentsChangedMessage();
msg.Actor = player;
_ui.RaiseUiMessage(uid, ItemSlotPickerKey.Key, msg);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
using Content.Client.Chat.UI;
using Content.Client.UserInterface.Controls;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Timing;
using static Robust.Client.UserInterface.Control;
using System.Numerics;
using Content.Shared._White.ItemSlotPicker;
using Content.Shared._White.ItemSlotPicker.UI;

namespace Content.Client._White.ItemSlotPicker.UI;

// a UFO came by and left this message here
[UsedImplicitly]
public sealed class ItemSlotPickerBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IEyeManager _eye = default!;

private readonly ItemSlotsSystem _itemSlots;
private readonly SharedTransformSystem _transform;

private RadialMenu? _menu;
private RadialContainer? _layer;

public ItemSlotPickerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
_itemSlots = EntMan.System<ItemSlotsSystem>();
_transform = EntMan.System<SharedTransformSystem>();
}

protected override void Open()
{
_menu = new EntityCenteredRadialMenu(Owner);
_menu.OnClose += Close;
_menu.CloseButtonStyleClass = "RadialMenuCloseButton";
_menu.BackButtonStyleClass = "RadialMenuBackButton";

UpdateLayer();
_menu.OpenCenteredAt(_eye.WorldToScreen(_transform.GetWorldPosition(Owner)) / _clyde.ScreenSize);
}

private void UpdateLayer()
{
var picker = EntMan.GetComponent<ItemSlotPickerComponent>(Owner);
if (_layer is not null)
_menu!.RemoveChild(_layer);

_layer = new RadialContainer();
foreach (var slotID in picker.ItemSlots)
{
if (!_itemSlots.TryGetSlot(Owner, slotID, out var slot) ||
!slot.HasItem)
continue;

// i see no value in having 99 different radial button types with the only difference being what data they hold
// hence i'm just setting all relevant parameters after constructing the button.
var button = new RadialMenuTextureButton
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = Loc.GetString(slot.Name),
};

var tex = new TextureRect
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = EntMan.GetComponent<SpriteComponent>(slot.Item!.Value).Icon?.Default,
TextureScale = new Vector2(2f, 2f),
};

button.AddChild(tex);
button.OnButtonUp += _ => { SendPredictedMessage(new ItemSlotPickerSlotPickedMessage(slotID)); };
_layer.AddChild(button);
}
_menu!.AddChild(_layer);
}

protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
if (message is not ItemSlotPickerContentsChangedMessage)
return;
UpdateLayer();
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;

_menu?.Dispose();
}
}

[Virtual]
public class EntityCenteredRadialMenu : RadialMenu
{
public EntityUid Entity;
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IEyeManager _eye = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
private readonly SharedTransformSystem _transform;

private Vector2 _cachedPos;

public EntityCenteredRadialMenu(EntityUid entity) : base()
{
Entity = entity;
IoCManager.InjectDependencies(this);
_transform = _entMan.System<SharedTransformSystem>();
}

public EntityCenteredRadialMenu(EntityUid entity, IEntityManager man, IEyeManager eye, IClyde clyde) : base()
{
Entity = entity;
_clyde = clyde;
_entMan = man;
_eye = eye;
_transform = _entMan.System<SharedTransformSystem>();
}


protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_entMan.Deleted(Entity) ||
!_entMan.TryGetComponent<TransformComponent>(Entity, out var transform))
return;
var pos = _eye.WorldToScreen(_transform.GetWorldPosition(Entity)) / _clyde.ScreenSize;
if (pos == _cachedPos)
return;
_cachedPos = pos;
RecenterWindow(pos);
}
}
5 changes: 5 additions & 0 deletions Content.Server/_White/ItemSlotPicker/ItemSlotPickerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Content.Shared._White.ItemSlotPicker;

namespace Content.Server._White.ItemSlotPicker;

public sealed class ItemSlotPickerSystem : SharedItemSlotPickerSystem;
21 changes: 21 additions & 0 deletions Content.Shared/Interaction/SharedInteractionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,8 @@ public bool UseInHandInteraction(
return InteractionActivate(user, used, false, false, false);
}



/// <summary>
/// Alternative interactions on an entity.
/// </summary>
Expand All @@ -1198,6 +1200,19 @@ public bool UseInHandInteraction(
/// <returns>True if the interaction was handled, false otherwise.</returns>
public bool AltInteract(EntityUid user, EntityUid target)
{
// WD EDIT START
// yeah, this is a crutch for stuff that should only be "alt-interacted"
// on a click, instead of showing it in the menu.
// Because of that, such interaction should not be obscured by a "higher priority" altverb,
// lest it becomes completely unavailable. Thus, it is relegated to a separate event,
// fired before looking for altverbs.
// Look upon my shit, and despair.
var ev = new AlternativeInteractionEvent(user);
RaiseLocalEvent(target, ev);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тебе тут нужен ref

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не нужен, ивент не struct

if (ev.Handled)
return true;
// WD EDIT END

// Get list of alt-interact verbs
var verbs = _verbSystem.GetLocalVerbs(target, user, typeof(AlternativeVerb)).Where(verb => ((AlternativeVerb) verb).InActiveHandOnly == false); // WD EDIT

Expand Down Expand Up @@ -1440,6 +1455,12 @@ public bool SupportsComplexInteractions(EntityUid user)
return _actionBlockerSystem.CanComplexInteract(user);
}
}
// WWDP EDIT START
public sealed class AlternativeInteractionEvent(EntityUid user) : HandledEntityEventArgs
{
public EntityUid User = user;
}
// WWDP EDIT END

/// <summary>
/// Raised when a player attempts to activate an item in an inventory slot or hand slot
Expand Down
4 changes: 2 additions & 2 deletions Content.Shared/Storage/Components/SharedMapLayerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public sealed partial class SharedMapLayerData
{
public string Layer = string.Empty;

[DataField("whitelist", required: true, serverOnly: true)]
public EntityWhitelist ServerWhitelist { get; set; } = new();
[DataField("whitelist", required: true)] // WWDP EDIT FORMELY ServerWhiteList
public EntityWhitelist Whitelist { get; set; } = new(); // WHO THE FUCK MADE IT SERVERONLY AND WHY

/// <summary>
/// Minimal amount of entities that are valid for whitelist.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private bool TryGetLayers(EntityUid uid,
var list = new List<string>();
foreach (var mapLayerData in itemMapper.MapLayers.Values)
{
var count = containedLayers.Count(ent => _whitelistSystem.IsWhitelistPass(mapLayerData.ServerWhitelist, ent));
var count = containedLayers.Count(ent => _whitelistSystem.IsWhitelistPass(mapLayerData.Whitelist, ent)); // WWDP EDIT ServerWhiteList -> Whitelist
if (count >= mapLayerData.MinCount && count <= mapLayerData.MaxCount)
{
list.Add(mapLayerData.Layer);
Expand Down
17 changes: 17 additions & 0 deletions Content.Shared/_White/ItemSlotPicker/ItemSlotPickerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Robust.Shared.GameStates;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Content.Shared._White.ItemSlotPicker;

[RegisterComponent]
[NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ItemSlotPickerComponent : Component
{
[DataField]
[AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public List<string> ItemSlots = new();
}
66 changes: 66 additions & 0 deletions Content.Shared/_White/ItemSlotPicker/SharedItemSlotPickerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Content.Shared._White.ItemSlotPicker.UI;
using Content.Shared.ActionBlocker;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Robust.Shared.Containers;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Content.Shared._White.ItemSlotPicker;

public abstract class SharedItemSlotPickerSystem : EntitySystem
{
[Dependency] protected readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] protected readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] protected readonly ActionBlockerSystem _blocker = default!;
[Dependency] protected readonly SharedInteractionSystem _interact = default!;

public override void Initialize()
{
SubscribeLocalEvent<ItemSlotPickerComponent, ComponentInit>(CompInit);
SubscribeLocalEvent<ItemSlotPickerComponent, AlternativeInteractionEvent>(AltInteract);
SubscribeLocalEvent<ItemSlotPickerComponent, ItemSlotPickerSlotPickedMessage>(OnMessage);
}

protected virtual void CompInit(EntityUid uid, ItemSlotPickerComponent comp, ComponentInit args)
{
_ui.SetUi(uid, ItemSlotPickerKey.Key, new InterfaceData("ItemSlotPickerBoundUserInterface", 1.5f));
}

protected virtual void AltInteract(EntityUid uid, ItemSlotPickerComponent comp, AlternativeInteractionEvent args)
{
var user = args.User;
if (!TryComp<ItemSlotsComponent>(uid, out var slots) ||
!TryComp<HandsComponent>(user, out var hands) ||
!_blocker.CanComplexInteract(user) ||
!_blocker.CanInteract(user, uid) ||
!_interact.InRangeAndAccessible(user, uid, 1.5f))
return;

args.Handled = true;

if (hands.ActiveHandEntity is EntityUid item)
foreach (var slot in comp.ItemSlots)
if (_itemSlots.TryInsert(uid, slot, item, user, slots, true))
return; // I wish this altverb bullshit wasn't a thing.

_ui.TryToggleUi(uid, ItemSlotPickerKey.Key, user);
}

protected virtual void OnMessage(EntityUid uid, ItemSlotPickerComponent comp, ItemSlotPickerSlotPickedMessage args)
{
if (!comp.ItemSlots.Contains(args.SlotId) ||
!_itemSlots.TryGetSlot(uid, args.SlotId, out var slot))
return;

_itemSlots.TryEjectToHands(uid, slot, args.Actor, true);
_ui.CloseUi(uid, ItemSlotPickerKey.Key, args.Actor);
}
}
[Serializable, NetSerializable]
public enum ItemSlotPickerKey { Key };
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Content.Shared._White.ItemSlotPicker.UI;

[Serializable, NetSerializable]
public sealed class ItemSlotPickerSlotPickedMessage(string id) : BoundUserInterfaceMessage
{
public string SlotId = id;
}


//[Serializable, NetSerializable]
public sealed class ItemSlotPickerContentsChangedMessage() : BoundUserInterfaceMessage
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@
tags:
- TrashBag
priority: 3 # Higher than drinking priority
- type: ItemSlotPicker # wwdp
itemSlots:
- mop_slot
- plunger_slot
- trashbag_slot
- lightreplacer_slot
- spraybottle_slot
- type: Fixtures
fixtures:
fix1:
Expand Down
Loading