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

Add Item Transfer System #476

Merged
merged 13 commits into from
Jul 6, 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
1 change: 1 addition & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.SmartEquipBelt);
human.AddFunction(ContentKeyFunctions.OpenBackpack);
human.AddFunction(ContentKeyFunctions.OpenBelt);
human.AddFunction(ContentKeyFunctions.OfferItem);
human.AddFunction(ContentKeyFunctions.MouseMiddle);
human.AddFunction(ContentKeyFunctions.ArcadeUp);
human.AddFunction(ContentKeyFunctions.ArcadeDown);
Expand Down
72 changes: 72 additions & 0 deletions Content.Client/OfferItem/OfferItemIndicatorsOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Numerics;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Shared.Enums;
using Robust.Shared.Utility;

namespace Content.Client.OfferItem;

public sealed class OfferItemIndicatorsOverlay : Overlay
{
private readonly IInputManager _inputManager;
private readonly IEntityManager _entMan;
private readonly IEyeManager _eye;
private readonly OfferItemSystem _offer;

private readonly Texture _sight;

public override OverlaySpace Space => OverlaySpace.ScreenSpace;

private readonly Color _mainColor = Color.White.WithAlpha(0.3f);
private readonly Color _strokeColor = Color.Black.WithAlpha(0.5f);
private readonly float _scale = 0.6f; // 1 is a little big

public OfferItemIndicatorsOverlay(IInputManager input, IEntityManager entMan,
IEyeManager eye, OfferItemSystem offerSys)
{
_inputManager = input;
_entMan = entMan;
_eye = eye;
_offer = offerSys;

var spriteSys = _entMan.EntitySysManager.GetEntitySystem<SpriteSystem>();
_sight = spriteSys.Frame0(new SpriteSpecifier.Rsi(new ResPath("/Textures/Interface/Misc/give_item.rsi"),
"give_item"));
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (!_offer.IsInOfferMode())
return false;

return base.BeforeDraw(in args);
}

protected override void Draw(in OverlayDrawArgs args)
{
var mouseScreenPosition = _inputManager.MouseScreenPosition;
var mousePosMap = _eye.PixelToMap(mouseScreenPosition);
if (mousePosMap.MapId != args.MapId)
return;


var mousePos = mouseScreenPosition.Position;
var uiScale = (args.ViewportControl as Control)?.UIScale ?? 1f;
var limitedScale = uiScale > 1.25f ? 1.25f : uiScale;

DrawSight(_sight, args.ScreenHandle, mousePos, limitedScale * _scale);
}

private void DrawSight(Texture sight, DrawingHandleScreen screen, Vector2 centerPos, float scale)
{
var sightSize = sight.Size * scale;
var expandedSize = sightSize + new Vector2(7f, 7f);

screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - sightSize * 0.5f, sightSize), _strokeColor);
screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - expandedSize * 0.5f, expandedSize), _mainColor);
}
}
51 changes: 51 additions & 0 deletions Content.Client/OfferItem/OfferItemSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Content.Shared.CCVar;
using Content.Shared.OfferItem;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
using Robust.Shared.Configuration;

namespace Content.Client.OfferItem;

public sealed class OfferItemSystem : SharedOfferItemSystem
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IEyeManager _eye = default!;

public override void Initialize()
{
Subs.CVar(_cfg, CCVars.OfferModeIndicatorsPointShow, OnShowOfferIndicatorsChanged, true);
}
public override void Shutdown()
{
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();

base.Shutdown();
}

public bool IsInOfferMode()
{
var entity = _playerManager.LocalEntity;

if (entity == null)
return false;

return IsInOfferMode(entity.Value);
}
private void OnShowOfferIndicatorsChanged(bool isShow)
{
if (isShow)
{
_overlayManager.AddOverlay(new OfferItemIndicatorsOverlay(
_inputManager,
EntityManager,
_eye,
this));
}
else
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
}
}
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.SwapHands);
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddButton(ContentKeyFunctions.OfferItem);

