Add Item Transfer System (#476)

# Description

This PR adds the ability to transfer objects from one player's hand to
another player's hand, as in SS13.

I have little coding experience, so my solutions may not be ideal.

---

# TODO

- [x] Make the code work
- [x] Add popup
- [x] Write a summary of the code
- [x] Сorrect inaccuracies

<details><summary><h1>Media</h1></summary>
<p>

https://youtu.be/zTQWTsYm1gw

</p>
</details>

---

# Changelog

🆑
- add: Added system
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -

---------

Co-authored-by: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com>
This commit is contained in:
Spatison
2024-07-06 03:19:35 +03:00
committed by GitHub
parent 726fd0f7aa
commit c8a9002efc
24 changed files with 559 additions and 1 deletions

View File

@@ -68,6 +68,7 @@ namespace Content.Client.Input
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);

View File

@@ -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);
}
}

View File

@@ -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>();
}
}

View File

@@ -183,6 +183,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(ContentKeyFunctions.SwapHands);
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddButton(ContentKeyFunctions.OfferItem);
AddHeader("ui-options-header-interaction-adv");
AddButton(ContentKeyFunctions.SmartEquipBackpack);

View File

@@ -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"/>

View File

@@ -60,6 +60,7 @@ namespace Content.Client.Options.UI.Tabs
ShowLoocAboveHeadCheckBox.OnToggled += OnCheckBoxToggled;
ShowHeldItemCheckBox.OnToggled += OnCheckBoxToggled;
ShowCombatModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
ShowOfferModeIndicatorsCheckBox.OnToggled += OnCheckBoxToggled;
OpaqueStorageWindowCheckBox.OnToggled += OnCheckBoxToggled;
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
@@ -75,6 +76,7 @@ namespace Content.Client.Options.UI.Tabs
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);
@@ -120,6 +122,7 @@ namespace Content.Client.Options.UI.Tabs
_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);
@@ -147,6 +150,7 @@ namespace Content.Client.Options.UI.Tabs
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);
@@ -163,6 +167,7 @@ namespace Content.Client.Options.UI.Tabs
isDiscordSame &&
isShowHeldItemSame &&
isCombatModeIndicatorsSame &&
isOfferModeIndicatorsSame &&
isOpaqueStorageWindow &&
isLoocShowSame &&
isFancyChatSame &&

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -52,7 +52,8 @@ namespace Content.Shared.Alert
SuitPower,
BorgHealth,
BorgCrit,
BorgDead
BorgDead,
Offer,
}
}

View File

@@ -810,6 +810,9 @@ namespace Content.Shared.CCVar
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);

View File

@@ -54,6 +54,7 @@ namespace Content.Shared.Input
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";

View File

@@ -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;
}

View File

@@ -0,0 +1,74 @@
using Content.Shared.Popups;
using Content.Shared.ActionBlocker;
using Content.Shared.Input;
using Content.Shared.Hands.Components;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
namespace Content.Shared.OfferItem;
public abstract partial class SharedOfferItemSystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly SharedPopupSystem _popup = 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 (session is not { } playerSession)
return;
if ((playerSession.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 == null)
return;
offerItem.Item = hands.ActiveHand.HeldEntity;
if (offerItem.IsInOfferMode == false)
{
if (offerItem.Item == null)
{
_popup.PopupEntity(Loc.GetString("offer-item-empty-hand"), uid, uid);
return;
}
if (offerItem.Hand == null || offerItem.Target == null)
{
offerItem.IsInOfferMode = true;
offerItem.Hand = hands.ActiveHand.Name;
Dirty(uid, offerItem);
return;
}
}
if (offerItem.Target != null)
{
UnReceive(offerItem.Target.Value, offerItem: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
return;
}
UnOffer(uid, offerItem);
}
}

View File

