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

OfferItem #933

Merged
merged 10 commits into from
Jan 3, 2025
62 changes: 62 additions & 0 deletions Content.Client/ADT/OfferItem/OfferItemIndicatorsOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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.ADT.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/ADT/Misc/give_item.rsi"), "give_item"));
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
return _offer.IsInOfferMode() && base.BeforeDraw(in args);
}

protected override void Draw(in OverlayDrawArgs args)
{
var mousePosMap = _eye.PixelToMap(_inputManager.MouseScreenPosition);

if (mousePosMap.MapId != args.MapId)
return;

var limitedScale = Math.Min(1.25f, (args.ViewportControl as Control)?.UIScale ?? 1f) * _scale;

DrawSight(_sight, args.ScreenHandle, _inputManager.MouseScreenPosition.Position, limitedScale);
}

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

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

namespace Content.Client.ADT.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()
{
base.Initialize();
Subs.CVar(_cfg, ADTCCVars.OfferModeIndicatorsPointShow, OnShowOfferIndicatorsChanged, true);
}

public override void Shutdown()
{
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
base.Shutdown();
}

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

return entity is not null && IsInOfferMode(entity.Value);
}

private void OnShowOfferIndicatorsChanged(bool isShow)
{
if (isShow)
_overlayManager.AddOverlay(new OfferItemIndicatorsOverlay(_inputManager, EntityManager, _eye, this));
else
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
}
}
2 changes: 2 additions & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.Arcade1);
human.AddFunction(ContentKeyFunctions.Arcade2);
human.AddFunction(ContentKeyFunctions.ToggleCrawling);///ADT crawling
human.AddFunction(ContentKeyFunctions.OfferItem); // ADT-Tweak

// actions should be common (for ghosts, mobs, etc)
common.AddFunction(ContentKeyFunctions.OpenActionsMenu);

Expand Down
2 changes: 1 addition & 1 deletion Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddButton(ContentKeyFunctions.SaveItemLocation);

AddButton(ContentKeyFunctions.OfferItem); // ADT-Tweak
AddHeader("ui-options-header-interaction-adv");
AddButton(ContentKeyFunctions.SmartEquipBackpack);
AddButton(ContentKeyFunctions.SmartEquipBelt);
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 @@ -22,6 +22,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'}" /> <!-- ADT-Tweak -->
<Label Text="{Loc 'ui-options-general-storage'}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="OpaqueStorageWindowCheckBox" Text="{Loc 'ui-options-opaque-storage-window'}" />
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/Options/UI/Tabs/MiscTab.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using Content.Client.UserInterface.Screens;
using Content.Shared.ADT.CCVar; // ADT-Tweak
using Content.Shared.CCVar;
using Content.Shared.HUD;
using Robust.Client.AutoGenerated;
Expand Down Expand Up @@ -52,7 +53,7 @@ public MiscTab()
Control.AddOptionCheckBox(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox);
Control.AddOptionCheckBox(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox);
Control.AddOptionCheckBox(CCVars.StaticStorageUI, StaticStorageUI);

Control.AddOptionCheckBox(ADTCCVars.OfferModeIndicatorsPointShow, ShowOfferModeIndicatorsCheckBox); // ADT-Tweak
Control.Initialize();
}
}
57 changes: 57 additions & 0 deletions Content.Server/ADT/OfferItemSystem/OfferItemSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Content.Shared.Alert;
using Content.Shared.ADT.OfferItem;
using Content.Shared.Mobs.Systems;
using Content.Shared.Hands.Components;

namespace Content.Server.ADT.OfferItem;

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

[Dependency] private readonly MobStateSystem _mobStateSystem = default!;

private float _offerAcc = 0;
private const float OfferAccMax = 3f;

public override void Update(float frameTime)
{
_offerAcc += frameTime;

if (_offerAcc >= OfferAccMax)
_offerAcc -= OfferAccMax;
else
return;

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

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

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

if (_mobStateSystem.IsCritical(uid) || _mobStateSystem.IsDead(uid))
{
_alertsSystem.ClearAlert(uid, OfferAlert);
continue;
}

_alertsSystem.ShowAlert(uid, OfferAlert);
}
}
}
6 changes: 6 additions & 0 deletions Content.Shared/ADT/CCVar/ADTCCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ public sealed class ADTCCVars

public static readonly CVarDef<string> DiscordBansWebhook =
CVarDef.Create("discord.bans_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);

/*
* Offer Items
*/
public static readonly CVarDef<bool> OfferModeIndicatorsPointShow =
CVarDef.Create("hud.offer_mode_indicators_point_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);
}
8 changes: 8 additions & 0 deletions Content.Shared/ADT/OfferItem/Alert/Click/AcceptingOffer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Content.Shared.Alert;

namespace Content.Shared.ADT.Alert.Click;

/// <summary>
/// Accepting the offer and receive item
/// </summary>
public sealed partial class AcceptOfferAlertEvent : BaseAlertEvent;
26 changes: 26 additions & 0 deletions Content.Shared/ADT/OfferItem/OfferItem/OfferItemComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Robust.Shared.GameStates;

namespace Content.Shared.ADT.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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Hands.Components;
using Content.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;

namespace Content.Shared.ADT.OfferItem;

public abstract partial class SharedOfferItemSystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;

private void InitializeInteractions()
{
CommandBinds.Builder
.Bind(ContentKeyFunctions.OfferItem, InputCmdHandler.FromDelegate(SetInOfferMode, handle: false, outsidePrediction: false))
.Register<SharedOfferItemSystem>();
}

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

CommandBinds.Unregister<SharedOfferItemSystem>();
}

private void SetInOfferMode(ICommonSession? session)
{
if (!_timing.IsFirstTimePredicted)
return;

if (session is null)
return;

if (session.AttachedEntity is not { Valid: true } uid || !Exists(uid) || !_actionBlocker.CanInteract(uid, null))
return;

if (!TryComp<OfferItemComponent>(uid, out var offerItem))
return;

if (!TryComp<HandsComponent>(uid, out var hands) || hands.ActiveHand is null)
return;

offerItem.Item = hands.ActiveHand.HeldEntity;

if (!offerItem.IsInOfferMode)
{
if (offerItem.Item is null)
{
_popup.PopupClient(Loc.GetString("offer-item-empty-hand"), uid, uid);
return;
}

if (offerItem.Hand is null || offerItem.Target is null)
{
offerItem.IsInOfferMode = true;
offerItem.Hand = hands.ActiveHand.Name;

Dirty(uid, offerItem);
return;
}
}

if (offerItem.Target is not null)
{
UnReceive(offerItem.Target.Value, offerItem: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
return;
}

UnOffer(uid, offerItem);
}
}
Loading
Loading