AddHeader("ui-options-header-interaction-adv");
AddButton(ContentKeyFunctions.SmartEquipBackpack);
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/MiscTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowHeldItemCheckBox" Text="{Loc 'ui-options-show-held-item'}" />
<CheckBox Name="ShowCombatModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-combat-mode-indicators'}" />
<CheckBox Name="ShowOfferModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-offer-mode-indicators'}" />
<Label Text="{Loc 'ui-options-general-storage'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
Expand Down
5 changes: 5 additions & 0 deletions Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public MiscTab()
ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
ShowOfferModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
OpaqueStorageWindowCheckBox.OnToggled += OnCheckBoxToggled;
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
Expand All @@ -75,6 +76,7 @@ public MiscTab()
ShowLoocAboveHeadCheckBox.Pressed = _cfg.GetCVar(CCVars.LoocAboveHeadShow);
ShowHeldItemCheckBox.Pressed = _cfg.GetCVar(CCVars.HudHeldItemShow);
ShowCombatModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
ShowOfferModeIndicatorsCheckBox.Pressed = _cfg.GetCVar(CCVars.OfferModeIndicatorsPointShow);
OpaqueStorageWindowCheckBox.Pressed = _cfg.GetCVar(CCVars.OpaqueStorageWindow);
FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
Expand Down Expand Up @@ -120,6 +122,7 @@ private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
_cfg.SetCVar(CVars.DiscordEnabled, DiscordRich.Pressed);
_cfg.SetCVar(CCVars.HudHeldItemShow, ShowHeldItemCheckBox.Pressed);
_cfg.SetCVar(CCVars.CombatModeIndicatorsPointShow, ShowCombatModeIndicatorsCheckBox.Pressed);
_cfg.SetCVar(CCVars.OfferModeIndicatorsPointShow, ShowOfferModeIndicatorsCheckBox.Pressed);
_cfg.SetCVar(CCVars.OpaqueStorageWindow, OpaqueStorageWindowCheckBox.Pressed);
_cfg.SetCVar(CCVars.LoocAboveHeadShow, ShowLoocAboveHeadCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
Expand Down Expand Up @@ -147,6 +150,7 @@ private void UpdateApplyButton()
var isDiscordSame = DiscordRich.Pressed == _cfg.GetCVar(CVars.DiscordEnabled);
var isShowHeldItemSame = ShowHeldItemCheckBox.Pressed == _cfg.GetCVar(CCVars.HudHeldItemShow);
var isCombatModeIndicatorsSame = ShowCombatModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.CombatModeIndicatorsPointShow);
var isOfferModeIndicatorsSame = ShowOfferModeIndicatorsCheckBox.Pressed == _cfg.GetCVar(CCVars.OfferModeIndicatorsPointShow);
var isOpaqueStorageWindow = OpaqueStorageWindowCheckBox.Pressed == _cfg.GetCVar(CCVars.OpaqueStorageWindow);
var isLoocShowSame = ShowLoocAboveHeadCheckBox.Pressed == _cfg.GetCVar(CCVars.LoocAboveHeadShow);
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
Expand All @@ -163,6 +167,7 @@ private void UpdateApplyButton()
isDiscordSame &&
isShowHeldItemSame &&
isCombatModeIndicatorsSame &&
isOfferModeIndicatorsSame &&
isOpaqueStorageWindow &&
isLoocShowSame &&
isFancyChatSame &&
Expand Down
24 changes: 24 additions & 0 deletions Content.Server/Alert/Click/AcceptingOffer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Content.Shared.OfferItem;
using Content.Server.OfferItem;
using Content.Shared.Alert;
using JetBrains.Annotations;

namespace Content.Server.Alert.Click;

/// <summary>
/// Accepting the offer and receive item
/// </summary>
[UsedImplicitly]
[DataDefinition]
public sealed partial class AcceptOffer : IAlertClick
{
public void AlertClicked(EntityUid player)
{
var entManager = IoCManager.Resolve<IEntityManager>();

if (entManager.TryGetComponent(player, out OfferItemComponent? offerItem))
{
entManager.System<OfferItemSystem>().Receive(player, offerItem);
}
}
}
83 changes: 83 additions & 0 deletions Content.Server/OfferItem/OfferItemSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Content.Server.Popups;
using Content.Shared.Hands.Components;
using Content.Shared.Alert;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.OfferItem;
using Content.Shared.IdentityManagement;
using Robust.Shared.Player;