@@ -0,0 +1,155 @@
using Content.Shared.Interaction;
using Content.Shared.IdentityManagement;
using Content.Shared.Hands.Components;
namespace Content.Shared.OfferItem;
public abstract partial class SharedOfferItemSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize()
{
SubscribeLocalEvent<OfferItemComponent, AfterInteractUsingEvent>(SetInReceiveMode);
SubscribeLocalEvent<OfferItemComponent, MoveEvent>(OnMove);
InitializeInteractions();
}
private void SetInReceiveMode(EntityUid uid, OfferItemComponent component, AfterInteractUsingEvent args)
{
if (!TryComp<OfferItemComponent>(args.User, out var offerItem))
return;
if (args.User == uid || component.IsInReceiveMode ||
(offerItem.IsInReceiveMode && offerItem.Target != uid))
return;
component.IsInReceiveMode = true;
component.Target = args.User;
Dirty(uid, component);
offerItem.Target = uid;
offerItem.IsInOfferMode = false;
Dirty(args.User, offerItem);
if (offerItem.Item == null)
return;
_popup.PopupEntity(Loc.GetString("offer-item-try-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-try-give-target",
("user", Identity.Entity(component.Target.Value, EntityManager)),
("item", Identity.Entity(offerItem.Item.Value, EntityManager))), component.Target.Value, uid);
}
private void OnMove(EntityUid uid, OfferItemComponent component, MoveEvent args)
{
if (component.Target == null ||
args.NewPosition.InRange(EntityManager, _transform,
Transform(component.Target.Value).Coordinates, component.MaxOfferDistance))
return;
UnOffer(uid, component);
}
/// <summary>
/// Resets the <see cref="OfferItemComponent"/> of the user and the target
/// </summary>
protected void UnOffer(EntityUid uid, OfferItemComponent component)
{
if (!TryComp<HandsComponent>(uid, out var hands) || hands.ActiveHand == null)
return;
if (TryComp<OfferItemComponent>(component.Target, out var offerItem) && component.Target != null)
{
if (component.Item != null)
{
_popup.PopupEntity(Loc.GetString("offer-item-no-give",
("item", Identity.Entity(component.Item.Value, EntityManager)),
("target", Identity.Entity(component.Target.Value, EntityManager))), uid, uid);
_popup.PopupEntity(Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(uid, EntityManager)),
("item", Identity.Entity(component.Item.Value, EntityManager))), uid, component.Target.Value);
}
else if (offerItem.Item != null)
{
_popup.PopupEntity(Loc.GetString("offer-item-no-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-no-give-target",
("user", Identity.Entity(component.Target.Value, EntityManager)),
("item", Identity.Entity(offerItem.Item.Value, EntityManager))), component.Target.Value, uid);
}
offerItem.IsInOfferMode = false;
offerItem.IsInReceiveMode = false;
offerItem.Hand = null;
offerItem.Target = null;
offerItem.Item = null;
Dirty(component.Target.Value, offerItem);
}
component.IsInOfferMode = false;
component.IsInReceiveMode = false;
component.Hand = null;
component.Target = null;
component.Item = null;
Dirty(uid, component);
}
/// <summary>
/// Cancels the transfer of the item
/// </summary>
protected void UnReceive(EntityUid uid, OfferItemComponent? component = null, OfferItemComponent? offerItem = null)
{
if (component == null && !TryComp(uid, out component))
return;
if (offerItem == null && !TryComp(component.Target, out offerItem))
return;
if (!TryComp<HandsComponent>(uid, out var hands) || hands.ActiveHand == null ||
component.Target == null)
return;
if (offerItem.Item != null)
{
_popup.PopupEntity(Loc.GetString("offer-item-no-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-no-give-target",
("user", Identity.Entity(component.Target.Value, EntityManager)),
("item", Identity.Entity(offerItem.Item.Value, EntityManager))), component.Target.Value, uid);
}
if (!offerItem.IsInReceiveMode)
{
offerItem.Target = null;
component.Target = null;
}
offerItem.Item = null;
offerItem.Hand = null;
component.IsInReceiveMode = false;
Dirty(uid, component);
}
/// <summary>
/// Returns true if <see cref="OfferItemComponent.IsInOfferMode"/> = true
/// </summary>
protected bool IsInOfferMode(EntityUid? entity, OfferItemComponent? component = null)
{
return entity != null && Resolve(entity.Value, ref component, false) && component.IsInOfferMode;
}
}

View File

@@ -110,3 +110,6 @@ alerts-revenant-essence-desc = The power of souls. It sustains you and is used f
alerts-revenant-corporeal-name = Corporeal
alerts-revenant-corporeal-desc = You have manifested physically. People around you can see and hurt you.
alerts-offer-name = Offer
alerts-offer-desc = Someone offers you an item.

View File

@@ -41,6 +41,7 @@ ui-options-volume-percent = { TOSTRING($volume, "P0") }
ui-options-show-held-item = Show held item next to cursor
ui-options-show-combat-mode-indicators = Show combat mode indicators with cursor
ui-options-show-offer-mode-indicators = Show offer mode indicators with cursor
ui-options-opaque-storage-window = Opaque storage window
ui-options-show-looc-on-head = Show LOOC chat above characters head
ui-options-fancy-speech = Show names in speech bubbles
@@ -135,6 +136,7 @@ ui-options-function-examine-entity = Examine
ui-options-function-swap-hands = Swap hands
ui-options-function-move-stored-item = Move stored item
ui-options-function-rotate-stored-item = Rotate stored item
ui-options-function-offer-item = Offer something
ui-options-static-storage-ui = Lock storage window to hotbar
ui-options-function-smart-equip-backpack = Smart-equip to backpack

View File

@@ -0,0 +1,13 @@
offer-item-empty-hand = You don't have anything in your hand to give!
offer-item-full-hand = Your hand isn't free to receive the item.
offer-item-try-give = You offer the {THE($item)} to {$target}
offer-item-try-give-target = {$user} offers you a {THE($item)}
offer-item-give = You handed {THE($item)} to {$target}
offer-item-give-other = {$user} handed {THE($item)} to {$target}
offer-item-give-target = {$user} handed you a {THE($item)}
offer-item-no-give = You stop offering {THE($item)} to {$target}
offer-item-no-give-target = {$user} is no longer offer a {THE($item)} to you

View File

@@ -24,6 +24,7 @@
- category: Thirst
- alertType: Magboots
- alertType: Pacified
- alertType: Offer
- type: alert
id: LowOxygen
@@ -150,6 +151,15 @@
name: alerts-buckled-name
description: alerts-buckled-desc
- type: alert
id: Offer
onClick: !type:AcceptOffer { }
icons:
- sprite: /Textures/Interface/Alerts/offer_item.rsi
state: offer_item
name: alerts-offer-name
description: alerts-offer-desc
- type: alert
id: HumanCrit
category: Health

View File

@@ -309,6 +309,7 @@
Asphyxiation: -1.0
- type: FireVisuals
alternateState: Standing
- type: OfferItem
- type: entity
save: false

View File

@@ -0,0 +1,14 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/ss220-space/Paradise/blob/master220/icons/mob/screen_alert.dmi",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "offer_item"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -0,0 +1,14 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/ss220-space/Paradise/blob/master220/icons/misc/mouse_icons/give_item.dmi",
"size": {
"x": 64,
"y": 64
},
"states": [
{
"name": "give_item"
}
]
}

View File

@@ -255,6 +255,9 @@ binds:
type: State
key: V
mod1: Shift
- function: OfferItem
type: State
key: F
- function: ShowDebugConsole
type: State
key: Tilde