namespace Content.Server.OfferItem;

public sealed class OfferItemSystem : SharedOfferItemSystem
{
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly PopupSystem _popup = default!;

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<OfferItemComponent>();
while (query.MoveNext(out var uid, out var offerItem))
{
if (!TryComp<HandsComponent>(uid, out var hands) || hands.ActiveHand == null)
continue;

if (offerItem.Hand != null &&
hands.Hands[offerItem.Hand].HeldEntity == null)
{
if (offerItem.Target != null)
{
UnReceive(offerItem.Target.Value, offerItem: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
}
else
UnOffer(uid, offerItem);
}

if (!offerItem.IsInReceiveMode)
{
_alertsSystem.ClearAlert(uid, AlertType.Offer);
continue;
}

_alertsSystem.ShowAlert(uid, AlertType.Offer);
}
}

/// <summary>
/// Accepting the offer and receive item
/// </summary>
public void Receive(EntityUid uid, OfferItemComponent? component = null)
{
if (!Resolve(uid, ref component) ||
!TryComp<OfferItemComponent>(component.Target, out var offerItem) ||
offerItem.Hand == null ||
component.Target == null ||
!TryComp<HandsComponent>(uid, out var hands))
return;

if (offerItem.Item != null)
{
if (!_hands.TryPickup(uid, offerItem.Item.Value, handsComp: hands))
{
_popup.PopupEntity(Loc.GetString("offer-item-full-hand"), uid, uid);
return;
}

_popup.PopupEntity(Loc.GetString("offer-item-give",
("item", Identity.Entity(offerItem.Item.Value, EntityManager)),
("target", Identity.Entity(uid, EntityManager))), component.Target.Value, component.Target.Value);
_popup.PopupEntity(Loc.GetString("offer-item-give-other",
("user", Identity.Entity(component.Target.Value, EntityManager)),
("item", Identity.Entity(offerItem.Item.Value, EntityManager)),
("target", Identity.Entity(uid, EntityManager)))
, component.Target.Value, Filter.PvsExcept(component.Target.Value, entityManager: EntityManager), true);
}

offerItem.Item = null;
UnReceive(uid, component, offerItem);
}
}
3 changes: 2 additions & 1 deletion Content.Shared/Alert/AlertType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public enum AlertType : byte
SuitPower,
BorgHealth,
BorgCrit,
BorgDead
BorgDead,
Offer,
}

}
3 changes: 3 additions & 0 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,9 @@ public static readonly CVarDef<bool>
public static readonly CVarDef<bool> CombatModeIndicatorsPointShow =
CVarDef.Create("hud.combat_mode_indicators_point_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);

public static readonly CVarDef<bool> OfferModeIndicatorsPointShow =
CVarDef.Create("hud.offer_mode_indicators_point_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);

public static readonly CVarDef<bool> LoocAboveHeadShow =
CVarDef.Create("hud.show_looc_above_head", true, CVar.ARCHIVE | CVar.CLIENTONLY);

Expand Down
1 change: 1 addition & 0 deletions Content.Shared/Input/ContentKeyFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public static class ContentKeyFunctions
public static readonly BoundKeyFunction ZoomOut = "ZoomOut";
public static readonly BoundKeyFunction ZoomIn = "ZoomIn";
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
public static readonly BoundKeyFunction OfferItem = "OfferItem";

public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown";
Expand Down
26 changes: 26 additions & 0 deletions Content.Shared/OfferItem/OfferItemComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Robust.Shared.GameStates;

namespace Content.Shared.OfferItem;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedOfferItemSystem))]
public sealed partial class OfferItemComponent : Component
{
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool IsInOfferMode;

[DataField, AutoNetworkedField]
public bool IsInReceiveMode;

[DataField, AutoNetworkedField]
public string? Hand;

[DataField, AutoNetworkedField]
public EntityUid? Item;

[DataField, AutoNetworkedField]
public EntityUid? Target;

[DataField]
public float MaxOfferDistance = 2f;
}
Loading
Loading